马黑黑 发表于 2024-4-30 18:44

用canvas画布绘制立方体框架(方法二)

本帖最后由 马黑黑 于 2024-4-30 18:49 编辑 <br /><br /><canvas id="canv" width="400" height="400"></canvas>

<script>

var ctx = canv.getContext('2d');
var x = 50, y = 150, width = 200;
var curX = x, curY = y;
points = [
        {x: x + width, y: y},
        {x: x, y: y},
        {x: x, y: y + width},
        {x: x + width, y: y + width},
        {x: x + width*3/2, y: y + width/2},
        {x: x + width*3/2, y: y - width/2},
        {x: x + width/2, y: y - width/2},
        {x: x + width/2, y: y + width/2}
];

ctx.strokeStyle = 'cyan';

var draw = () => {
        ctx.beginPath();
        ctx.moveTo(points.x, points.y);
        for(var j = 1; j < points.length; j ++) {
                ctx.lineTo(points.x, points.y);
        }
        ctx.lineTo(points.x, points.y);
        ctx.stroke();
};

draw();

ctx.translate(200,200);
ctx.rotate(180 * Math.PI / 180);
ctx.translate(-200,-200);
draw();

</script>

马黑黑 发表于 2024-4-30 18:45

本帖最后由 马黑黑 于 2024-4-30 18:51 编辑 <br /><br /><style>
.mum { position: relative; margin: 0; padding: 10px; font: normal 16px/20px Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; color: black; background: rgba(240, 240, 240,.95); box-shadow: 2px 2px 4px gray; border: thick groove lightblue; border-radius: 6px; }
.mum ::selection { background-color: rgba(0,100,100,.35); }
.mum div { margin: 0; padding: 0; }
.mum cl-cd { display: block; position: relative; margin: 0 0 0 50px; padding: 0 0 0 10px; white-space: pre-wrap; overflow-wrap: break-word; border-left: 1px solid silver; }
.mum cl-cd::before { position: absolute; content: attr(data-idx); width: 50px; color: gray; text-align: right; transform: translate(-70px); }
.tRed { color: red; }
.tBlue { color: blue; }
.tGreen { color: green; }
.tDarkRed { color: darkred; }
.tMagenta { color: magenta; }
</style>

<h2>代码(去掉注释可以填充颜色)</h2>
<div class='mum'>
<cl-cd data-idx="1">&lt;<span class="tDarkRed">canvas</span> <span class="tRed">id</span>=<span class="tMagenta">"canv"</span> width=<span class="tMagenta">"400"</span> height=<span class="tMagenta">"400"</span>&gt;&lt;<span class="tDarkRed">/canvas</span>&gt;</cl-cd>
<cl-cd data-idx="2">&nbsp;</cl-cd>
<cl-cd data-idx="3">&lt;<span class="tDarkRed">script</span>&gt;</cl-cd>
<cl-cd data-idx="4">&nbsp;</cl-cd>
<cl-cd data-idx="5"><span class="tBlue">var</span> ctx = canv.getContext(<span class="tMagenta">'2d'</span>);</cl-cd>
<cl-cd data-idx="6"><span class="tBlue">var</span> x = 50, y = 150, width = 200;</cl-cd>
<cl-cd data-idx="7"><span class="tBlue">var</span> curX = x, curY = y;</cl-cd>
<cl-cd data-idx="8">points = [</cl-cd>
<cl-cd data-idx="9">&nbsp; &nbsp; {<span class="tBlue">x:</span> x + width, <span class="tBlue">y:</span> y},                <span class="tGreen">// 1</span></cl-cd>
<cl-cd data-idx="10">&nbsp; &nbsp; {<span class="tBlue">x:</span> x, <span class="tBlue">y:</span> y},                        <span class="tGreen">// 2</span></cl-cd>
<cl-cd data-idx="11">&nbsp; &nbsp; {<span class="tBlue">x:</span> x, <span class="tBlue">y:</span> y + width},                <span class="tGreen">// 3</span></cl-cd>
<cl-cd data-idx="12">&nbsp; &nbsp; {<span class="tBlue">x:</span> x + width, <span class="tBlue">y:</span> y + width},      <span class="tGreen">// 4</span></cl-cd>
<cl-cd data-idx="13">&nbsp; &nbsp; {<span class="tBlue">x:</span> x + width*3/2, <span class="tBlue">y:</span> y + width/2},<span class="tGreen">// 5</span></cl-cd>
<cl-cd data-idx="14">&nbsp; &nbsp; {<span class="tBlue">x:</span> x + width*3/2, <span class="tBlue">y:</span> y - width/2},<span class="tGreen">// 6</span></cl-cd>
<cl-cd data-idx="15">&nbsp; &nbsp; {<span class="tBlue">x:</span> x + width/2, <span class="tBlue">y:</span> y - width/2},    <span class="tGreen">// 7</span></cl-cd>
<cl-cd data-idx="16">&nbsp; &nbsp; {<span class="tBlue">x:</span> x + width/2, <span class="tBlue">y:</span> y + width/2}   <span class="tGreen">// 8</span></cl-cd>
<cl-cd data-idx="17">];</cl-cd>
<cl-cd data-idx="18">&nbsp;</cl-cd>
<cl-cd data-idx="19">ctx.strokeStyle = <span class="tMagenta">'cyan'</span>;</cl-cd>
<cl-cd data-idx="20"><span class="tGreen">//ctx.fillStyle = <span class="tMagenta">'rgba(0,128,128,.4)'</span>;</span></cl-cd>
<cl-cd data-idx="21">&nbsp;</cl-cd>
<cl-cd data-idx="22"><span class="tBlue">var</span> draw = () =&gt; {</cl-cd>
<cl-cd data-idx="23">&nbsp; &nbsp; ctx.beginPath();</cl-cd>
<cl-cd data-idx="24">&nbsp; &nbsp; ctx.moveTo(points.x, points.y);</cl-cd>
<cl-cd data-idx="25">&nbsp; &nbsp; <span class="tBlue">for</span>(<span class="tBlue">var</span> j = 1; j &lt; points.length; j ++) {</cl-cd>
<cl-cd data-idx="26">&nbsp; &nbsp; &nbsp; &nbsp; ctx.lineTo(points.x, points.y);</cl-cd>
<cl-cd data-idx="27">&nbsp; &nbsp; }</cl-cd>
<cl-cd data-idx="28">&nbsp; &nbsp; ctx.lineTo(points.x, points.y);</cl-cd>
<cl-cd data-idx="29">&nbsp; &nbsp; ctx.stroke();</cl-cd>
<cl-cd data-idx="30">};</cl-cd>
<cl-cd data-idx="31">&nbsp;</cl-cd>
<cl-cd data-idx="32">draw();</cl-cd>
<cl-cd data-idx="33"><span class="tGreen">//ctx.fill();</span></cl-cd>
<cl-cd data-idx="34">&nbsp;</cl-cd>
<cl-cd data-idx="35">ctx.translate(200,200);</cl-cd>
<cl-cd data-idx="36">ctx.rotate(180 * <span class="tRed">Math</span>.PI / 180);</cl-cd>
<cl-cd data-idx="37">ctx.translate(-200,-200);</cl-cd>
<cl-cd data-idx="38">draw();</cl-cd>
<cl-cd data-idx="39"><span class="tGreen">//ctx.fill();</span></cl-cd>
<cl-cd data-idx="40">&lt;<span class="tDarkRed">/script</span>&gt;</cl-cd>
</div>

马黑黑 发表于 2024-4-30 18:52

本帖最后由 马黑黑 于 2024-4-30 19:28 编辑

八个顶点是酱紫安排:

   7      6
2      1
    8      5
3      4

以上,按顺序连线并在最后连到 3 就是立方体的一半。然后将画布旋转180度再画另一半。二者拼凑起来,就是立方体了。

马黑黑 发表于 2024-4-30 19:46

本帖最后由 马黑黑 于 2024-4-30 19:47 编辑

立方体八个顶点示意图
https://638183.freep.cn/638183/small/3dbox.png
两次绘制的点顺序:1 2 3 4 5 6 7 8 3
第二次绘制前变更画布:旋转180度,位移画布坐标系到(200,200)

小辣椒 发表于 2024-4-30 20:32

上课了。。。铃声响起,小辣椒做教室里面认真听课了,懂不懂另一回事。认真听讲还是应该做到的{:4_173:}

马黑黑 发表于 2024-4-30 20:46

小辣椒 发表于 2024-4-30 20:32
上课了。。。铃声响起,小辣椒做教室里面认真听课了,懂不懂另一回事。认真听讲还是应该做到的

立体的东东是相对复杂的,比平面复杂N多倍

红影 发表于 2024-4-30 21:32

这个比前面那个绘制简单,先做出8个顶点,然后通过连线和旋转再连线,得到了边框或填充图案。
但是这个比前面一个更难理解些。

马黑黑 发表于 2024-4-30 21:34

红影 发表于 2024-4-30 21:32
这个比前面那个绘制简单,先做出8个顶点,然后通过连线和旋转再连线,得到了边框或填充图案。
但是这个比 ...

难点一:顶点顺序。理清这个,并尝试绘制一次不翻转的,就什么都能明白;

难点二:画布坐标系位移、翻转。这个之前做时钟的时候讲到过,弄懂它也不是太麻烦。

红影 发表于 2024-4-30 21:36

立方体6个面12条线,看代码好像连了7条,旋转后再连7条,这里面有重复连线?

红影 发表于 2024-4-30 21:38

点的分部位置看明白了,连线有点懵。
旋转后的点号不是现在的样子了吧。

马黑黑 发表于 2024-4-30 21:39

红影 发表于 2024-4-30 21:36
立方体6个面12条线,看代码好像连了7条,旋转后再连7条,这里面有重复连线?

实际上每一次画了八条线,第二次翻转180度,线会有重叠。

如果你能找出一次性画 12 条连接的线,那就不会有重复。

马黑黑 发表于 2024-4-30 21:40

红影 发表于 2024-4-30 21:38
点的分部位置看明白了,连线有点懵。
旋转后的点号不是现在的样子了吧。

旋转后你跟着旋转,一切都不会有变化

小辣椒 发表于 2024-4-30 21:46

马黑黑 发表于 2024-4-30 20:46
立体的东东是相对复杂的,比平面复杂N多倍

所以小辣椒以后不会的更加多了

马黑黑 发表于 2024-4-30 22:47

小辣椒 发表于 2024-4-30 21:46
所以小辣椒以后不会的更加多了

会该会的就行

红影 发表于 2024-5-1 08:11

马黑黑 发表于 2024-4-30 21:34
难点一:顶点顺序。理清这个,并尝试绘制一次不翻转的,就什么都能明白;

难点二:画布坐标系位移、翻 ...

嗯,顶点顺序不难懂,主要翻转迷糊了一下。应该也是不难{:4_173:}

红影 发表于 2024-5-1 08:15

马黑黑 发表于 2024-4-30 21:39
实际上每一次画了八条线,第二次翻转180度,线会有重叠。

如果你能找出一次性画 12 条连接的线,那就 ...

是的,每次画了8条,我忘了还要回到3号点{:4_173:}
用这样的方式一次性画12条是不可能的,除非后面单独补缺失的4条。

红影 发表于 2024-5-1 08:15

马黑黑 发表于 2024-4-30 21:40
旋转后你跟着旋转,一切都不会有变化

有道理{:4_173:}

马黑黑 发表于 2024-5-1 08:16

红影 发表于 2024-5-1 08:15
有道理

{:4_172:}

马黑黑 发表于 2024-5-1 08:17

红影 发表于 2024-5-1 08:15
是的,每次画了8条,我忘了还要回到3号点
用这样的方式一次性画12条是不可能的,除非后面单独 ...

补缺失的还有 moveTo 几次,何必呢

马黑黑 发表于 2024-5-1 08:18

红影 发表于 2024-5-1 08:11
嗯,顶点顺序不难懂,主要翻转迷糊了一下。应该也是不难

画布坐标系移位+翻转+移位回,这是画布旋转物体的方法,这个一定要理解
页: [1] 2 3 4 5 6 7 8 9
查看完整版本: 用canvas画布绘制立方体框架(方法二)