JavaScript 贝塞尔曲线计算偏移距离

JavaScript Bezier curve compute offset distance

提问人:B L Praveen 提问时间:11/6/2023 最后编辑:B L Praveen 更新时间:11/7/2023 访问量:59

问:

我正在绘制一个拖拽和控制点。Bezier curvecp1cp2

要使用 .Bezier CurveD3js

Bezier Curve四个控制点是 、 和 。line1cp1cp2line2

我按照以下步骤绘制一个Bezier curve

1)Moveto(Line1)

2)BezierCurve(Cp1 Cp2 Line2)

pathPoints = d3.path();
pathPoints.moveTo(allPaths[0].l1.x,allPaths[0].l1.y);
pathPoints.bezierCurveTo(cp1.x,cp1.y,cp2.x,cp2.y,item.l2.x,item.l2.y);

当我从鼠标事件中拖动时,我得到位置 cp1。cp1

现在我知道了,我该如何计算.line1cp1dist

我正在使用这里的参考代码

使用函数我得到和.我不知道。pointFromLinecp1cp2dist

我还有另一个函数 calculatePoint 要获取和在 .cp1cp2line1

cp1 = calculatePoint(item.l1,item.l2,50);
d1 = hypo(item.l1,cp1);
cp2 = calculatePoint(item.l2,item.l1,50);
d2 = hypo(item.l2,cp2);

d1并且发现欧几里得距离不等于 .欧几里得之间的距离是否正确,并给出距离。d250line1cp1d1

function pointFromLine(along, dist, p1, p2, res = {}) {
  const dx = p2.x - p1.x;
  const dy = p2.y - p1.y;
  res.x = p1.x + dx * along - dy * dist;
  res.y = p1.y + dy * along + dx * dist;
  return res;
}

function calculatePoint(a,b,distance)
{

  // a. calculate the vector from o to g:
  let vectorX = b.x - a.x;
  let vectorY = b.y - a.y;
  // b. calculate the proportion of hypotenuse
  let factor = distance / Math.sqrt(vectorX * vectorX + vectorY * vectorY);

  // c. factor the lengths
  vectorX *= factor;
  vectorY *= factor;

  // d. calculate and Draw the new vector,
  // return new Point((int)(a.X + vectorX), (int)(a.Y + vectorY));
  return {x:a.x + vectorX,y:a.y + vectorY}
}

function hypo(p0,p1){
  return Math.round(Math.sqrt((p1.x-p0.x)** 2  + (p1.y-p0.y)** 2 ))
}

我不明白,如果我知道,以及如何计算distance alongdistance offsetline1cp1

在这里的参考文献中

(4/3)*tan(pi/8) = 4*(sqrt(2)-1)/3

我不确定什么是“n”。我知道 cp1 和 line1。

JavaScript D3.js 立方贝塞尔

评论


答:

0赞 Keyboard Corporation 11/6/2023 #1

中的 distance 参数似乎与 中的参数不同。in , distance 是从计算点到的总距离,而 in , 是计算点处线的垂直距离。calculatePointdistpointFromLinecalculatePointapointFromLinedist

如果要计算 and 使它们分别相距 50 个单位,则应使用 代替 .cp1cp2line1line2pointFromLinecalculatePoint

函数 calculatePoint 中修改;

cp1 = pointFromLine(0.5, 50, item.l1, item.l2);
d1 = hypo(item.l1, cp1);
cp2 = pointFromLine(0.5, 50, item.l2, item.l1);
d2 = hypo(item.l2, cp2);

这里,0.5 是从要计算的位置到要计算的线的比例。如果要 和 分别位于 和 的中点,则应使用 0.5。如果你想让他们处于其他位置,你应该相应地调整这个比例。line1line2cp1cp2cp1cp2line1line2

*如果您仍然得到不等于 50 的距离,则可能是由于您绘制贝塞尔曲线的方式所致。D3.js 中的函数使用 (cp1x, cp1y) 作为曲线起点的控制点,使用 (cp2x, cp2y) 作为曲线末端的控制点,创建从当前点到 (x, y) 的三次贝塞尔曲线。如果曲线没有完全通过,则计算点不会与 相距 50 个单位。bezierCurveTocp1cp2line1line2

我不明白这一点“在 calculatePoint 中,distance 是从 a 到计算点的总距离,而在 pointFromLine 中,dist 是计算点处与线的垂直距离。

澄清:在 中,该参数表示从点(线段的起点)到函数计算的新点的总距离。这是通过将向量从 to(线段的终点)缩放到 与向量长度的比值来计算的。calculatePointdistanceaabdistanceab

另一方面,在 中,该参数表示从计算点处的直线到新点的垂直距离。这是通过向量向线上垂直于直线且长度为 的点的指定位置添加一个向量来计算的。pointFromLinedistalongdist

换句话说,通过缩放从线段起点到线段结束的矢量来计算沿线段的点,同时通过在线段上指定位置添加垂直于线的向量来计算沿线段的点。calculatePointpointFromLine

之所以使用垂直距离的概念,是因为它计算沿线段在线段上指定位置与线相距一定距离的点。这与 中使用的总距离概念不同,后者计算沿线段的点,该点距离线段起点有一定的总距离。pointFromLinecalculatePoint

评论

0赞 B L Praveen 11/6/2023
我不明白这一点“在 calculatePoint 中,distance 是从 a 到计算点的总距离,而在 pointFromLine 中,dist 是计算点处与线的垂直距离。