gpt4 book ai didi

javascript - 将格子图案添加到动态绘制的 3 人国际象棋棋盘

转载 作者:搜寻专家 更新时间:2023-10-31 08:10:51 25 4
gpt4 key购买 nike

你们好,一群了不起的天才!

我似乎已经达到了知识的顶峰,希望有人能给我指出正确的方向。

我正在尝试使用 JavaScript 和 HTML 5 Canvas 动态绘制 3 人国际象棋/跳棋棋盘。

到目前为止,我已经想到了这个;

var canvas = document.getElementById('canvas')
var length = canvas.height / 2;
var center = canvas.width / 2;

var rotation = ToRadians(60);

var angle = ToRadians(30);
var height = length * Math.cos(angle);
var width = length * Math.sin(angle);
while (rotation < Math.PI * 2) {
a = [center, length];
b = [a[0] - height * Math.sin(rotation), a[1] + height * Math.cos(rotation)];
c = [b[0] + width * Math.cos(rotation), b[1] + width * Math.sin(rotation)];
d = [c[0] + width * Math.sin(angle + rotation), c[1] - width * Math.cos(angle + rotation)];

//Drawing Main Frame and 6 segments
var c2 = canvas.getContext('2d');
c2.fillStyle = '#f00';
c2.strokeStyle = "#0f0";
c2.beginPath();
c2.moveTo(a[0], a[1]);
c2.lineTo(b[0], b[1]);
c2.lineTo(c[0], c[1]);
c2.lineTo(d[0], d[1]);
c2.closePath();
c2.stroke();

//Drawing first set of divides
ab1=[((a[0]+b[0])/2),((a[1]+b[1])/2)]
cd1=[((c[0]+d[0])/2),((c[1]+d[1])/2)]
ab2=[((a[0]+ab1[0])/2),((a[1]+ab1[1])/2)]
cd2=[((d[0]+cd1[0])/2),((d[1]+cd1[1])/2)]
ab3=[((b[0]+ab1[0])/2),((b[1]+ab1[1])/2)]
cd3=[((c[0]+cd1[0])/2),((c[1]+cd1[1])/2)]

c2.beginPath();
c2.moveTo(ab1[0], ab1[1]);
c2.lineTo(cd1[0], cd1[1]);
c2.moveTo(ab2[0], ab2[1]);
c2.lineTo(cd2[0], cd2[1]);
c2.moveTo(ab3[0], ab3[1]);
c2.lineTo(cd3[0], cd3[1]);
c2.stroke();

//Drawing second set of divides
bc1=[((c[0]+b[0])/2),((c[1]+b[1])/2)]
ad1=[((a[0]+d[0])/2),((a[1]+d[1])/2)]
bc2=[((c[0]+bc1[0])/2),((c[1]+bc1[1])/2)]
ad2=[((d[0]+ad1[0])/2),((d[1]+ad1[1])/2)]
bc3=[((b[0]+bc1[0])/2),((b[1]+bc1[1])/2)]
ad3=[((a[0]+ad1[0])/2),((a[1]+ad1[1])/2)]

c2.beginPath();
c2.moveTo(bc1[0], bc1[1]);
c2.lineTo(ad1[0], ad1[1]);
c2.moveTo(bc2[0], bc2[1]);
c2.lineTo(ad2[0], ad2[1]);
c2.moveTo(bc3[0], bc3[1]);
c2.lineTo(ad3[0], ad3[1]);
c2.stroke();

rotation += ToRadians(60);
}
function ToRadians(degrees) {
return degrees / (180 / Math.PI);
}

fiddle :http://jsfiddle.net/yd7Wv/6529/

到目前为止,我对代码非常满意,但当我需要添加已检查的模式时,我完全被难住了。我真的不知道该怎么做,所以想知道是否有人可以指出我正确的方向。我知道这里有一个普遍的共识,即人们应该尝试自己做,但我就是做不到!任何指针将不胜感激。

干杯

最佳答案

您所看到的与四边形变换密切相关。

您可以将一个线段(“三 Angular 形”)看成一个象限,只是在视角上发生了扭曲。

Fiddle demo

产生这个结果:

Board

让我们从定义计算和循环所需的一些变量开始。

var w = canvas.width,                // width
h = canvas.height, // height
cx = w * 0.5, // center of board
cy = h * 0.5,
r = cx * 0.9, // radius of board
pi2 = Math.PI * 2, // cache
segments = 6, // a hexagon based shape so 6
segment = pi2 / segments, // angle of each segment
hSegment = segment * 0.5, // half segment for center line
ul, ur, bl, br, // quad. corners
check = 0.25, // interpolation interval (one check)
yc = 0, xc = 0, // interpolation counters
toggle = false, // for color
x, y = 0, i = 0; // counters...

让我们通过定义外边界的 Angular 来定义一个四边形正方形:

第一个 Angular 将是板的中心,这样就很简单了:

var ul = {
x: cx,
y: cy}

第二个 Angular 在右上角:

ur = {
x: cx + r * Math.cos(hSegment) * 0.865,
y: cy + r * Math.sin(hSegment) * 0.865
};

右下角第三个:

br = {
x: cx + r * Math.cos(segment),
y: cy + r * Math.sin(segment)
};

最后,左下角:

bl = {
x: cx + r * Math.cos(hSegment + segment) * 0.865,
y: cy + r * Math.sin(hSegment + segment) * 0.865
};

如果我们画出这个形状,我们会得到这个:

Quadrilateral outline

现在我们有了 Angular 点,我们只需按照检查间隔 (0.25) 对“正方形”中的每条线进行插值,这将总共提供 5 条线。我们只会计算 4,但我们也会使用包含当前值的行。

为了对两点进行插值,我们使用一个简单的函数,它接受两个点和一个归一化值 [0.0, 1.0]:

function getInt(p1, p2, t) {
return {
x: p1.x + (p2.x - p1.x) * t,
y: p1.y + (p2.y - p1.y) * t,
}
}

我们创建一个循环来遍历 y 点和 x 点,这样我们就可以以系统的方式执行此操作:

for(y = 0, yc = 0; y < 4; y++) {
for(x = 0, xc = 0; x < 4; x++) {

// for upper lines (ul-ur), get first row:
var l1a = getInt(ul, bl, yc),
l1b = getInt(ur, br, yc),
l2a = getInt(ul, bl, yc + check),
l2b = getInt(ur, br, yc + check),

c1 = getInt(l1a, l1b, xc),
c2 = getInt(l1a, l1b, xc + check),
c3 = getInt(l2a, l2b, xc + check),
c4 = getInt(l2a, l2b, xc);

... draw shape ...

xc += check;
}
yc += check;
}

本节:

var l1a = getInt(ul, bl, yc),          // current line [0, 3]
l1b = getInt(ur, br, yc),
l2a = getInt(ul, bl, yc + check), // next line [1, 4]
l2b = getInt(ur, br, yc + check),

计算外垂直线上的插值点。这给了我们两个新点,然后我们用它们来计算水平线上的一个点,并使我们能够计算每个 Angular 点以进行“检查”:

c1 = getInt(l1a, l1b, xc),          // corner 1 UL
c2 = getInt(l1a, l1b, xc + check), // corner 2 UR (next line)
c3 = getInt(l2a, l2b, xc + check), // corner 3 BR (next line)
c4 = getInt(l2a, l2b, xc); // corner 4 BL

现在我们只需在这些 Angular 之间绘制一个多边形并填充:

ctx.beginPath();
ctx.moveTo(c1.x, c1.y);
ctx.lineTo(c2.x, c2.y);
ctx.lineTo(c3.x, c3.y);
ctx.lineTo(c4.x, c4.y);

ctx.fillStyle = toggle ? '#000' : '#fff';

我们使用拨动开关来改变颜色。

这个片段看起来像这样:

Single segment

下一步是绘制所有线段。我们重复使用上面的代码,每次简单地旋转 Canvas 一个片段并进行额外的切换。

当所有代码放在一起时,我们得到:

for(; i < segments; i++) {    // loop six segments
toggle = !toggle; // alter color each segment
// loop quadrilateral grid 4x4 cells (5x5 lines exclusive)
for(y = 0, yc = 0; y < 4; y++) {
for(x = 0, xc = 0; x < 4; x++) {

// for upper lines (ul-ur), get first row:
var l1a = getInt(ul, bl, yc),
l1b = getInt(ur, br, yc),
l2a = getInt(ul, bl, yc + check),
l2b = getInt(ur, br, yc + check),
c1 = getInt(l1a, l1b, xc),
c2 = getInt(l1a, l1b, xc + check),
c3 = getInt(l2a, l2b, xc + check),
c4 = getInt(l2a, l2b, xc);

ctx.beginPath();
ctx.moveTo(c1.x, c1.y);
ctx.lineTo(c2.x, c2.y);
ctx.lineTo(c3.x, c3.y);
ctx.lineTo(c4.x, c4.y);
ctx.fillStyle = toggle ? '#000' : '#fff';
ctx.fill();
toggle = !toggle;
xc += check;
}
yc += check; // next segment line
toggle = !toggle; // toggle per line as well
}
ctx.translate(cx, cy); // translate to center
ctx.rotate(segment); // rotate one segment
ctx.translate(-cx, -cy); // translate back
}

现在您可以根据需要简单地绘制轮廓等等。

关于javascript - 将格子图案添加到动态绘制的 3 人国际象棋棋盘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22368144/

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