JavaScript Bezier curve compute offset distance

78 views Asked by At

I am drawing a Bezier curve on drag cp1 and cp2 control points.

To draw Bezier Curve using D3js.

Bezier Curve four control points are line1,cp1,cp2 and line2.

I follow below steps to draw a 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);

When I drag cp1 from the mouse events I get positions cp1.

Now I know line1 and cp1 how do I compute dist.

I am using reference code from here

Using pointFromLine function I get cp1 and cp2. I dont know dist.

I also have another function calculatePoint to get cp1 and cp2 on a line1.

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 and d2 after finding the Euclidian Distance is not equal to 50.Is it correct Euclidian distance between line1 and cp1 give distance d1.

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 ))
}

I did not understand distance along and distance offset and how to compute if I know line1 and cp1

In the refernce here

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

I am not sure what is 'n'. I know cp1 and line1.

1

There are 1 answers

1
Keyboard Corporation On

The distance parameter in calculatePoint seems not the same as the dist parameter in pointFromLine. In calculatePoint, distance is the total distance from a to the calculated point, while in pointFromLine, dist is the perpendicular distance from the line at the calculated point.

If you want to calculate cp1 and cp2 such that they are 50 units away from line1 and line2 respectively, you should use pointFromLine instead of calculatePoint.

Modified in function 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);

Here, 0.5 is the proportion of the line from line1 to line2 where you want to calculate cp1 and cp2. If you want cp1 and cp2 to be at the midpoints of line1 and line2 respectively, you should use 0.5. If you want them to be at other positions, you should adjust this proportion accordingly.

*If you still get distances that are not equal to 50, it might be due to the way you are drawing your Bezier curve. The bezierCurveTo function in D3.js creates a cubic Bezier curve from the current point to (x, y) using (cp1x, cp1y) as the control point at the beginning of the curve and (cp2x, cp2y) as the control point at the end of the curve. If the curve does not pass through cp1 and cp2 exactly, the calculated points will not be 50 units away from line1 and line2.

I did not understand this point "In calculatePoint, distance is the total distance from a to the calculated point, while in pointFromLine, dist is the perpendicular distance from the line at the calculated point."

Clarification: In the calculatePoint, the distance parameter represents the total distance from point a (the starting point of the line segment) to the new point that the function calculates. This is calculated by scaling the vector from a to b (the end point of the line segment) by the ratio of distance to the length of the vector from a to b.

On the other hand, in the pointFromLine, the dist parameter represents the perpendicular distance from the line at the calculated point to the new point. This is calculated by adding a vector to the point on the line at the position specified by along that is perpendicular to the line and has a length of dist.

In other words, calculatePoint calculates a point along a line segment by scaling the vector from the start of the line segment to the end of the line segment, while pointFromLine calculates a point along a line segment by adding a vector perpendicular to the line at a specified position on the line segment.

The concept of perpendicular distance is used in the pointFromLine because it calculates a point along a line segment that is a certain distance away from the line at a specified position on the line segment. This is different from the concept of total distance used in the calculatePoint, which calculates a point along a line segment that is a certain total distance from the start of the line segment.