# Bisectors the good old compass way

I am trying to reproduce the construction of bisectors with compass. Here is what I managed to get so far

vardef bisector(expr A, O, B, r) =
save arc, E, F, I;
path arc[] ; pair E, F, I[];

% Draw one arc of radius \r\ around center \O\ such that
% it cuts \OA\ and \OB\ respectively at points \E\ and \F\.
arc = fullcircle scaled r shifted O;
E      = (O--A) intersectiontimes arc;
F      = (O--B) intersectiontimes arc;

% With the same length \r\, draw two arcs respectively around
% centers \E\ and \F\ intersecting each other.
arc = fullcircle scaled r shifted point (ypart E) of arc;
arc = fullcircle scaled r shifted point (ypart F) of arc;

% That intersection point is \I\.
I = (reverse arc) intersectionpoint (reverse arc) ;
I = (reverse arc) intersectiontimes (reverse arc) ;
I = arc intersectiontimes arc ;

% Draw the arc around points \E\ and \F\ on rays \OA\ and \OB\.
draw subpath(ypart E - rad, ypart E + rad) of arc withcolor .8[black,white];
draw subpath(ypart F - rad, ypart F + rad) of arc withcolor .8[black,white];

% Draw arcs around point \I\.
draw subpath(ypart I - rad, ypart I + rad) of arc withcolor .5[black,white] ;
draw subpath(xpart I - rad, xpart I + rad) of arc withcolor .5[black,white] ;

I
enddef;


Which, when used in this piece of code

\startMPpage[offset=1dk]
u = cm ;
pair O, x, y, A, B, M[] ;

O = origin ;
x = (4u,2u) ;
y = (5u,-3u) ;

M = bisector(x,O,y,30) ;
M = bisector(O,x,y,30) ;
M = bisector(x,y,O,30) ;

draw O -- x -- y -- cycle ;
draw O -- y ;
draw O -- M shortened -u;
draw x -- M shortened -u;
draw y -- M shortened -u;

dotlabel.top("O", O) ;
dotlabel.top("x", x) ;
dotlabel.top("y", y) ;
\stopMPpage


produces And I do not understand why this is working in some cases but not in others… In fact, I am not even sure how it even works in the working cases.

What I am doing wrong?

• This is horrible style! I = (reverse arc) intersectionpoint (reverse arc) ; I = (reverse arc) intersectiontimes (reverse arc) ; It is almost deliberately obfusticated. May 27 at 16:38

Here's an alternative approach, that produces this version of your diagram. My source is wrapped up in luamplib so you need to compile it with lualatex, but I have only used plain MP macros, so you can easily adapt it for Context or plain MP.

\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}

boolean show_construction; show_construction = true;
numeric extra_angle; extra_angle = 16;

vardef bisection_point(expr a, o, b, r) =
% declare local variables
save arc, arc_a, arc_b;    path arc, arc_a, arc_b;
save point_a, point_b, m;  pair point_a, point_b, m;
% make the first arc scaled and centred at "o"
arc = fullcircle scaled 2r
rotated (angle (b-o) - extra_angle)
shifted o

% find the points where the arc crosses each line
point_a = arc intersectionpoint (o--a);
point_b = arc intersectionpoint (o--b);

% make the subsidiary arcs, scaled and centered at the points just found
arc_a = fullcircle scaled 2r rotated angle (a-o) shifted point_a;
arc_b = fullcircle scaled 2r rotated angle (b-o) shifted point_b;

% find the intersections of the arcs -- the rotations above and
% reversing arc_a here ensures we get the right intersection of arc_a and arc_b
m = reverse arc_a intersectionpoint arc_b;

% draw what we have done if required
if show_construction:
drawoptions(withpen pencircle scaled 1/4 withcolor 1/2);
draw arc;
save t; pair t; t = 1/45(-extra_angle, extra_angle);
draw subpath t of fullcircle scaled 2r rotated angle (m-point_a) shifted point_a;
draw subpath t of fullcircle scaled 2r rotated angle (m-point_b) shifted point_b;
drawoptions(withpen pencircle scaled 3/2 withcolor 1/2);
draw m; draw point_a; draw point_b;
drawoptions();
fi

% return the bisection point
m
enddef;

beginfig(1);

pair A, B, C;

A = (10, 5);
B = (200, 90);
C = (190, -80);

pair m; m = bisection_point(B, A, C, 30); draw A -- 4[A,m];
pair n; n = bisection_point(C, B, A, 30); draw B -- 4[B,n];
pair o; o = bisection_point(A, C, B, 30); draw C -- 4[C,o];

draw A--C--B--cycle;
dotlabel.lft("$A$", A);
dotlabel.urt("$B$", B);
dotlabel.lrt("$C$", C);

endfig;
\end{mplibcode}
\end{document}


If you set show_construction := false then you get this version: The important bit of the construction is to make sure that you rotate arc_a and arc_b correctly so that you always get the correct intersection. But this is not the most efficient or simplest way to get the bisection point in Metapost. This, for example, is rather quicker and much simpler:

vardef bisection_point(expr a, o, b, r) =
o + unitvector (a-o) scaled r
+ unitvector (b-o) scaled r
enddef;


although you don't get the pretty construction marks...

For more on this topic you might like to read sections 9.1 and 9.2 of my Drawing with Metapost document, now available on CTAN.

• I really like your work with Drawing with Metapost. May 30 at 3:11