Open bgeorge77 opened 9 months ago
I guess the best way to go about this would be to make a new document in LaTeX and use the LaTeX package which is also on CTAN and it's not even necessary to download it. What paper format do you prefer "Byrnified Heath" to be in?
The big issue here I guess is that ConTeXT is broken still(?), and so I can't really do this on my own.
The ConTeXt version is indeed broken, after one of the recent updates many things stopped working at once. I almost completed a LaTeX version though, which is intended to be identical to the ConTeXt one, the only thing I can't get to work yet is initials, but I'll upload it soon regardless after I clean up the code a little bit, and they are not strictly necessary for anything anyway.
Wow--yeah this is exactly what I needed to get started! Will I be able to copy-paste the diagram code from the ConTeXT version, or is it different? Most importantly, does the new version support the little letters?
Yes, all the MetaPost syntax is the same (it's the same library) and the TeX macros are the same with some minor exceptions (e.g. there's no \drawCurrentPictureInMargin
, but you can implement it easily in LaTeX). Little letters are supported as well.
Hi Sergey, I'm working with Ben on this, and first of all, the byrne stuff you've done is amazing. I've been cranking through the Byrnification of props 1-10. A couple issues, though. 1) In Heath, Euclid refers to circles using 3 points, never using the center-radius standard (e.g. he says "circle BCD" instead of "circle AB" in prop 1). I'm wondering if you have any tips on how we could implement a way to make the text references in Heath correspond to the circle references (when we want to call in a picture of a circle from the drawing into the Heath text, for example). We could refer to them in the code using the center-radius method, then refer in the text using the other name, but having a similar name would make the work easier. 2) The labeling and/or relabeling of points is cumbersome, especially when redrawing the diagrams to look like Heath's. What is your rule of thumb in terms of using the various labeling function options (byLabelPoint or byLabelsOnPolygon...etc)?
@DBM-Applied Hi. That's great news! And thank you.
byCircleABC(...)
, it's pretty straightforward, you just feed it three points instead of two, to construct the circle. Here's the first proposition diagram with this function instead of byCircle
:
\defineNewPicture{
pair A, B, C, D, E;
path P[];
numeric r;
r := 3/2u;
A := (0, 0);
B := (r, 0);
P1 := fullcircle scaled 2r;
P2 := fullcircle scaled 2r shifted B;
C := P1 intersectionpoint P2;
D := A shifted (unitvector(A-B) scaled r); % defining points D and E relative to the other points
E := B shifted (unitvector(B-A) scaled r);
byLineDefine(A, B, byblack, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(B, C, byred, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(C, A, byyellow, SOLID_LINE, REGULAR_WIDTH);
draw byNamedLineSeq(-1)(AB,CA,BC);
draw byCircleABC(B, C, D, byblue, 0, 0, 1/2); % `byCircleABC` defines a circle by three points on its circumference
draw byCircleABC(A, C, E, byred, 0, 0, 1/2);
draw byLabelsOnPolygon(A, C, B)(ALL_LABELS, 1);
draw byLabelLineEnd(D, E, 1);
draw byLabelLineEnd(E, D, 1);
}
\drawCurrentPicture
Describe \drawCircle{BCD} with center \drawPoint{A} ... % and then you can reference the circle using the three points
![circleABC](https://github.com/user-attachments/assets/9db65de0-3444-4ff3-b950-12486d4857f0)
2. Labeling might indeed get cumbersome at times. Unfortunately, I didn't come up with a robust way to make it fully automatic.
I use `byLabelsOnPolygon` most of the time, because it allows to place many labels on the vertices of an [imaginary] polygon, and this placement works in a lot cases.
`byLabelPoint` I use when I need to label a specific point, and there's a very specific place next to this point where the label can go.
Also there's `byLabelLineEnd` which places a label at the end of a line segment, which is often useful as well. You can see it in the example above.
And there are some other functions for specific scenarios, which are mostly used internally by the lib.
The most up-to-date descriptions of all these things you can find in [`byrne-latex`](https://github.com/jemmybutton/byrne-latex) repo (simply compile byrne-latex.tex from there for the .pdf).
Sergey, thank you for the quick response! Redefining circles using byCircleABC function does seem like the best way to go.
Another question/request we have is the following: would it be possible to be able to automatically produce this style of text from a flag:
If such a flag does not exist (from what I can tell it doesn't) would you be up for doing this? Ben and I are not the Tex-wizard you are to be able to finagle it, or at least it would take MUCH longer for us.
To add to what Dan said, we would want this Reduced mode so that we could, with a flag, convert the text from the "Full Byrne" mode to something a little more subdued, for the longer proofs especially, when one might assume that the more classic Heath style would be too stark but that the Byrne style is too busy looking.
One major problem though is how to show a point in this reduced Byne way.
Thanks again for making all this work available to us, its just amazing what we're able to do so quickly.
Sure, it shouldn't be too difficult to implement. From what I see on the picture, for most of the things it can be done using some wrapper macros. Here's an example with the same construction as above:
\def\drawCircleAlt#1{\drawCircle{#1}\textbf{#1}} % these are the wrapper macros
\def\drawPointAlt#1{\drawPoint{#1}\textbf{#1}}
\defineNewPicture[1/6]{
pair A, B, C, D, E;
path P[];
numeric r;
r := 3/2u;
A := (0, 0);
B := (r, 0);
P1 := fullcircle scaled 2r;
P2 := fullcircle scaled 2r shifted B;
C := P1 intersectionpoint P2;
D := A shifted (unitvector(A-B) scaled r);
E := B shifted (unitvector(B-A) scaled r);
byLineDefine(A, B, byblack, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(B, C, byred, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(C, A, byyellow, SOLID_LINE, REGULAR_WIDTH);
draw byNamedLineSeq(-1)(AB,CA,BC);
draw byCircleABC(B, C,D, byblue, 0, 0, 1/2);
draw byCircleABC(A, C, E, byred, 0, 0, 1/2);
draw byLabelsOnPolygon(A, C, B)(ALL_LABELS, 1);
draw byLabelLineEnd(D, E, 1);
draw byLabelLineEnd(E, D, 1);
textLabels := false; %you need to turn off regular text labels, it will only affect pictures, derived from this construction
}
\drawCurrentPicture
Describe \drawCircleAlt{BCD} with center \drawPointAlt{A} ...
And for points specifically, there's alternative way to represent them, namely using byPointMark
. This allows to mark and reference points using small colored circles.
\def\drawCircleAlt#1{\drawCircle{#1}\textbf{#1}}
\def\drawPointAlt#1{\drawPointM{#1}\textbf{#1}}
\defineNewPicture[1/6]{
pair A, B, C, D, E;
path P[];
numeric r;
r := 3/2u;
A := (0, 0);
B := (r, 0);
P1 := fullcircle scaled 2r;
P2 := fullcircle scaled 2r shifted B;
C := P1 intersectionpoint P2;
D := A shifted (unitvector(A-B) scaled r);
E := B shifted (unitvector(B-A) scaled r);
byLineDefine(A, B, byblack, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(B, C, byred, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(C, A, byyellow, SOLID_LINE, REGULAR_WIDTH);
draw byNamedLineSeq(-1)(AB,CA,BC);
draw byCircleABC(B, C,D, byblue, 0, 0, 1/2);
draw byCircleABC(A, C, E, byred, 0, 0, 1/2);
draw byLabelsOnPolygon(A, C, B)(ALL_LABELS, 1);
draw byLabelLineEnd(D, E, 1);
draw byLabelLineEnd(E, D, 1);
draw byPointMark(A)(byblue,0);
draw byPointMark(B)(byyellow,0);
draw byPointMark(C)(byblack,0);
textLabels := false;
}
\drawCurrentPicture
Describe \drawCircleAlt{BCD} with center \drawPointAlt{A} ...
The line segments in your example require a different approach. At the moment, the closest thing is to make text labels big by default (which, I think, makes sense anyway), and to allow automatic labelling for line segments specifically:
\def\pointlabel#1{\textbf{#1}}
\def\drawCircleAlt#1{\drawCircle{#1}\textbf{#1}}
\def\drawPointAlt#1{\drawPointM{#1}\textbf{#1}}
\DeclareDocumentCommand{\drawUnitLineAlt}{o m}{% This is a little bit hacky, but not too difficult
\IfNoValueTF{#1}%
{\drawFromCurrentPicture[middle][uline#2]{
textLabels := true; %this turns on text labels for line segments specifically
startAutoLabeling;
draw byNamedCompoundLine(1cm, 0)(#2);
stopAutoLabeling;
textLabels := false; %this turns text labels off again
}}%
{\drawFromCurrentPicture[middle][uline#2#1]{
textLabels := true;
startAutoLabeling;
draw byNamedCompoundLine(#1, 0)(#2);
stopAutoLabeling;
textLabels := false;
}}%
}
\defineNewPicture[1/6]{
textLabelScaleFactor := 1;
pair A, B, C, D, E;
path P[];
numeric r;
r := 3/2u;
A := (0, 0);
B := (r, 0);
P1 := fullcircle scaled 2r;
P2 := fullcircle scaled 2r shifted B;
C := P1 intersectionpoint P2;
D := A shifted (unitvector(A-B) scaled r);
E := B shifted (unitvector(B-A) scaled r);
byLineDefine(A, B, byblack, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(B, C, byred, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(C, A, byyellow, SOLID_LINE, REGULAR_WIDTH);
draw byNamedLineSeq(-1)(AB,CA,BC);
draw byCircleABC(B, C,D, byblue, 0, 0, 1/2);
draw byCircleABC(A, C, E, byred, 0, 0, 1/2);
draw byLabelsOnPolygon(A, C, B)(ALL_LABELS, 1);
draw byLabelLineEnd(D, E, 1);
draw byLabelLineEnd(E, D, 1);
draw byPointMark(A)(byblue,0);
draw byPointMark(B)(byyellow,0);
draw byPointMark(C)(byblack,0);
textLabels := false;
}
\drawCurrentPicture
Describe \drawCircleAlt{BCD} with center \drawPointAlt{A}.
Draw \drawUnitLineAlt[0.5cm]{AB}... %you can use first optional argument to make the segments shorter
To make the segment labels appear on the bottom and take less space will require me to add some code to the lib. I'll think about the best way to do it, and come back with a solution.
I updated byrne-latex package, so here's how you can achieve the described result now:
\def\mpPre{
u:=1cm;
textLabels := true; % add these four lines to your \mpPre
compensateLineLabels := false; % this one removes vertical compensation for text labels for line segments
lineLabelsOnTop := false; % this one moves line segment labels to the bottom
textLabelScaleFactor := 1; % this one removes the default scaling for text labels
}
\def\mpPost{
textLabels := false; % and this line to your \mpPost
}
\newdimen\textLabelShift % This thing allows you to move labeled line segments up and down to make the labels appear like normal characters
\textLabelShift = -1.75pt % This value works for me, but might not work with a different typeface
\def\pointlabel#1{\textbf{#1}} % Here the style of text labels is redefined
\def\drawCircleAlt#1{\drawCircle{#1}\pointlabel{#1}} % These macros simply put text Labels as plain text
\def\drawPointAlt#1{\drawPointM{#1}\pointlabel{#1}}
\DeclareDocumentCommand{\drawUnitLineAlt}{o m}{% This is an alternative macro for inline line segments
\advance\pictOffsetBottom by \textLabelShift
\advance\pictOffsetTop by \textLabelShift
\IfNoValueTF{#1}%
{\drawFromCurrentPicture[top][uline#2]{
textLabels := true;
startAutoLabeling;
draw byNamedCompoundLine(1cm, 0)(#2);
stopAutoLabeling;
textLabels := false;
}}%
{\drawFromCurrentPicture[top][uline#2#1]{
textLabels := true;
startAutoLabeling;
draw byNamedCompoundLine(#1, 0)(#2);
stopAutoLabeling;
textLabels := false;
}}%
\advance\pictOffsetBottom by -\textLabelShift
\advance\pictOffsetTop by -\textLabelShift
}
\defineNewPicture[1/6]{ % here everything is the same as usual, [1/6] makes the inline pictures 1/6 of their original size, instead of the default 1/3
pair A, B, C, D, E;
path P[];
numeric r;
r := 3/2u;
A := (0, 0);
B := (r, 0);
P1 := fullcircle scaled 2r;
P2 := fullcircle scaled 2r shifted B;
C := P1 intersectionpoint P2;
D := A shifted (unitvector(A-B) scaled r);
E := B shifted (unitvector(B-A) scaled r);
byLineDefine(A, B, byblack, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(B, C, byred, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(C, A, byyellow, SOLID_LINE, REGULAR_WIDTH);
draw byNamedLineSeq(-1)(AB,CA,BC);
draw byCircleABC(B, C,D, byblue, 0, 0, 1/2);
draw byCircleABC(A, C, E, byred, 0, 0, 1/2);
draw byLabelsOnPolygon(A, C, B)(ALL_LABELS, 1);
draw byLabelLineEnd(D, E, 1);
draw byLabelLineEnd(E, D, 1);
draw byPointMark(A)(byblue,0);
draw byPointMark(B)(byyellow,0);
draw byPointMark(C)(byblack,0);
}
\drawCurrentPicture
Draw \drawUnitLineAlt[0.5cm]{BA}... % I changed label rendering a little bit, so that the labels are aligned inwards and don't take much space. Also [0.5cm] optional argument can be incorporated into \drawUnitLineAlt definition, if all these lines are intended to be shorter
Describe \drawCircleAlt{BCD} with center \drawPointAlt{A}.
we would want this Reduced mode so that we could, with a flag, convert the text from the "Full Byrne" mode to something a little more subdued, for the longer proofs especially, when one might assume that the more classic Heath style would be too stark but that the Byrne style is too busy looking.
Now, obviously, what I described above is a "global" solution, and it will affect the whole document. I'd like to avoid incorporating such a flag into the main library at the moment, because it affects both TeX and MetaPost parts of the workflow, and I need to come up with a nice and easy-to-support way to implement it. But I'm happy to help you write an extension for your particular use-case, so that it's convenient for you.
These are the options already available for showing points. I guess we could place a circle above the point, but doing so does not seem to be advantageous in any way as the point would not have color. The intersecting lines do aid the reader in locating the point referred to, but then this seems going overboard. I would go for doing nothing for points.
The flags "\drawLine{}" and "\drawCircle{}" are super helpful already. Sergey, I guess what we are looking for is a mod to these flags so that instead of being aligned with the text, the lines are placed above the line letters. I think all the other figures can be generated using the already existing flags (because we don't need to place the triangles and circles above the text, for example).
I guess we could place a circle above the point, but doing so does not seem to be advantageous in any way as the point would not have color.
It's possible to make colored circles for points you just need to add this to the diagram definition, like so: draw byPointMark(A)(byblue,0);
(see the example in the previous message), but I agree, it's not necessarily the best way to go.
so that instead of being aligned with the text, the lines are placed above the line letters Simply moving the image of the line segment above the line is even easier, here's an example:
\def\mpPre{ u:=1cm; textLabels := true; textLabelScaleFactor := 1; } \def\mpPost{ textLabels := false; }
\def\pointlabel#1{\textbf{#1}}
\def\drawCircleAlt#1{\drawCircle{#1}\pointlabel{#1}} \def\drawPointAlt#1{\drawPoint{#1}\pointlabel{#1}}
\def\drawUnitLineAlt#1{% This one simply places a 1/2cm picture of a line above its name \raisebox{0.5\baselineskip}{\drawUnitLine[0.5cm]{#1}}% \hskip-0.55cm\pointlabel{#1}% }
\defineNewPicture[1/6]{ pair A, B, C, D, E; path P[]; numeric r; r := 3/2u; A := (0, 0); B := (r, 0); P1 := fullcircle scaled 2r; P2 := fullcircle scaled 2r shifted B; C := P1 intersectionpoint P2; D := A shifted (unitvector(A-B) scaled r); E := B shifted (unitvector(B-A) scaled r); byLineDefine(D, A, byred, DASHED_LINE, REGULAR_WIDTH); byLineDefine(B, E, byblue, DASHED_LINE, REGULAR_WIDTH); byLineDefine(A, B, byblack, SOLID_LINE, REGULAR_WIDTH); byLineDefine(B, C, byred, SOLID_LINE, REGULAR_WIDTH); byLineDefine(C, A, byyellow, SOLID_LINE, REGULAR_WIDTH); draw byNamedLineSeq(-1)(CA,BC); draw byNamedLineSeq(0)(DA,AB,BE); draw byCircleABC(B, C,D, byblue, 0, 0, 1/2); draw byCircleABC(A, C, E, byred, 0, 0, 1/2); draw byLabelsOnPolygon(A, C, B)(ALL_LABELS, 1); draw byLabelLineEnd(D, E, 1); draw byLabelLineEnd(E, D, 1); } \drawCurrentPicture
Draw \drawUnitLineAlt{DE}...
Describe \drawCircleAlt{BCD} with center \drawPointAlt{A}.
![altLabels5](https://github.com/user-attachments/assets/b1978950-6aef-48f4-bf6d-725de253d652)
But it has a serious disadvantage over the solution I proposed in the previous message. Namely, the length of the line can be arbitrary, but you want it to fit over the line's name, e.g. DE. And if the line actually contains several different styles (like, several colors, and some parts of the line are dashed), there's just not enough horizontal space to make the line well-recognizable, as you can see on the provided example.
Could you provide an example of both the code and the output you'd like to see, and I'll try and write an extension that does this?
I added a slightly modified (I changed the drawCircleAlt code to draw a circle closer in size to the text) version of your last code: \def\pointlabel#1{\textbf{#1}}
\def\drawCircleAlt#1{\drawCircle[1][0.125]{#1}\pointlabel{#1}} % I changed the drawCircle code to draw a circle closer in size to the text% \def\drawPointAlt#1{\drawPoint{#1}\pointlabel{#1}}
\def\drawUnitLineAlt#1{% This one simply places a 1/2cm picture of a line above its name \raisebox{0.5\baselineskip}{\drawUnitLine[0.5cm]{#1}}% \hskip-0.55cm\pointlabel{#1}% }
into our local copy of byrne.sty, and I am able to generate something like what we are looking for using this .tex: \documentclass{ltxdoc} \usepackage{byrne} \usepackage{ccicons,bxtexlogo,listings,hyperref} \usepackage{tikz} \usepackage{comment}
\lstset{ language=MetaPost, alsolanguage=TeX, numbers=none, basicstyle=\ttfamily\scriptsize }
\begin{document}
\section{Proposition I.1:} \textit{On a given finite straight line to construct an equilateral triangle.} \vskip \baselineskip
\defineNewPicture{ % This code is modified version of Sergey's, using drawCircleABC
textLabels := true;
pair A, B, C, D, E;
path P[];
numeric r;
r := 3/2u;
A := (0, 0);
B := (r, 0);
P1 := fullcircle scaled 2r;
P2 := fullcircle scaled 2r shifted B;
C := P1 intersectionpoint P2;
D := A shifted (unitvector(A-B) scaled r); % defining points D and E relative to the other points
E := B shifted (unitvector(B-A) scaled r);
byLineDefine(A, B, byblack, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(B, C, byred, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(C, A, byyellow, SOLID_LINE, REGULAR_WIDTH);
draw byNamedLineSeq(-1)(AB,CA,BC);
draw byCircleABC(B, C, D, byblue, 0, 0, 1/2); % byCircleABC
defines a circle by three points on its circumference
draw byCircleABC(A, C, E, byred, 0, 0, 1/2);
draw byLabelsOnPolygon(A, C, B)(OMIT_FIRST_LABEL+OMIT_LAST_LABEL, 1);
draw byLabelsOnCircle(B, D)(BCD);
draw byLabelsOnCircle(A, E)(ACE);
textLabels := false;
}
~\hfill\drawCurrentPicture\hfill~
\vskip \baselineskip
Let \drawUnitLineAlt{AB} be the given finite straight line. Thus it is required to construct an equilateral triangle on the straight line \drawUnitLineAlt{AB}. With centre A and distance \drawUnitLineAlt{AB} let the circle \drawCircleAlt{BCD} be described; [Post. 3] again, with centre B and distance \drawUnitLineAlt{BA} let the circle \drawCircleAlt{ACE} be described; [Post. 3] and from the point C, in which the circles cut one another, to the points A, B let the straight lines \drawUnitLineAlt{CA}, \drawUnitLineAlt{CB} be joined. [Post. 1] Now, since the point A is the centre of the circle \drawCircleAlt{CDB}, \drawUnitLineAlt{AC} is equal to \drawUnitLineAlt{AB}. [Def. 15] Again, since the point B is the centre of the circle \drawCircleAlt{CAE}, \drawUnitLineAlt{BC} is equal to \drawUnitLineAlt{BA}. [Def. 15] But \drawUnitLineAlt{CA} was also proved equal to \drawUnitLineAlt{AB}; therefore each of the straight lines \drawUnitLineAlt{CA}, \drawUnitLineAlt{CB} is equal to \drawUnitLineAlt{AB}. And things which are equal to the same thing are also equal to one another; [C.N. 1] therefore CA is also equal to CB. Therefore the three straight lines CA, AB, BC are equal to one another. Therefore the triangle ABC is equilateral; and it has been constructed on the given finite straight line AB. (Being) what it was required to do.
\end{document}
The attached image is the output. Everything looks great except... 1) Line BA and the overline are on separate lines of text. 2) Heath (or Euclid probably) refers to what was earlier called "circle BCD" as "circle CDB", so the "\drawCircleAlt{CAE}" doesn't pull any drawing from the fig. 3) After this point (it seems) the text starts getting jumbled together. All-around, though, super helpful. Thank you.
So, I guess what we'd like different from this is:
First two are pretty straightforward, but the last one is somewhat tricky.
There's currently no separate entity for triangles. So the thing needs to check if something is a triangle, then make a decision on how to transform it into an equilateral (which side to use as the base, how to divide the sides, if they consist of several subsegments).
Also I have a feeling, that it won't work well for strongly non-equilateral triangles, or even triangles in different orientations, and it might get confusing in many instances, because the overall shape is also an important clue, which is being completely omitted in this scenario. E.g., if you have a triangle with its base on top in your diagram, its flipped representation in the text can take some time to parse, and understand which way it was rotated for the diagram.
What I would suggest right now, is to use some wrapper macro for triangles, and meanwhile I'll try to come up with a solution. My initial thoughts are to implement continuous transformations of polygons between their original shape and some more "regular" shape, optimized for small-size display.
Yes, I can see how changing all triangle to equlaterial triangles will be difficult and also potentially confusing. We'll have to put more thought into whether this is actually what we want.
I wrote a script to at least easily reference the triangles within the text. I don't know how to modify it so that I can simply call \drawTriangleAlt{ABC} instead of \drawTriangleAlt{A}{B}{C}...
% Attempt at facilitating Triangle call (not morphed into equilateral triangle) \def\drawTriangleAlt#1#2#3{% \edef\tempA{#1#2}% define AB, \edef\tempB{#2#3}% BC \edef\tempC{#1#3}% and AC \edef\tempABC{triangle#1#2#3}% define triangleABC \drawFromCurrentPicture[1][\tempABC]{% draw the triangleABC from the input {A}{B}{C} draw byNamedLineSeq(0)(\tempA, \tempB, \tempC);% }% }
I used this command in a version of prop 5 to call the triangles into the text: \documentclass{ltxdoc} \usepackage{byrne} \usepackage{ccicons,bxtexlogo,listings,hyperref} \usepackage{tikz} \usepackage{comment}
\lstset{ language=MetaPost, alsolanguage=TeX, numbers=none, basicstyle=\ttfamily\scriptsize }
\begin{document}
\section{Proposition I.5:} \textit{In isosceles triangles the angles at the base are equal to one another, and, if the equal straight lines be produced further, the angles under the base will be equal to one another.}
\vskip 0.5\baselineskip \defineNewPicture{ textLabels := true; angleSize := 1cm; pair A, B, C, D, E, F, G; A := (0, 0); B := A shifted (-u, -2u); C := B xscaled -1; D := 15/8[A,B]; E := 15/8[A,C]; F := 3/2[A,B]; G := 3/2[A,C]; byAngleDefine(B, A, C, byblack, SOLID_SECTOR); byAngleDefine(A, B, C, byblue, SOLID_SECTOR); byAngleDefine(B, C, A, byblue, SOLID_SECTOR); byAngleDefine(C, B, G, byyellow, SOLID_SECTOR); byAngleDefine(B, C, F, byyellow, SOLID_SECTOR); byAngleDefine(B, G, C, byred, SOLID_SECTOR); byAngleDefine(C, F, B, byred, SOLID_SECTOR); byAngleDefine(C, B, F, byblack, ARC_SECTOR); byAngleDefine(B, C, G, byblack, ARC_SECTOR); draw byNamedAngleResized(BAC,ABC,BCA,CBG,BCF,BGC,CFB,CBF,CBF,BCG); byLineDefine(B, F, byyellow, SOLID_LINE, REGULAR_WIDTH); byLineDefine(C, G, byyellow, SOLID_LINE, REGULAR_WIDTH); byLineDefine(B, G, byblue, SOLID_LINE, REGULAR_WIDTH); byLineDefine(C, F, byblue, SOLID_LINE, REGULAR_WIDTH); byLineDefine(A, B, byred, SOLID_LINE, REGULAR_WIDTH); byLineDefine(A, C, byred, SOLID_LINE, REGULAR_WIDTH); byLineDefine(B, C, byblack, SOLID_LINE, REGULAR_WIDTH); byLineDefine(F, D, byblack, SOLID_LINE, REGULAR_WIDTH); byLineDefine(G, E, byblack, SOLID_LINE, REGULAR_WIDTH); draw byNamedLineSeq(0)(FD,GE,BG,CF,BF,CG,AC,AB,BC); label.top(btex A etex, A); label.rt(btex C etex, C); label.lft(btex B etex, B); label.rt(btex E etex, E); label.lft(btex D etex, D); label.lft(btex F etex, F); label.rt(btex G etex, G); textLabels := false; } ~\hfill\drawCurrentPicture\hfill~ \vskip \baselineskip
Let \drawTriangleAlt{A}{B}{C} ABC be an isosceles triangle having the side \drawUnitLineAlt{AB} equal to the side \drawUnitLineAlt{AC}; and let the straight lines \drawUnitLineAlt{BD}, \drawUnitLineAlt{CE} be produced further in a straight line with \drawUnitLineAlt{AB}, \drawUnitLineAlt{AC}. [Post. 2] I say that the angle \drawAngleAlt{ABC} is equal to the angle \drawAngleAlt{ACB}, and the angle CBD to the angle BCE. Let a point F be taken at random on BD; from AE the greater let AG be cut off equal to AF the less; [I. 3] and let the straight lines FC, GB be joined. [Post. 1] Then, since AF is equal to AG and AB to AC, the two sides FA, AC are equal to the two sides GA, AB, respectively; and they contain a common angle, the angle FAG. Therefore the base FC is equal to the base GB, and the triangle \drawTriangleAlt{A}{F}{C}AFC is equal to the triangle \drawTriangleAlt{A}{G}{B}AGB, and the remaining angles will be equal to the remaining angles respectively, namely those which the equal sides subtend, that is, the angle ACF to the angle ABG, and the angle AFC to the angle AGB. [I. 4] And, since the whole AF is equal to the whole AG, and in these AB is equal to AC, the remainder BF is equal to the remainder CG. But FC was also proved equal to GB; therefore the two sides BF, FC are equal to the two sides CG, GB respectively; and the angle BFC is equal to the angle CGB, while the base BC is common to them; therefore the triangle \drawTriangleAlt{B}{F}{C}BFC is also equal to the triangle \drawTriangleAlt{C}{G}{B}CGB, and the remaining angles will be equal to the remaining angles respectively, namely those which the equal sides subtend; therefore the angle FBC is equal to the angle GCB, and the angle BCF to the angle CBG. Accordingly, since the whole angle ABG was proved equal to the angle ACF, and in these the angle CBG is equal to the angle BCF, the remaining angle ABC is equal to the remaining angle ACB; and they are at the base of the triangle ABC. But the angle FBC was also proved equal to the angle GCB; and they are under the base. Therefore etc.
Q. E. D.
\end{document}
Here is the result:
Got it. First, I realized, that I have some obvious functionality missing from byrne.mp
, namely, that you can't construct polygons by referencing vertices, instead of edges, and it turned out quite easy to implement. So in the new version there's byNamedLineSeqByPoints
for MetaPost and \drawLineByPoints
for LaTeX. They take a list of points instead of a list of line segments, like so: \drawLineByPoints{F,A,C}
. With this, it's pretty straightforward to implement what you've made with triangles, but with a bit more concise syntax (commas, instead of a lot of curly braces).
\drawTriangleAlt{ABC}
syntax would be even better, but it's a little bit tricky to implement. The thing is, point names can be arbitrary strings of characters, and breaking a large string apart to find point names, without even knowing in advance how many points there are (naturally, I want this thing to work for arbitrary polygons, not just trinagles) can be slow and might result in ambiguities.
For your special case, if you only intend to use single-letter point names (i.e. no A'
, A''
&c) it's easy to write a piece of Lua code (similar to the one I added below to remove commas and spaces) which will just add commas in between the letters.
\documentclass{ltxdoc}
\usepackage{byrne}
\usepackage{ccicons,bxtexlogo,listings,hyperref}
\usepackage{tikz}
\usepackage{comment}
%
% Put the following section into a separate file, like preambe.tex
%
\directlua{
function cleanPolygonName(s)
local resultingName = s:gsub ("[, ]","")
resultingName = resultingName:gsub ("-","minus")
tex.print(resultingName)
end
}
\def\mpPre{
u:=1cm;
textLabels := true;
textLabelScaleFactor := 1;
angleSize := 1cm;
compensateLineLabels := false; % this one removes vertical compensation for text labels for line segments
lineLabelsOnTop := false; % this one moves line segment labels to the bottom
}
\def\mpPost{
textLabels := false;
}
\def\pointlabel#1{\textbf{#1}} % This one determines the style of text labels both on the main diagram and in the text
\newdimen\textLabelShift % This thing allows you to move labeled line segments up and down to make the labels appear like normal characters
\textLabelShift = -1.75pt % This value works for me, but might not work with a different typeface
\DeclareDocumentCommand{\drawUnitLineAlt}{o m}{% This is an alternative macro for inline line segments
\advance\pictOffsetBottom by \textLabelShift
\advance\pictOffsetTop by \textLabelShift
\IfNoValueTF{#1}%
{\drawFromCurrentPicture[top][uline#2]{
textLabels := true;
startAutoLabeling;
draw byNamedCompoundLine(0.6cm, 0)(#2);
stopAutoLabeling;
textLabels := false;
}}%
{\drawFromCurrentPicture[top][uline#2#1]{
textLabels := true;
startAutoLabeling;
draw byNamedCompoundLine(#1, 0)(#2);
stopAutoLabeling;
textLabels := false;
}}%
\advance\pictOffsetBottom by -\textLabelShift
\advance\pictOffsetTop by -\textLabelShift
}
\def\drawCircleAlt#1{\drawCircle{#1}\pointlabel{#1}}
\def\drawPointAlt#1{\drawPointM{#1}\pointlabel{#1}}
\def\drawAngleAlt#1{\drawAngle{#1}\pointlabel{#1}}
\def\drawLineAlt#1{\drawLineByPoints{#1}\pointlabel{\directlua{cleanPolygonName("#1")}}}
%
% End of preamble.tex
%
\lstset{
language=MetaPost,
alsolanguage=TeX,
numbers=none,
basicstyle=\ttfamily\scriptsize
}
\begin{document}
\section{Proposition I.5:}
\textit{In isosceles triangles the angles at the base are equal to one another, and, if the equal straight lines be produced further, the angles under the base will be equal to one another.}
\vskip 0.5\baselineskip
\defineNewPicture{
pair A, B, C, D, E, F, G;
A := (0, 0);
B := A shifted (-1cm, -2cm);
C := B xscaled -1;
D := 15/8[A,B];
E := 15/8[A,C];
F := 3/2[A,B];
G := 3/2[A,C];
byAngleDefine(B, A, C, byblack, SOLID_SECTOR);
byAngleDefine(A, B, C, byblue, SOLID_SECTOR);
byAngleDefine(B, C, A, byblue, SOLID_SECTOR);
byAngleDefine(C, B, G, byyellow, SOLID_SECTOR);
byAngleDefine(B, C, F, byyellow, SOLID_SECTOR);
byAngleDefine(B, G, C, byred, SOLID_SECTOR);
byAngleDefine(C, F, B, byred, SOLID_SECTOR);
byAngleDefine(C, B, F, byblack, ARC_SECTOR);
byAngleDefine(B, C, G, byblack, ARC_SECTOR);
draw byNamedAngleResized(); % you don't need to list the angles, if you want all to be drawn
byLineDefine(B, F, byyellow, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(C, G, byyellow, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(B, G, byblue, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(C, F, byblue, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(A, B, byred, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(A, C, byred, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(B, C, byblack, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(F, D, byblack, SOLID_LINE, REGULAR_WIDTH);
byLineDefine(G, E, byblack, SOLID_LINE, REGULAR_WIDTH);
draw byNamedLineSeq(0)(FD,GE,BG,CF,BF,CG,AC,AB,BC);
draw byLabelsOnPolygon(A, C, G, E, D, F, B)(0, 0); % I changed to byrne.mp labels to make text styles consistent and the code more concise
}
~\hfill\drawCurrentPicture\hfill~
\vskip \baselineskip
Let \drawLineAlt{A,B,C} be an isosceles triangle having the side \drawUnitLineAlt{AB} equal to the side \drawUnitLineAlt{AC}; and let the straight lines \drawUnitLineAlt{BD}, \drawUnitLineAlt{CE} be produced further in a straight line with \drawUnitLineAlt{AB}, \drawUnitLineAlt{AC}. [Post. 2] I say that the angle \drawAngleAlt{ABC} is equal to the angle \drawAngleAlt{ACB}, and the angle CBD to the angle BCE. Let a point F be taken at random on BD; from AE the greater let AG be cut off equal to AF the less; [I. 3] and let the straight lines FC, GB be joined. [Post. 1] Then, since AF is equal to AG and AB to AC, the two sides FA, AC are equal to the two sides GA, AB, respectively; and they contain a common angle, the angle FAG. Therefore the base FC is equal to the base GB, and the triangle \drawLineAlt{A,F,C} is equal to the triangle \drawLineAlt{A,G,B}, and the remaining angles will be equal to the remaining angles respectively, namely those which the equal sides subtend, that is, the angle ACF to the angle ABG, and the angle AFC to the angle AGB. [I. 4] And, since the whole AF is equal to the whole AG, and in these AB is equal to AC, the remainder BF is equal to the remainder CG. But FC was also proved equal to GB; therefore the two sides BF, FC are equal to the two sides CG, GB respectively; and the angle BFC is equal to the angle CGB, while the base BC is common to them; therefore the triangle \drawLineAlt{B,F,C} is also equal to the triangle \drawLineAlt{C,G,B}, and the remaining angles will be equal to the remaining angles respectively, namely those which the equal sides subtend; therefore the angle FBC is equal to the angle GCB, and the angle BCF to the angle CBG. Accordingly, since the whole angle ABG was proved equal to the angle ACF, and in these the angle CBG is equal to the angle BCF, the remaining angle ABC is equal to the remaining angle ACB; and they are at the base of the triangle ABC. But the angle FBC was also proved equal to the angle GCB; and they are under the base. Therefore etc.
Q. E. D.
\end{document}
There's a slight bug with line segment labels, I'll fix it tomorrow.
Sergey, the "\drawLineByPoints" command is super useful. And I see your point about trying to have the input be a triangle name, without delimiters separating the points (like ABC).
I saved the preamble of your prop5 as a "preamble.tex" file, and now just load it with "\input{preamble.tex} after the .tex header stuff.
We're battling with what is probably a super-simple fix, but given the length of .sty and .mp files, its hard to identify how to fix it. We want to be able to control the font style and size of the labels on the diagram and match it to the text. We really like the font style you have in the byrn-latex.tex file, though the labels are a bit small.
We want to be able to control the font style and size of the labels on the diagram and match it to the text.
There are two places where the look of the labels is determined, first, it's a simple definition of \pointlabel
, and can be used both in the main text and in the labels, in byrne-latex
it looks like this:
\def\pointlabel#1{\textsf{#1}}
in the example above I redefined it to be
\def\pointlabel#1{\\textbf{#1}}
but you can change it to anything you like.
Second is textLabelScaleFactor
, which is set in MetaPost. It's simply a scale factor for text lables, because it's a bit easier to control than TeX's font sizes. By default it's:
textLabelScaleFactor := 2/5;
in the example above I changed its value in \mpPre
:
textLabelScaleFactor := 1;
so that the labels are exactly the same as the main text
Got it - adjusting the text font and size seems pretty straightforward. Thanks!
I forgot to mention this in a previous message, but the drawCircleAlt could also be improved.
Would it be feasible to modify the command \drawCircleAlt#1 so that it iterates through different permutations of the three letters in #1 until it identifies a valid drawing. See in my last message with a picture Alternatively, we could implement a fix like drawing (or naming) each permutation of the circle in the original drawing.
For example, in prop 1, circle BCD is later referenced as circle CDB by Euclid, but the \drawCircleAlt command doesn't recognize the name "CDB".
Let \drawUnitLineAlt{AB} be the given finite straight line. Thus it is required to construct an equilateral triangle on the straight line \drawUnitLineAlt{AB}. With centre A and distance \drawUnitLineAlt{AB} let the circle \drawCircleAlt{BCD} be described; [\textit{Post. 3}] again, with centre B and distance \drawUnitLineAlt{BA} let the circle \drawCircleAlt{ACE} be described; [\textit{Post. 3}] and from the point C, in which the circles cut one another, to the points A, B let the straight lines \drawUnitLineAlt{CA}, \drawUnitLineAlt{CB} be joined. [\textit{Post. 1}] Now, since the point A is the centre of the circle \drawCircleAlt{CDB},
I suppose another option would be to define a new command like \byCircleABCAlt which not draws three circles, one for each permutation of the points defined -- perhaps this would be best because the points are given as a list for this function, so this would work even if the points were longer than one character, e.g. {A', B', C'}.
I didn't use three-point circles a lot, and didn't make a routine to generate synonyms for them. Now it's implemented, and any way you reference them should work.
Beautiful - so good, man.
Hey Sergey, I've been making a lot of progress with the Byrnified Heath diagrams. Thanks for the help! I have a couple questions:
First Question: What is the difference between defining and then drawing (e.g. "byLineDefine(A, F, byred, DASHED_LINE, REGULAR_WIDTH)" and then later "\draw byNamedLineSeq{AF}") vs using the command that defines and draws in one line (e.g "draw byLine(A, F, byred, DASHED_LINE, REGULAR_WIDTH)" )?
See for example in prop 34 where both commands are used (but for different lines obviously):
\starttheorem{Prop XXXIV. Theor.}\label{prop:I.XXXIV} \defineNewPicture{ pair A, B, C, D, d[]; d1 := (5/2u, 0); d2 := (-7/8u, -3u); A := (0, 0); B := A shifted d1; C := A shifted d2; D := C shifted d1; byAngleDefine(B, A, D, byblue, SOLID_SECTOR); byAngleDefine(D, A, C, byred, SOLID_SECTOR); byAngleDefine(C, D, A, byyellow, SOLID_SECTOR); byAngleDefine(A, D, B, byred, SOLID_SECTOR); byAngleDefine(A, C, D, byblack, SOLID_SECTOR); byAngleDefine(D, B, A, byblack, SOLID_SECTOR); draw byNamedAngleResized(); draw byLine(A, D, byblack, SOLID_LINE, REGULAR_WIDTH); byLineDefine(A, B, byred, SOLID_LINE, REGULAR_WIDTH); byLineDefine(C, D, byred, DASHED_LINE, REGULAR_WIDTH); byLineDefine(A, C, byyellow, SOLID_LINE, REGULAR_WIDTH); byLineDefine(B, D, byblue, SOLID_LINE, REGULAR_WIDTH); draw byNamedLineSeq(0)(AB,BD,CD,AC); draw byLabelsOnPolygon(A, B, D, C)(ALL_LABELS, 0); } \drawCurrentPictureInMargin \problem{T}{he}{opposite sides and angles of any parallelogram are equal, and the diagonal (\drawUnitLine{AD}) divides it into two equal parts.}
Second Question: Could you write another command for our special preamble.tex doc that will draw in-line images of colored triangles, then put the name of the triangle after it?
Third Question: I discovered the command "byPointLabelDefine(A, "F");", for relabeling points in the diagrams (e.g. changing the "A" to "F" for the Heath-style figure). This won't work, however, because we'll need to use the original point names as references in the text itself.
What is the difference between defining and then drawing (e.g. "byLineDefine(A, F, byred, DASHED_LINE, REGULAR_WIDTH)" and then later "\draw byNamedLineSeq{AF}") vs using the command that defines and draws in one line (e.g "draw byLine(A, F, byred, DASHED_LINE, REGULAR_WIDTH)" )?
If you only want one line, there's no difference, but byNamedLineSeq
can draw several lines, which, instead of having several disjoint lines with square ends, are connected with nice joints like this:
So for stand-alone lines it makes sense to just use draw byLine...
, but when you want the lines to be connected to form a figure, you use byLineDefine...
/draw byNamesLineSeq...
.
Got it. Thanks!
Sergey, Currently this is our preamble.tex, containing a bunch of useful tailored commands: `\directlua{ function cleanPolygonName(s) local resultingName = s:gsub ("[, ]","") resultingName = resultingName:gsub ("-","minus") tex.print(resultingName) end }
\def\mpPre{textLabels := true;} \def\mpPre{ u:=1cm; textLabels := true; textLabelScaleFactor := 1; angleSize := 1cm; compensateLineLabels := false; % this one removes vertical compensation for text labels for line segments lineLabelsOnTop := false; % this one moves line segment labels to the bottom }
\def\mpPost{ textLabels := false; }
\def\pointlabel#1{\textsf{\textbf{#1}}} % This one determines the style of text labels both on the main diagram and in the text
\newdimen\textLabelShift % This thing allows you to move labeled line segments up and down to make the labels appear like normal characters
\textLabelShift = -1.75pt % This value works for me, but might not work with a different typeface
\DeclareDocumentCommand{\drawUnitLineAlt}{o m}{% This is an alternative macro for inline line segments \advance\pictOffsetBottom by \textLabelShift \advance\pictOffsetTop by \textLabelShift \IfNoValueTF{#1}% {\drawFromCurrentPicture[top][uline#2]{ textLabels := true; startAutoLabeling; draw byNamedCompoundLine(0.45cm, 0)(#2); % Sergey had this set to 0.6cm; DBM changed to 0.45cm stopAutoLabeling; textLabels := false; }}% {\drawFromCurrentPicture[top][uline#2#1]{ textLabels := true; startAutoLabeling; draw byNamedCompoundLine(#1, 0)(#2); stopAutoLabeling; textLabels := false; }}% \advance\pictOffsetBottom by -\textLabelShift \advance\pictOffsetTop by -\textLabelShift }
\def\drawCircleAlt#1{\drawCircle{#1}\pointlabel{#1}} \def\drawPointAlt#1{\drawPointM{#1}\pointlabel{#1}} \def\drawAngleAlt#1{\drawAngle{#1}\pointlabel{#1}} \def\drawLineAlt#1{\drawLineByPoints{#1}\pointlabel{\directlua{cleanPolygonName("#1")}}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Added by DBM \renewcommand{\familydefault}{\sfdefault}`
The "drawLineAlt" command employs "drawLineByPoints". I'm wondering if there is a similar command for angles ("drawAngleByPoints") so that angles can be referenced by different names. In prop 5, for example, Euclid (Heath Text) references angle BCE by GCB later on. It would be nice to be able to get the angle to render even if it is defined using different points (or at least in a different order).
Followup questions from a previous post:
Second Question: Could you write another command for our special preamble.tex doc that will draw in-line images of colored triangles, then put the name of the triangle after it?
Third Question: I discovered the command "byPointLabelDefine(A, "F");", for relabeling points in the diagrams (e.g. changing the "A" to "F" for the Heath-style figure). This won't work, however, because we'll need to use the original point names as references in the text itself.
Is there any way to make it possible to use such a simple command and have the in-line references still work? Would it be possible to reference a line or shape by its labeled points instead of by its actually variable point names? I ask only because using this byPointLabelDefine makes relabelling points so much easier!
I'm wondering if there is a similar command for angles ("drawAngleByPoints") so that angles can be referenced by different names. In prop 5, for example, Euclid (Heath Text) references angle BCE by GCB later on. It would be nice to be able to get the angle to render even if it is defined using different points (or at least in a different order).
Currently the algorithm works in such a way that it only accepts clockwise angles if they are simple (i.e. defined as a single angle), but for compound angles only counter-clockwise naming works, to avoid ambiguity (even now ambiguity is technically possible though). As long as your angle is counter-clockwise, you should be able to use any points on angle's sides to reference it.
I'm not sure how to implement angles >π without additional arguments, but what is easy to implement in your case, is to simply add an additional argument to drawAngleAlt
, so that you can override the name you referenced the angle by, by anything else, like so drawAngleAlt[GCB]{BCE}
:
\DeclareDocumentCommand{\drawAngleAlt}{o m}{%
\drawAngle{#2}%
\IfNoValueTF{#1}%
{\pointlabel{#2}}%
{\pointlabel{#1}}%
}%
In the future I will try and do it in such a way that if there's no possible counter-clockwise angle it will look for a clockwise one, but that's a potential source of confusing errors (e. g., you add an angle, and everything crashes, or, worse, angles in the text are quietly redrawn to counter-clockwise ones, and you you are not even notified), so I need to think about it.
Could you write another command for our special preamble.tex doc that will draw in-line images of colored triangles, then put the name of the triangle after it?
Triangles don't exist as a separate entity, they are either line sequences (i.e. \drawLineAlt
) or polygons. What would you like this command to look like?
I discovered the command "byPointLabelDefine(A, "F");", for relabeling points in the diagrams (e.g. changing the "A" to "F" for the Heath-style figure). This won't work, however, because we'll need to use the original point names as references in the text itself. Is there any way to make it possible to use such a simple command and have the in-line references still work?
This command only affects text labels, but not variable names. Moreover, it only affects labels produced in MetaPost, but in "alt" commands labels are produced in TeX, and are not affected, therefore, variable names are still printed as is. Technically, it's not too difficult to modify "alt" commands to respect changes made with byPointLabelDefine
(probably it would take drawing text labels in MetaPost instead of TeX). If you need it, I can do it this week.
Would it be possible to reference a line or shape by its labeled points instead of by its actually variable point names? I'm not sure how to make this work in general. What if you relabel, say, point
A
to be calledB
and vice versa? This can get very confusing. Also, this seems to be a tad too difficult to implement.
In general, I'd advise against relabeling things unless absolutely necessary, and rename variables instead. Yes, it takes more time, but it's so much easier to work when the names are the same in text and in diagram code.
Could you write another command for our special preamble.tex doc that will draw in-line images of colored triangles, then put the name of the triangle after it?
Triangles don't exist as a separate entity, they are either line sequences (i.e. \drawLineAlt) or polygons. What would you like this command to look like?
OK - I see now. I was able to make a function modeled after the other functions (\byPolygonAlt)
\def\drawPolygonAlt#1{\drawPolygon{#1}\pointlabel{#1}}
I discovered the command "byPointLabelDefine(A, "F");", for relabeling points in the diagrams (e.g. changing the "A" to "F" for the Heath-style figure). This won't work, however, because we'll need to use the original point names as references in the text itself. Is there any way to make it possible to use such a simple command and have the in-line references still work?
This command only affects text labels, but not variable names. Moreover, it only affects labels produced in MetaPost, but in "alt" commands labels are produced in TeX, and are not affected, therefore, variable names are still printed as is. Technically, it's not too difficult to modify "alt" commands to respect changes made with byPointLabelDefine (probably it would take drawing text labels in MetaPost instead of TeX). If you need it, I can do it this week.
Would it be possible to reference a line or shape by its labeled points instead of by its actually variable point names? I'm not sure how to make this work in general. What if you relabel, say, point A to be called B and vice versa? This can get very confusing. Also, this seems to be a tad too difficult to implement.
In general, I'd advise against relabeling things unless absolutely necessary, and rename variables instead. Yes, it takes more time, but it's so much easier to work when the names are the same in text and in diagram code.
The relabeling of points just makes things way easier - it's possible to change the variables to different names throughout the entire drawing code, it just takes a lot longer.
If it's possible to make a function that will refer to relabeled points, that would be great.
Currently the algorithm works in such a way that it only accepts clockwise angles if they are simple (i.e. defined as a single angle), but for compound angles only counter-clockwise naming works, to avoid ambiguity (even now ambiguity is technically possible though). As long as your angle is counter-clockwise, you should be able to use any points on angle's sides to reference it.
What do you mean by clockwise and counterclockwise angles? In the image below, would "byAngleDefine(A,B,C...)" be a counterclockwise definition, whereas "byAngleDefine(C,B,A...)" would be the clockwise definition of the same angle? Or is it the other way around? I'm thinking it's either viewing the vertex (A) as the pivot point around which clockwise and counterclockwise are defined OR it is simply defined based on either a clockwise or counterclockwise trajectory of the points (in this case I got it backwards).
Also, I think there is a typo in line 166 of "byrne-latex.tex" file in https://github.com/jemmybutton/byrne-latex. It says "...the angle in the example can be called \texttt{A}, \texttt{BAC} or \texttt{ABC} interchangeably..." Shouldn't it be "...the angle in the example can be called \texttt{A}, \texttt{BAC} or \texttt{CAB} interchangeably..."?
If it's possible to make a function that will refer to relabeled points, that would be great.
I doubt I can make a function to refer to relabeled points (that is, to do something like \drawAngle{CAB}
to work instead of \drawAngle{ABC}
after the point A
is relabeled to C
, B
to A
and C
to B
). But I'll try and make a function which would display changed labels in text (e.g. if the point A
is relabeled to C
, B
to A
and C
to B
, \drawAngle{ABC}
will produce an image of the angle with CAB
next to it, instead of ABC
).
What do you mean by clockwise and counterclockwise angles? In the image below, would "byAngleDefine(A,B,C...)" be a counterclockwise definition, whereas "byAngleDefine(C,B,A...)" would be the clockwise definition of the same angle?
Imagine an arrow pointing from the second point (B
) to the first point (A
in the first example or C
in the second). If the arrow has to move clockwise to go over the angle, then the angle is clockwise. I. e. ABC
is counterclockwise and CBA
is clockwise. The direction doesn't matter most of the time, but is you need to reference a compound angle (i. e. defined as several parts), then it has to be counterclockwise.
Also, I think there is a typo in line 166 of "byrne-latex.tex" file in https://github.com/jemmybutton/byrne-latex. It says "...the angle in the example can be called \texttt{A}, \texttt{BAC} or \texttt{ABC} interchangeably..." Shouldn't it be "...the angle in the example can be called \texttt{A}, \texttt{BAC} or \texttt{CAB} interchangeably..."?
Good catch! Fixed.
OK. I think I'm starting to wrap my head around it. So, we will need to reference angles by the variables used in the coding of the diagram (not by relabeled points).
We're trying to streamline the process of adding the inline alt code to the Heath text. So, for example, we're just flagging the text with things like "\angleCBD" which would later be replaced by "\drawAngleAlt{CBD}". Using the \drawAngleAlt[CBD]{DBC} syntax becomes very cumbersome, so we are trying to think of a way around it. The challenge enters when the angle (e.g. CBD) is a compound angle and the way it's referenced in the Heath text is a "clockwise" angle direction.
If this is possible:
In the future I will try and do it in such a way that if there's no possible counter-clockwise angle it will look for a clockwise one, but that's a potential source of confusing errors (e. g., you add an angle, and everything crashes, or, worse, angles in the text are quietly redrawn to counter-clockwise ones, and you you are not even notified), so I need to think about it. That would be a huge help.
`\documentclass{ltxdoc} \usepackage{byrne} \usepackage{ccicons,bxtexlogo,listings,hyperref} \usepackage{tikz} \usepackage{comment}
\input{preamble.tex}
\begin{document}
\section{Proposition I.5:} \textit{In isosceles triangles the angles at the base are equal to one another, and, if the equal straight lines be produced further, the angles under the base will be equal to one another.}
\vskip 0.5\baselineskip \defineNewPicture[1/3][1]{ textLabels := true; angleSize := 1cm; pair A, B, C, D, E, F, G; A := (0, 0); B := A shifted (-u, -2u); C := B xscaled -1; D := 15/8[A,B]; E := 15/8[A,C]; F := 3/2[A,B]; G := 3/2[A,C]; byAngleDefine(B, A, C, byblack, SOLID_SECTOR); byAngleDefine(A, B, C, byblue, SOLID_SECTOR); byAngleDefine(B, C, A, byblue, SOLID_SECTOR); byAngleDefine(C, B, G, byyellow, SOLID_SECTOR); byAngleDefine(B, C, F, byyellow, SOLID_SECTOR); byAngleDefine(B, G, C, byred, SOLID_SECTOR); byAngleDefine(C, F, B, byred, SOLID_SECTOR); byAngleDefine(G, B, D, byblack, ARC_SECTOR); % needs to be re-defined as GBD so that compound angle renders in the text when angle CBD is referenced byAngleDefine(F, C, E, byblack, ARC_SECTOR); draw byNamedAngleResized(); byLineDefine(B, F, byyellow, SOLID_LINE, REGULAR_WIDTH); byLineDefine(C, G, byyellow, SOLID_LINE, REGULAR_WIDTH); byLineDefine(B, G, byblue, SOLID_LINE, REGULAR_WIDTH); byLineDefine(C, F, byblue, SOLID_LINE, REGULAR_WIDTH); byLineDefine(A, B, byred, SOLID_LINE, REGULAR_WIDTH); byLineDefine(A, C, byred, SOLID_LINE, REGULAR_WIDTH); byLineDefine(B, C, byblack, SOLID_LINE, REGULAR_WIDTH); byLineDefine(F, D, byblack, SOLID_LINE, REGULAR_WIDTH); byLineDefine(G, E, byblack, SOLID_LINE, REGULAR_WIDTH); draw byNamedLineSeq(0)(FD,GE,BG,CF,BF,CG,AC,AB,BC); label.top(btex A etex, A); label.rt(btex C etex, C); label.lft(btex B etex, B); label.rt(btex E etex, E); label.lft(btex D etex, D); label.lft(btex F etex, F); label.rt(btex G etex, G); } ~\hfill\drawCurrentPicture\hfill~ \vskip \baselineskip
Let \drawLineAlt{A,B,C} be an isosceles triangle having the side \drawUnitLineAlt{AB} equal to the side \drawUnitLineAlt{AC}; and let the straight lines \drawUnitLineAlt{BD}, \drawUnitLineAlt{CE} be produced further in a straight line with \drawUnitLineAlt{AB}, \drawUnitLineAlt{AC}. [\textit{Post. 2}]
I say that the angle \drawAngleAlt{ABC} is equal to the angle \drawAngleAlt{ACB}, and the angle \drawAngleAlt[CBD]{DBC} to the angle \drawAngleAlt{BCE}.
Let a point F be taken at random on \drawUnitLineAlt{BD}; from AE the greater let AG be cut off equal to AF the less; [\textit{I. 3}] and let the straight lines FC, GB be joined. [\textit{Post. 1}] Then, since AF is equal to AG and AB to AC, the two sides FA, AC are equal to the two sides GA, AB, respectively; and they contain a common angle, the angle \drawAngleAlt{FAG}. Therefore the base FC is equal to the base GB, and the triangle \drawLineAlt{A,F,C} is equal to the triangle \drawLineAlt{A,G,B}, and the remaining angles will be equal to the remaining angles respectively, namely those which the equal sides subtend, that is, the angle ACF to the angle \drawAngleAlt{ABG}, and the angle AFC to the angle AGB. [\textit{I. 4}] And, since the whole AF is equal to the whole AG, and in these AB is equal to AC, the remainder BF is equal to the remainder CG. But FC was also proved equal to GB; therefore the two sides BF, FC are equal to the two sides CG, GB respectively; and the angle BFC is equal to the angle CGB, while the base BC is common to them; therefore the triangle \drawLineAlt{B,F,C} is also equal to the triangle \drawLineAlt{C,G,B}, and the remaining angles will be equal to the remaining angles respectively, namely those which the equal sides subtend; therefore the angle FBC is equal to the angle GCB, and the angle BCF to the angle CBG. Accordingly, since the whole angle ABG was proved equal to the angle ACF, and in these the angle CBG is equal to the angle BCF, the remaining angle ABC is equal to the remaining angle ACB; and they are at the base of the triangle ABC. But the angle FBC was also proved equal to the angle \drawAngleAlt{GCB}; and they are under the base. Therefore etc.
Q. E. D.
\end{document}`
I added the support for clockwise compound angles to byrne-latex
.
It works as follows. There are two new flags, first angleClockwiseMode
changes the preferred direction for the angles. If set to angleClockwiseMode := true
, it changes the default direction for the angles. Second, probably more important for you, is angleModeFallback
. This one instructs the algorithm to try and look for the angle if different direction, if the default one fails. You can set it to angleModeFallback := true
in \mpPre
(it is set to false
by default) and your examples from above should work.
There are, however, some caveats. First, if there's an angle with a missing part in the middle in the default direction, the algorithm will still fail, because the check for gaps is performed downstream. This scenario should be very rare if ever encountered. Second, if the full 2π around the center point is occupied by angles, the algorithm uses the default direction.
In both such cases you'll have to temporarily set the opposite angle direction using angleClockwiseMode
to draw the desired angles. Like this:
\drawFromCurrentPicture[middle][triangleACD]{ % notice the second argument, it allows you to redraw this whole picture using a macro, \triangleACD in this case
startAngleOppositeMode; % I also added this environment for convenience
startAutoLabeling;
draw byNamedAngleWithDummySides(ACD);
stopAutoLabeling;
stopAngleOppositeMode;
}
(note, however, that this picture won't have letter ACD
coming with it in your case, because these letters are no longer handled by MetaPost)
But, I reckon, you won't have to use this last method often or at all.
That is awesome, man. That makes it so much easier to add the in-line angles.
I think I understand your caveat about missing angle parts. Please correct me if this is wrong: Basically, if a section of the angle is undefined, and you try to draw a composite angle, the algorithm fails(?) I just tried this (getting the algorithm to fail) and fortunately the entire pdf didn't compile, so looks like it will be pretty apparent when it does happen.
Yes, it should either work as intended, or fail to compile at all in certain situations. But there certainly may still be errors which I didn't think of.
I would like to, at least for Book One as an experiment, replace Byrne's text with Heath's text, but with Byrne's graphic style--and with letterines on all the diagrams and line numbers along the side. This I believe would be the gold standard for teaching. There are many annoying issues with the way Byrne "translates" Euclid, and Heath would be a standardization of this.
The big issue here I guess is that ConTeXT is broken still(?), and so I can't really do this on my own.