tangent circles - blossommerz/locus-hub GitHub Wiki

Home > Tangent circles

< Previous: CLI commands | Next: Tick and strike >

CLI

Tangent circles

How to construct a circle that touches other objects, using the straightedge and compass commands rather than a command that hands you the answer.

[!IMPORTANT] Under construction. The CLI is being built, and this page describes work in progress. What it is called, what it can do, and how it behaves are all still moving. Nothing here is a promise about the finished feature.

Why there is no one command for it

Nothing takes a list of things and returns the circle that touches all of them. That is on purpose. A construction you can follow is a construction you can inspect, adjust and reuse: every point in it says where it came from, and moving a parent point moves the whole thing. A single command would hand you a circle with nothing behind it to look at.

Once you know the center, one command does finish the job: model circle-center-tangent puts a circle on a center and makes it touch a target. The part with no command is finding the center, and that is what the construction below is for.

The incircle of a triangle

The circle inside a triangle that touches all three sides. Its center is where the angle bisectors meet, and its radius is the distance from that center straight to a side.

1. The triangle

model point \
  --at 0,0 \
  --name "cornerA"

model point \
  --at 80,0 \
  --name "cornerB"

model point \
  --at 30,60 \
  --name "cornerC"

model segment \
  --from "cornerA" \
  --to "cornerB" \
  --name "sideAB"

model segment \
  --from "cornerB" \
  --to "cornerC" \
  --name "sideBC"

model segment \
  --from "cornerC" \
  --to "cornerA" \
  --name "sideCA"

2. Two bisectors, and where they cross

Two is enough. The third passes through the same point, which is the theorem this construction rests on, so drawing it only confirms what you already have.

model bisector-angle \
  --vertex "cornerA" \
  --arm1 "cornerB" \
  --arm2 "cornerC" \
  --name "biA"

model bisector-angle \
  --vertex "cornerB" \
  --arm1 "cornerC" \
  --arm2 "cornerA" \
  --name "biB"

model intersect \
  --a "biA" \
  --b "biB" \
  --near 34,21 \
  --name "incenter"

--near is a hint saying which crossing you meant. It only has to be nearer to the one you want than to any other, and the point it makes is exact.

3. Where the circle touches

The radius is the perpendicular distance from the center to a side, so drop a perpendicular onto one side and take the point where it lands.

model line-perpendicular \
  --base "sideAB" \
  --through "incenter" \
  --name "perpAB"

model intersect \
  --a "perpAB" \
  --b "sideAB" \
  --near 34,0 \
  --name "touchAB"

4. The circle

model circle-center-point \
  --center "incenter" \
  --through "touchAB" \
  --name "incircle"

That is the incircle. It touches all three sides, and it keeps touching them when you drag a corner, because every step above is still holding.

Clearing the scaffolding away

The bisectors and the perpendicular did their job and are now in the way. Put them in a group, then hide the group. Two steps, not one: a group is an arrangement, and hiding is a separate thing you do to it.

model group \
  --members "biA","biB","perpAB","touchAB" \
  --name "scaffold"

model hide \
  --targets "scaffold"

Nothing is thrown away. The circle still depends on all of it, so the construction keeps working, and showing the group again brings it all back when you want to see how the circle was arrived at.

Naming, so the example keeps working

The names above are deliberately longer than one letter. Placed points get automatic names from a counter that does not check what is already taken, so a hand-written name like A or C1 will eventually collide with one of them, and from then on every reference to that name is refused. Two letters or more avoids it.

Related

< Previous: CLI commands | Next: Tick and strike >