计算两点之间的偏移点坐标

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, startYendX, endY 的直线,而是画 2 条线 - 一条从 startX, startYdiversionX, 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>