## Freesteel Blog » Biarc geometry done easy

## Biarc geometry done easy

Wednesday, January 20th, 2016 at 4:57 pm

*This is about C-shaped biarcs. I’m not interested in the S-shaped ones, so I’ve not looked at them.*

A Biarc is a smooth curve composed of two consecutive tangential circular arcs that can be drawn between a given pair of points with a given tangency at those points.

In many ways a biarc fulfills the job of a cubic spline commonly used in CAD to interpolate a curve between two points with given tangencies. They can be chained to form a continuous curve that appears smooth to the eye (continuous first derivative) all along its length.

Given end points and tangent vectors, there are two extra degrees of freedom for the cubic spline. These are usually called the *weight factors*.

A biarc has only one extra degree of freedom, which determines the point where the two arcs join tangentially.

Biarcs have a larger application in CAM than CAD for the following reasons:

**1)** CNC mechanisms whose motions are controlled by G-code (most of them) have G1 for linear motion as well as G2 and G3 for circular arc clockwise and circular arc counter-clockwise. They do not have codes to do arcs (although Siemens tried to market a controller in the 1990s that had NURBS), so if you want to produce a perfectly smooth path then you need to provide a sequence of tangential arcs. Biarcs can effectively act as a drop-in replacement for cubic splines.

**2)** Physical machines in motion are limited by their maximum acceleration which is determined by the power. A cubic spline has a maximum acceleration (minimum curvature) at only one point along its length, and this means all the other points have to be run below this value. On the other hand, a circular arc has a constant and easy to calculate acceleration for a given velocity. This means it is more likely to be programmed to attain the maximum power over a longer distance than is the case for cubic splines which are too hard to optimize.

Let’s get to the point. After days of messy algebra, similar to what’s been done by this guy and in other papers I have read, I spotted a pattern, which I have reduced to a nice theorem in plane geometry.

Theorem:Given pointsAandBand tangent vectors at them that intersect atE, we consider any biarc that is consistent with these endpoints and tangents. (This is defined as two circular arcs that are tangent at these points and to each other)This biarc is drawn as the arc

AC(with centrea) and the arcCB(with centreb)If we extend the line

EBto the pointDso that the length ofEDequals the length ofEAthen the pointCwhere the two arcs meet will always lie on the circle through the pointsA,BandD(whose centre isc)

proof:

The pointsA,B,E,Dare given by the initial conditions. PointsC,a,bare given by the choice of biarc.By the definition of the biarc, the line

aA(which is a radius of the left hand big arc) is perpendicular to the lineAE, the linebB(which is a radius of the right hand small arc) is perpendicular toBE, and the pointsa,bandCmust be collinear for the two arcs to be tangential atC.Let

fbe the midpoint of the arcACandgbe the midpoint of the arcBCand draw in the linesafandbgto form bisectors of their respective arc angles.Extend the line

bgback to the pointcwhere it intersects the lineaf.By symmetry (of

afbeing a bisection line), the lengths ofcAandcChave the same length. Similarly the linescCandcBhave the same length. Therefore the three pointsA,BandCall lie on the orange circle whose centre is atcwhich we just constructed by intersecting these two bisector lines.By bisector symmetry the angle

aAcspecified bydis equal to the angleaCc, and the anglecCbis equal to the anglecBbspecified byd’. In other wordsdequalsd’.The tangent line to the orange circle at

Ais perpendicular to the radius linecA; if we rotate it anticlockwise about the pointAthrough the angledthen it will be aligned withAE. Similarly, the tangent line to the orange circle atBis perpendicular to the radius linebB, and if we rotate it anticlockwise about the pointBthrough the angled’then it will be aligned withEB.Because the construction of both these lines are the equivalent (due to the sizes of the angles

dandd’being the same), the chord lengths ofAhandBkare the same (whereA,handEare collinear andE,Bandkare collinear).We need to equate the angles

chEandchEto prove symmetry. The perpendicular bisector of the chordAhwill pass through the centre of the circlec, and therefore by symmetry around this line the anglechEis equal to 90 degrees plus the angled. But we also know that the anglecBEis also 90 degrees plus the same angled’(since the linesbBandBEare perpendicular).This proves that the triangles

chEandcBEare equal. Therefore the line lengthEhequalsEB. Since the chord lengthsAhandBkare equal, the length ofBkis the length ofAEminus the length ofEh, which putskat exactly the point where we originally constructedDin the statement of the theorem.The orange circle about

cpasses through the pointsA,BandD, which is a statement that crucially does not depend on the choice of the biarc.

I’m not saying that any of the above is easy. The consequence, however, is a remarkably easy method to find biarcs.

Using my namedtuple P2 class with a few basic functions, like so:

class P2(namedtuple('P2', ['u', 'v'])): ... def Dot(a, b): return a.u*b.u + a.v*b.v def CPerp(v): return P2(v.v, -v.u) def APerp(v): return P2(-v.v, v.u)

Start with the points **A** and **B** with unit normal vectors **nA** and **nB**.

To find the intersection of the tangents we need to solve:

E = A + CPerp(nA)*sA = B + APerp(nB)*sB

Compute the values of **sA** and **sB** by dotting this equation with **nA** and **nB** and dividing out:

sA = Dot(B-A, nB)/Dot(CPerp(nA), nB) sB = Dot(A-B, nA)/Dot(APerp(nB), nA) E = A + CPerp(nA)*sA E = B + APerp(nB)*sB # same value

The centre point **c** of the orange circle lies on the perpendicular bisector of **BD** at an unknown distance of **h** along this perpendicular where it interesects the angle bisector line from E (which is parallel to **nA+nB**).

sH = ((sA+sB)*0.5) c = E + CPerp(nB)*sH + nB*h solve: Dot(c - E, CPerp(nA + nB)) = 0 0 = Dot(CPerp(nB)*sH + nB*h, CPerp(nA) + CPerp(nB)) = Dot(nA, nB)*sH + h*Dot(nB, CPerp(nA)) + sH h = -(Dot(nB, nA)+1)*sH / Dot(nB, CPerp(nA))

This means we’re almost done as we know where the **c** lies. All that remains is to choose the point **C** on this circle.

Project a point from the chord betweenhBto the circle centred oncwith radiusrC. Let 0<lam<1 refer to a point position along this chord. rC = (CPerp(nA)*(s1-s0)/2 + nA*h).Len() = sqrt((s1-s0)**2/4 + h**2) sM = min(sA, sB) pC = E + (APerp(n0)*(1-lam) + CPerp(n1)*lam)*min(sA, sB) cpC = pC - c C = c + cpC*(rC/cpC.Len())

Now all that remains is to find the radii of the two arcs in the biarc.

Left hand arc has radius rA and centre cA: cA = A + nA*rA Distance to C should also be rA: rA = (cA - C).Len() = (A + nA*rA - C).Len() rA**2 = (A - C).Len()**2 + 2*Dot(A - C, nA)*nA + rA**2 rA = -(A - C).Len()**2 / (2*Dot(A - C, nA)) Similarly: rB = -(B - C).Len()**2 / (2*Dot(B - C, nB))

Basically, the entire operation is done with with a few dot products and around 2 square roots. No quadratic equations needed to be solved, so we’ve not had to mess around with choosing the right polynomial root or any guesswork which this entails.

This should be able to extend into a reliable arc fitting algorithm to a point sequence which I’ll get to at some point later.

## Leave a comment