gpt4 book ai didi

html5 - 使用贝塞尔曲线的拼图碎片

转载 作者:太空宇宙 更新时间:2023-11-04 13:40:41 25 4
gpt4 key购买 nike

我想做一些这样的拼图-
我到现在为止一直在用lineTo-

outside: function (ctx, s, cx, cy) {
ctx.lineTo(cx, cy)
ctx.lineTo(cx+s*.3, cy)
ctx.lineTo(cx+s*.5, cy+s*-.2)
ctx.lineTo(cx+s*.7, cy)
ctx.lineTo(cx+s, cy)
},
inside: function (ctx, s, cx, cy) {
ctx.lineTo(cx, cy)
ctx.lineTo(cx+s*.3, cy)
ctx.lineTo(cx+s*.5, cy+s*+.2)
ctx.lineTo(cx+s*.7, cy)
ctx.lineTo(cx+s, cy)
},

Fiddle Link

最佳答案

高效的拼图设计非常简单,其工作原理如下:
链接的代码已经展示了如何通过重用单面设计来高效地组装拼图块。
插图右侧的部分是传统的(或“日本风格”)部分。这意味着它的两侧长度一致,完全互锁。日式拼图最容易设计,因为一段设计代码可以在整个拼图中重用。
具有讽刺意味的是,虽然日式拼图是最容易编码的,但对用户来说更难解决,因为许多拼图块在没有正确解决拼图的情况下会在物理上组合在一起。
如何设计日式拼图
设计一边(不要更多!)由多个三次贝塞尔曲线组合而成的拼图。
根据需要,使用变换将该拼图设计应用于顶部、右侧、底部或左侧。(或代码功能,自动操作原始贝塞尔控制点,以应用一个拼图设计到4个方面)。镜像原始的侧面设计,让您的作品有各种“inny”和“outy”的侧面。
通过镜像每个相邻边的设计,将拼图拼成碎片:
给左上角(0,0)一个随机的右侧(inny或outy)。
假设工件(0,0)被分配了一个外侧右侧。然后右边的下一块(1,0)必须有一个小的左边。
现在给片(1,0)一个随机的右边(inny或outy),片(2,0)必须得到镜像类型的边。等等。。。
因此,一般来说,填充拼图的方法是将随机的右侧指定给所有块,并将指定的一侧镜像到下一块的左侧。
在垂直方向上做同样的操作。通过将随机的底部边分配给所有的块,并将分配的边镜像到下一块的顶部来填充拼图。
设计你所展示的两个例子
我假设链接的代码不是您的代码,因为它已经展示了如何在您的插图右侧设计该部分(!).

// Given the center point of the piece (cx,cy) and the side length (s)
// The single side "outy" design is below
// Use this single design (with transforms/mirroring) to make all pieces
ctx.lineTo(cx + s * .34, cy);
ctx.bezierCurveTo(cx + s * .5, cy, cx + s * .4, cy + s * -.15, cx + s * .4, cy + s * -.15);
ctx.bezierCurveTo(cx + s * .3, cy + s * -.3, cx + s * .5, cy + s * -.3, cx + s * .5, cy + s * -.3);
ctx.bezierCurveTo(cx + s * .7, cy + s * -.3, cx + s * .6, cy + s * -.15, cx + s * .6, cy + s * -.15);
ctx.bezierCurveTo(cx + s * .5, cy, cx + s * .65, cy, cx + s * .65, cy);
ctx.lineTo(cx + s, cy);

然后,您可以重用这一组贝塞尔曲线以及转换来创建整个谜题。变换=移动、旋转和镜像单个设计,以构成任何拼图块的任何边。
插图左边的部分可能来自自由形式的拼图。它更复杂,因为它使用3种不同的侧面设计。我假设你还没有展示其他的侧面设计,因为你展示的3面设计不允许所有的部分相互连接来完成拼图。
在创建自由形式的拼图时,有几个选项。
非联锁自由形式样式
在这种样式中,基本上是取一个图像并绘制线,将其切割成可以排列成图像的非均匀块。把它想象成一个被随意切成片的比萨饼。你可以把这些碎片拼凑在一起来改造披萨,即使这些碎片没有连锁。嗯,披萨!:-)
联锁自由形式样式
在这种风格中,你设计2+面和创建拼图的方式与传统风格的拼图几乎相同。通常,您创建一个用于所有左右侧的设计,第二个用于所有上下侧的设计。复杂的是,这2种类型的边必须在它们相遇的地方相配。这意味着side-type-1必须在与side-type-2相交的位置共享镜像模式。
因此,要设计插图左侧的部分,必须确定是联锁自由形式还是非联锁自由形式。
非联锁自由形式更容易。只需将这三种类型的边分开,并与镜像的伙伴一起使用它们来分割您的图像。
对于联锁自由形式,更多的设计工作是必要的一部分。您必须创建额外的侧面设计,将与您已经创建的3个设计互锁。
这是一个快速的拼图之旅…祝你的项目好运!
[其他详细信息]
对于插图右侧的部分,常见的“外侧”看起来像“肩部和头部”轮廓。
贝塞尔设置为创建肩部和头部这样的分解:
“左肩”的贝塞尔
“左脖子”的贝塞尔
“左头”的贝塞尔
“右头”的贝塞尔
“右脖子”的贝塞尔
“右肩”的贝塞尔
肩部和头部贝塞尔装置可能如下所示:
下面是一个特定的控制点示例,用于创建具有“肩部和头部”形状的外侧:
var ShouldersAndHeadCubicBezierControlPoints=[
{cx1:0, cy1:0, cx2:35,cy2:15, ex:37, ey:5}, // left shoulder
{cx1:37, cy1:5, cx2:40,cy2:0, ex:38, ey:-5}, // left neck
{cx1:38, cy1:-5, cx2:20,cy2:-20,ex:50, ey:-20}, // left head
{cx1:50, cy1:-20,cx2:80,cy2:-20,ex:62, ey:-5}, // right head
{cx1:62, cy1:-5, cx2:60,cy2:0, ex:63, ey:5}, // right neck
{cx1:63, cy1:5, cx2:65,cy2:15, ex:100,ey:0}, // right shoulder
];

一旦有了“outside”曲线集,就可以使用canvas的上下文转换将“outside”翻转为其镜像的“inside”。或者,可以手动反转曲线控制点的“外部”数组。
插图:顶部选项卡和顶部插槽(顶部插槽镜像顶部选项卡)
显示顶部选项卡和顶部插槽的示例:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
function reOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }

ctx.lineWidth=3;
var colors=['red','green','blue','gold','purple','cyan'];

var bSet=makeBeziers();

draw(bSet,50,100);

var bSetMirrored=mirror(bSet,1,-1,0,0);

draw(bSetMirrored,50,200);

function draw(bSet,transX,transY){
ctx.translate(transX,transY);
ctx.scale(2,2);
for(var i=0;i<bSet.length;i++){
var b=bSet[i];
ctx.beginPath();
ctx.bezierCurveTo(b.cx1,b.cy1,b.cx2,b.cy2,b.ex,b.ey);
ctx.strokeStyle=colors[i];
ctx.stroke();
}
ctx.setTransform(1,0,0,1,0,0);
}


function makeBeziers(){
return([
{cx1:0, cy1:0, cx2:35,cy2:15, ex:37, ey:5}, // left shoulder
{cx1:37, cy1:5, cx2:40,cy2:0, ex:38, ey:-5}, // left neck
{cx1:38, cy1:-5, cx2:20,cy2:-20,ex:50, ey:-20}, // left head
{cx1:50, cy1:-20,cx2:80,cy2:-20,ex:62, ey:-5}, // right head
{cx1:62, cy1:-5, cx2:60,cy2:0, ex:63, ey:5}, // right neck
{cx1:63, cy1:5, cx2:65,cy2:15, ex:100,ey:0}, // right shoulder
]);
}

function mirror(b,signX,signY,x,y){
var a=[];
for(var i=0;i<b.length;i++){
var bb=b[i];
a.push({
cx1: bb.cx1*signX+x,
cy1: bb.cy1*signY+y,
cx2: bb.cx2*signX+x,
cy2: bb.cy2*signY+y,
ex: bb.ex*signX+x,
ey: bb.ey*signY+y
});
}
return(a);
}

body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }

<canvas id="canvas" width=300 height=300></canvas>

关于html5 - 使用贝塞尔曲线的拼图碎片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30617132/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com