计算机图形学六面体旋转并实时切换虚线实线 - 代码实现

Posted 征途黯然.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算机图形学六面体旋转并实时切换虚线实线 - 代码实现相关的知识,希望对你有一定的参考价值。

第一章 作业背景

1.1 作业要求

  编程实现一个多面体的旋转。在多面体的旋转过程中,对于不可见的线,用虚线表示;对于可见的线,用实线表示。

1.2 开发技术

  本次作业采用前端技术实现,主要有:html、css、css3、javascript、Jquery。其中,html作为页面显示的骨架,css用来渲染页面样式、绘制立体图形,css3控制图形旋转等相关参数,javascript作为脚本语言来显式的操作页面各个dom的css样式,Jquery是javascript的框架,实现跨浏览器的js编写。

1.3 实现思路

  ①绘制6个正方形,利用css3把它们拼成一个立方体;
  ②使用css3的动画功能,设置立方体旋转;
  ③使用Jquery,读取立方体旋转的角度,当角度在一定阈值的时候,显式地控制立方体地12条边变为虚线或者变为实线。

第二章 代码实现

2.1 绘制立方体

  首先,编写html代码,绘制立方体的6个面:

<div class="box">
    <ul>
        <li id="panel_1">1</li>
        <li id="panel_2">2</li>
        <li id="panel_3">3</li>
        <li id="panel_4">4</li>
        <li id="panel_5">5</li>
        <li id="panel_6">6</li>
    </ul>
</div>

  代码块2-1 立方体html代码
  之后,加上css的样式,对每个面进行一定量的偏移。此处需要数学的3D几何基础,计算每个面在X方向、Y方向、Z方向的偏移量,css代码如下:

*margin: o;padding: 0;
bodybackground: white;
.box
    width: 400px;
    height: 400px;
    margin: 200px auto;
    perspective: 1000px;

.box ul
    width: 300px;
    height: 300px;
    margin: 48px;
    position:relative;
    transform-style: preserve-3d;
    animation: move 20s infinite linear;
    transform-origin:center center 150px ;

.box ul li
    width: 300px;
    height: 300px;
    list-style: none;
    font-size: 20px;
    color: #000;
    text-align: center;
    line-height: 300px;
    position: absolute;

.box ul li:nth-of-type(2) transform:translateX(300px) rotateY(-90deg) ;transform-origin: left;
.box ul li:nth-of-type(3) transform:translateX(-300px) rotateY(90deg);transform-origin: right;
.box ul li:nth-of-type(4) transform: translateY(-300px) rotateX(-90deg);transform-origin:bottom;
.box ul li:nth-of-type(5) transform: translateY(300px) rotateX(90deg);transform-origin:top;
.box ul li:nth-of-type(6) transform: translateZ(300px);

  代码块2-2 立方体css代码
  最终立方体的效果图,如下所示:

  图2-1 立方体静态效果

2.2 使立方体旋转

  图2-1的立方体只是静态的,我们使用css3的动画控制,使得立方体的6个面绕Y轴转动。代码如下:

@keyframes move
    fromtransform:rotateY(0deg);
    totransform: rotateY(360deg);

  代码块2-3 立方体css3代码
  旋转后的gif效果图如下:


  图2-2 立方体旋转效果

2.3 实线虚线切换

  图2-2的立方体中,所有的线都是实线,我们需要当立方体的边不可见时,把边变成虚线,可见时再变成实线。这里使用了Jquery,判断每个的旋转角度,当某个面旋转的角度大于0或者小于0时,表示这个面可见或者不可见,往往这个时候又伴随着某线边的可见与不可见,于是写下JS代码如下:

setInterval( ()=>
	 var deg_2 = parseFloat($("ul").css("transform").replace(/[^0-9\\-.,]/g,'').split(',')[2])
	 var deg_3 = parseFloat($("ul").css("transform").replace(/[^0-9\\-.,]/g,'').split(',')[8])
	 var deg_6 = parseFloat($("ul").css("transform").replace(/[^0-9\\-.,]/g,'').split(',')[10])
	
	 // 面3不可见时
	 if(deg_3 <= 0)
	     /***面2可见***/
	     // 面2上下变实线
	     $("li").eq(1).css('borderTop','2px solid black')
	     $("li").eq(1).css('borderBottom','2px solid black')
	     // 面3上下变虚线
	     $("li").eq(2).css('borderTop','2px dashed black')
	     $("li").eq(2).css('borderBottom','2px dashed black')
	     // 面2可见时,面36之间线不可见
	     $("li").eq(5).css('borderLeft','2px dashed black')
	 else
	     /***面3可见***/
	     // 面3上下变实线
	     $("li").eq(2).css('borderTop','2px solid black')
	     $("li").eq(2).css('borderBottom','2px solid black')
	     // 面2上下变虚线
	     $("li").eq(1).css('borderTop','2px dashed black')
	     $("li").eq(1).css('borderBottom','2px dashed black')
	     // 面3可见时,面12之间线不可见
	     $("li").eq(0).css('borderRight','2px dashed black') 
	 
	 
	 if(deg_6 <= 0)
	     /***面1可见***/
	     // 面1上下变实线
	     $("li").eq(0).css('borderTop','2px solid black')
	     $("li").eq(0).css('borderBottom','2px solid black')
	     // 面6上下变虚线
	     $("li").eq(5).css('borderTop','2px dashed black')
	     $("li").eq(5).css('borderBottom','2px dashed black')
	     // 面1可见时,面12之间线可见
	     $("li").eq(0).css('borderRight','2px solid black')
	     // 面2可见时,26线可见
	     $("li").eq(5).css('borderRight','2px dashed black')
	 else
	     /***面6可见***/
	     // 面1上下变虚线
	     $("li").eq(0).css('borderTop','2px dashed black')
	     $("li").eq(0).css('borderBottom','2px dashed black')
	     // 面6上下变实现
	     $("li").eq(5).css('borderTop','2px solid black')
	     $("li").eq(5).css('borderBottom','2px solid black')
	     // 面6可见时,面36之间线可见
	     $("li").eq(5).css('borderLeft','2px solid black')
	     // 面3可见时,13线可见
	     $("li").eq(2).css('borderRight','2px dashed black')
	 
	
	 if(deg_2<=0)
	     // 面3可见时,13线可见
	     $("li").eq(2).css('borderRight','2px solid black')
	 else
	     // 面2可见时,26线可见
	     $("li").eq(5).css('borderRight','2px solid black')
	 
	,20)

  代码块2-4 立方体边虚实JS代码
  此时,效果图如下:

  图2-3 立方体最终旋转效果

2.4 动态切换视角

  图2-3的立方体是在一定视角下来观看的,我们添加一个切换视点的函数,如下:

var per = 1000 ;

$(document).mousewheel(function(event) 
    if(event.deltaY < 0 )
        per = per >= 2000 ? 2000 : per+100
    else
        per = per <= 300 ? 300 : per-100
    
    $('.box').css('perspective', per + 'px')
    console.log(per)
);

  代码块2-5 立方体切换视角代码
  当鼠标滚轮上下滑动时,可以拉近或者拉远视点。

第三章 总结

  作业实现起来难度较大,如果掌握一定的专业工具实现起来的效果、效率都会很高,用前端网页只能实现一些简单的功能。

  掌握一些制作游戏的引擎、开发工具、概念应该很容易去做,耳熟能详的有UE4、Unity、光追、光捕、粒子等等。

  在读研究生选方向前,我也有一腔热血,想投身于计算机图形学。凭什么电影《哪吒》的画质效果比不过皮克斯、迪士尼,为什么中国做不出属于自己的特效呢?后来才发现这条路太难走了,家里条件也不支持,最终妥协,选了NLP作为科研方向。

附代码及使用方式

总共有三个文件,一个index.html,一个jquery-3.3.1.min.js,一个jquery.mousewheel.min.js。后两个js文件网上自行下载,很容易找,下面附上index.html


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>立方体</title>
    <style>
        *margin: o;padding: 0;
        bodybackground: white;
        .box
            width: 400px;
            height: 400px;
            margin: 200px auto;
            perspective: 1000px;
        
        .box ul
            width: 300px;
            height: 300px;
            margin: 48px;
            position:relative;
            transform-style: preserve-3d;
            animation: move 20s infinite linear;
            transform-origin:center center 150px ;
        
        .box ul li
            width: 300px;
            height: 300px;
            list-style: none;
            font-size: 20px;
            color: #000;
            text-align: center;
            line-height: 300px;
            position: absolute;
        
        .box ul li:nth-of-type(2) transform:translateX(300px) rotateY(-90deg) ;transform-origin: left;
        .box ul li:nth-of-type(3) transform:translateX(-300px) rotateY(90deg);transform-origin: right;
        .box ul li:nth-of-type(4) transform: translateY(-300px) rotateX(-90deg);transform-origin:bottom;
        .box ul li:nth-of-type(5) transform: translateY(300px) rotateX(90deg);transform-origin:top;
        .box ul li:nth-of-type(6) transform: translateZ(300px);

        @keyframes move
            fromtransform:rotateY(0deg);
            totransform: rotateY(360deg);
        
    </style>
</head>
<body>
   
    <div class="box">
        
        <ul>
            <li id="panel_1">1</li>
            <li id="panel_2">2</li>
            <li id="panel_3">3</li>
            <li id="panel_4">4</li>
            <li id="panel_5">5</li>
            <li id="panel_6">6</li>
        </ul>
    </div>
    
</body>
<script src="./jquery-3.3.1.min.js"></script>
<script src="./jquery.mousewheel.min.js"></script>
<script>
    /**
     * 6与1相对,2与3相对
     * deg_2 第2面:为正可见, 为负不可见
     * deg_3 第3面:为正可见, 为负不可见
     * deg_6 第6面:为正可见, 为负不可见
     * 
     * 当1个面可见时,这个面的右边框可见,为实线
     **/
    setInterval( ()=>
        var deg_2 = parseFloat($("ul").css("transform").replace(/[^0-9\\-.,]/g,'').split(',')[2])
        var deg_3 = parseFloat($("ul").css("transform").replace(/[^0-9\\-.,]/g,'').split(',')[8])
        var deg_6 = parseFloat($("ul").css("transform").replace(/[^0-9\\-.,]/g,'').split(',')[10])

        // 面3不可见时
        if(deg_3 <= 0)
            /***面2可见***/
            // 面2上下变实线
            $("li").eq(1).css('borderTop','2px solid black')
            $("li").eq(1计算机图形学_图元的属性_4_线的属性_2_线宽

画三视图时啥时候应画实线,啥时候画虚线?

怎么证明三阶行列式是它三个向量张成的六面体的体积,说思路就像

codeforces733D. Kostya the Sculptor 偏序cmp排序,数据结构hash,代码简化

世界上有没有正五面体?

世界上有没有正五面体?