计算机图形学六面体旋转并实时切换虚线实线 - 代码实现
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_线宽
怎么证明三阶行列式是它三个向量张成的六面体的体积,说思路就像