Perpendicular

Method: point.perpendicular(Pt1, Pt2)

Parameters:

  • Pt1 — first point defining the line

  • Pt2 — second point defining the line

Returns: Point — the foot of the perpendicular from this onto the line


Description

Given a point \(P\) (this) and an infinite line passing through points \(A\) (Pt1) and \(B\) (Pt2), perpendicular returns the point \(F\) on the line that is closest to \(P\) — the foot of the perpendicular from \(P\) to the line.

Derivation

Define two vectors:

\[\overrightarrow{AB} = B - A = (B_x - A_x,\ B_y - A_y)\]
\[\overrightarrow{AP} = P - A = (P_x - A_x,\ P_y - A_y)\]

Any point on the infinite line can be written as \(A + t\,\overrightarrow{AB}\) for some scalar \(t\). The foot of the perpendicular is the value of \(t\) that minimises the distance from \(P\) to the line, found by projecting \(\overrightarrow{AP}\) onto \(\overrightarrow{AB}\):

\[t = \frac{\overrightarrow{AB} \cdot \overrightarrow{AP}}{|\overrightarrow{AB}|^2}\]

The dot product in the numerator measures how much of \(\overrightarrow{AP}\) lies along \(\overrightarrow{AB}\); dividing by the squared magnitude normalises this to a parameter value. The foot of the perpendicular is then:

\[F = A + t\,\overrightarrow{AB}\]

When \(t = 0\), \(F\) coincides with \(A\); when \(t = 1\), \(F\) coincides with \(B\). Values outside \([0, 1]\) fall on the line extended beyond the segment.

Implementation

perpendicular(Pt1, Pt2) {
  const APx = this.x - Pt1.x;
  const APy = this.y - Pt1.y;
  const ABx = Pt2.x - Pt1.x;
  const ABy = Pt2.y - Pt1.y;

  const magAB2 = ABx * ABx + ABy * ABy;
  const ABdotAP = ABx * APx + ABy * APy;
  const t = ABdotAP / magAB2;

  const x = Pt1.x + ABx * t;
  const y = Pt1.y + ABy * t;
  return new Point(x, y);
}

Usage in Design

  • Object snapping — the nearest snap type finds the closest point on a line or polyline segment to the cursor by calling perpendicular with the segment endpoints.

  • RotatedDimension — after the user specifies the rotation angle, the measured point (Pt14) is projected onto the dimension line axis using perpendicular. The direction vector for the axis is first obtained with project(angleRad, 1), making the two methods work in tandem:

    const dimLineDir = Pt11.project(angleRad, 1);
    const foot = Pt14.perpendicular(Pt11, dimLineDir);
    
  • Trim / Extend — intersection resolution uses perpendicular projection to determine where an entity edge meets a boundary.

See Also

Dot Product | Project | Development