计算两点之间的偏移点坐标
Calculate offset point coordinate between two points
我很难弄清楚如何表达这个,所以拍照时间。
我把点排列成一个圆圈,我知道所有点的 x,y
坐标。
我可以遍历每个点并在它们之间画一条线,很简单
//in a for each dot loop..
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.stroke();
这是我到现在为止。其他的我想不通
在迭代一个点时,我想创建一个左右交替的“转移”(就好像你正在从序列中的一个点看向下一个点)。
我想取两点之间直线的中点,向左或向右倾斜 90 度(比方说 i % 2
或其他),移动设定距离 d
并放置一个指向结束位置。每个点的距离 d
都不同,我已经为每个点确定了值。
然后继续迭代每个点,同时从两点之间的中线参考向左或向右交替创建偏移点。
当迭代一个点时,我不会画一条从 startX, startY
到 endX, endY
的直线,而是画 2 条线 - 一条从 startX, startY
到 diversionX, diversionY
和一条从那到 endX, endY
。最终的渲染结果是这样的。
我真正想问的是关于偏移点放置的帮助,我在学校与几何关系不大,这一直困扰着我..绘制路径是微不足道的,我只需要知道要绘制的点坐标 to/from..
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var pointSize = 5;
var points = [
[300, 50, 10], // x, y, offset point distance
[175, 80, 15],
[100, 185, 9],
[100, 315, 21],
[175, 420, 12],
[300, 460, 15],
[420, 420, 8],
[500, 315, 16],
[500, 185, 25],
[420, 80, 17]
];
for(var i = 0; i < points.length; i++) {
x = points[i][0];
y = points[i][1];
d = points[i][2]; // diversion length
// draw point
ctx.fillStyle = '#000000';
ctx.fillRect(x-(pointSize/2), y-(pointSize/2), pointSize, pointSize);
// draw temporary connecting line to next point
ctx.strokeStyle = '#d4d4d4';
nextPoint = points[(i + 1) % points.length];
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineWidth = 3;
ctx.lineTo(nextPoint[0], nextPoint[1]);
ctx.stroke();
// aaaaand I'm lost
// get midpoint of drawn line
// shoot off 90 degress to a side (i %2)
// travel distance of "d"
// get "d" x, y position
// draw lines between
// x,y and dx,dy
// dx,dy and nextX, nextY
}
<canvas id="canvas" width="600" height="600"></canvas>
获取直线的中心点
mid.X = (start.X + end.X) / 2;
mid.Y = (start.Y + end.Y) / 2;
从两点获取向量
vec.X = end.X - start.X;
vec.Y = end.Y - start.Y;
获取矢量形式点=>位置
这就像有一个从 0、0 到点 => 你的位置的向量,所以:
vec.X = mid.X;
vec.Y = mid.Y;
转90度
// Depending on the direction you'd either have to negate the x or y component
const prevY = vec.Y;
vec.Y = vec.X;
vec.X = -prevY;
const prevY = vec.Y;
vec.Y = -vec.X;
vec.X = prevY;
走一段距离
// You have 'point' in your case the center point and the rotated vector 'vec'
// Here you first calculate the length of 'vec'
// then get dX and dY that you move per unit in the direction of 'vec'
// then you multiply that with the distance and get your offset
const vecLength = Math.sqrt(vec.X * vec.X + vec.Y * vec.Y);
const xOffset = vec.X / vecLength * distance;
const yOffset = vec.Y / vecLength * distance;
添加一个偏移量(但我想这不是困难的部分;))
point.X += xOffset;
point.Y += yOffset;
这是已实施的解决方案:有一些临时图纸只是为了更清楚地说明每一步发生的事情。
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var pointSize = 5;
var points = [
[300, 50, 50], // x, y, offset point distance
[175, 80, 15],
[100, 185, 9],
[100, 315, 21],
[175, 420, 12],
[300, 460, 15],
[420, 420, 8],
[500, 315, 16],
[500, 185, 25],
[420, 80, 17]
];
for(var i = 0; i < points.length; i++) {
x = points[i][0];
y = points[i][1];
d = points[i][2]; // diversion length
// draw point
ctx.fillStyle = '#000000';
ctx.fillRect(x-(pointSize/2), y-(pointSize/2), pointSize, pointSize);
// draw temporary connecting line to next point
ctx.strokeStyle = '#d4d4d4';
nextPoint = points[(i + 1) % points.length];
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineWidth = 3;
ctx.lineTo(nextPoint[0], nextPoint[1]);
ctx.stroke();
const midX = (x + nextPoint[0]) / 2;
const midY = (y + nextPoint[1]) / 2;
// draw center point
ctx.fillStyle = '#00ff00';
ctx.fillRect(midX-(pointSize/2), midY-(pointSize/2), pointSize, pointSize);
const midXVec = nextPoint[0] - midX;
const midYVec = nextPoint[1] - midY;
const nMidXVec = i % 2 === 0 ? -midYVec : midYVec;
const nMidYVec = i % 2 === 0 ? midXVec : -midXVec;
// draw rotated vector from midpoint
ctx.strokeStyle = '#f1f1f1';
ctx.beginPath();
ctx.moveTo(midX, midY);
ctx.lineWidth = 3;
ctx.lineTo(midX + nMidXVec, midY + nMidYVec);
ctx.stroke();
const nMidLength = Math.sqrt(nMidXVec * nMidXVec + nMidYVec * nMidYVec);
const dXVec = nMidXVec / nMidLength * d;
const dYvec = nMidYVec / nMidLength * d;
const dX = midX + dXVec;
const dY = midY + dYvec;
// draw point dX, dY
ctx.fillStyle = '#ff0000';
ctx.fillRect(dX-(pointSize/2), dY-(pointSize/2), pointSize, pointSize);
// draw final lines
ctx.strokeStyle = '#000000';
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineWidth = 3;
ctx.lineTo(dX, dY);
ctx.lineTo(nextPoint[0], nextPoint[1]);
ctx.stroke();
}
<canvas id="canvas" width="600" height="600"></canvas>
我很难弄清楚如何表达这个,所以拍照时间。
我把点排列成一个圆圈,我知道所有点的 x,y
坐标。
我可以遍历每个点并在它们之间画一条线,很简单
//in a for each dot loop..
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.stroke();
这是我到现在为止。其他的我想不通
在迭代一个点时,我想创建一个左右交替的“转移”(就好像你正在从序列中的一个点看向下一个点)。
我想取两点之间直线的中点,向左或向右倾斜 90 度(比方说 i % 2
或其他),移动设定距离 d
并放置一个指向结束位置。每个点的距离 d
都不同,我已经为每个点确定了值。
然后继续迭代每个点,同时从两点之间的中线参考向左或向右交替创建偏移点。
当迭代一个点时,我不会画一条从 startX, startY
到 endX, endY
的直线,而是画 2 条线 - 一条从 startX, startY
到 diversionX, diversionY
和一条从那到 endX, endY
。最终的渲染结果是这样的。
我真正想问的是关于偏移点放置的帮助,我在学校与几何关系不大,这一直困扰着我..绘制路径是微不足道的,我只需要知道要绘制的点坐标 to/from..
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var pointSize = 5;
var points = [
[300, 50, 10], // x, y, offset point distance
[175, 80, 15],
[100, 185, 9],
[100, 315, 21],
[175, 420, 12],
[300, 460, 15],
[420, 420, 8],
[500, 315, 16],
[500, 185, 25],
[420, 80, 17]
];
for(var i = 0; i < points.length; i++) {
x = points[i][0];
y = points[i][1];
d = points[i][2]; // diversion length
// draw point
ctx.fillStyle = '#000000';
ctx.fillRect(x-(pointSize/2), y-(pointSize/2), pointSize, pointSize);
// draw temporary connecting line to next point
ctx.strokeStyle = '#d4d4d4';
nextPoint = points[(i + 1) % points.length];
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineWidth = 3;
ctx.lineTo(nextPoint[0], nextPoint[1]);
ctx.stroke();
// aaaaand I'm lost
// get midpoint of drawn line
// shoot off 90 degress to a side (i %2)
// travel distance of "d"
// get "d" x, y position
// draw lines between
// x,y and dx,dy
// dx,dy and nextX, nextY
}
<canvas id="canvas" width="600" height="600"></canvas>
获取直线的中心点
mid.X = (start.X + end.X) / 2;
mid.Y = (start.Y + end.Y) / 2;
从两点获取向量
vec.X = end.X - start.X;
vec.Y = end.Y - start.Y;
获取矢量形式点=>位置
这就像有一个从 0、0 到点 => 你的位置的向量,所以:
vec.X = mid.X;
vec.Y = mid.Y;
转90度
// Depending on the direction you'd either have to negate the x or y component
const prevY = vec.Y;
vec.Y = vec.X;
vec.X = -prevY;
const prevY = vec.Y;
vec.Y = -vec.X;
vec.X = prevY;
走一段距离
// You have 'point' in your case the center point and the rotated vector 'vec'
// Here you first calculate the length of 'vec'
// then get dX and dY that you move per unit in the direction of 'vec'
// then you multiply that with the distance and get your offset
const vecLength = Math.sqrt(vec.X * vec.X + vec.Y * vec.Y);
const xOffset = vec.X / vecLength * distance;
const yOffset = vec.Y / vecLength * distance;
添加一个偏移量(但我想这不是困难的部分;))
point.X += xOffset;
point.Y += yOffset;
这是已实施的解决方案:有一些临时图纸只是为了更清楚地说明每一步发生的事情。
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var pointSize = 5;
var points = [
[300, 50, 50], // x, y, offset point distance
[175, 80, 15],
[100, 185, 9],
[100, 315, 21],
[175, 420, 12],
[300, 460, 15],
[420, 420, 8],
[500, 315, 16],
[500, 185, 25],
[420, 80, 17]
];
for(var i = 0; i < points.length; i++) {
x = points[i][0];
y = points[i][1];
d = points[i][2]; // diversion length
// draw point
ctx.fillStyle = '#000000';
ctx.fillRect(x-(pointSize/2), y-(pointSize/2), pointSize, pointSize);
// draw temporary connecting line to next point
ctx.strokeStyle = '#d4d4d4';
nextPoint = points[(i + 1) % points.length];
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineWidth = 3;
ctx.lineTo(nextPoint[0], nextPoint[1]);
ctx.stroke();
const midX = (x + nextPoint[0]) / 2;
const midY = (y + nextPoint[1]) / 2;
// draw center point
ctx.fillStyle = '#00ff00';
ctx.fillRect(midX-(pointSize/2), midY-(pointSize/2), pointSize, pointSize);
const midXVec = nextPoint[0] - midX;
const midYVec = nextPoint[1] - midY;
const nMidXVec = i % 2 === 0 ? -midYVec : midYVec;
const nMidYVec = i % 2 === 0 ? midXVec : -midXVec;
// draw rotated vector from midpoint
ctx.strokeStyle = '#f1f1f1';
ctx.beginPath();
ctx.moveTo(midX, midY);
ctx.lineWidth = 3;
ctx.lineTo(midX + nMidXVec, midY + nMidYVec);
ctx.stroke();
const nMidLength = Math.sqrt(nMidXVec * nMidXVec + nMidYVec * nMidYVec);
const dXVec = nMidXVec / nMidLength * d;
const dYvec = nMidYVec / nMidLength * d;
const dX = midX + dXVec;
const dY = midY + dYvec;
// draw point dX, dY
ctx.fillStyle = '#ff0000';
ctx.fillRect(dX-(pointSize/2), dY-(pointSize/2), pointSize, pointSize);
// draw final lines
ctx.strokeStyle = '#000000';
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineWidth = 3;
ctx.lineTo(dX, dY);
ctx.lineTo(nextPoint[0], nextPoint[1]);
ctx.stroke();
}
<canvas id="canvas" width="600" height="600"></canvas>