Constructing a triangle

Constructing a triangle

\documentclass[border=10pt]{standalone}
\usepackage{asymptote}
\begin{document}
\begin{asy}[inline=true]
import math;
import graph;

struct construct{
  pair[] loc;
  string[] name;
  pair[] namePos;
  guide[] straight;
  pen[] straightPen;
  guide[] circ;
  pen[] circPen;

  pen thinpen;

  bool pqr(pair p, pair q, pair r){
    return (p.x*(q.y-r.y)+(r.y-p.y)*q.x+r.x*(p.y-q.y))>0;
  };

  pair lastpoint(){
    assert(loc.length>0); 
    return loc[loc.length-1]; 
  }

  pair prevpoint(){
    assert(loc.length>1); 
    return loc[loc.length-2]; 
  }

  pair newpoint(pair ploc, string pname="", pair npos=(0,0)){
    loc.push(ploc);
    name.push(pname);
    namePos.push(npos);
    return loc[loc.length-1];
  }

  guide newstraight(pair A, pair B, pen p=nullpen){
    straight.push(A--B);
    straightPen.push(p);    
    return straight[straight.length-1];
  }

  guide newcirc(pair A,pair B, pen p=nullpen){
    circ.push(Circle(A,arclength(A--B)));
    circPen.push(p);
    return circ[circ.length-1];
  }

  pair halve(pair A, pair B, string pname="", pair npos=(0,0)){
    guide p,q; 
    pair[] xpt;
    p=newcirc(A,B,thinpen);
    q=newcirc(B,A,thinpen);
    xpt=intersectionpoints(p,q);
    newpoint(xpt[0]);
    newpoint(xpt[1]);
    newstraight(lastpoint(),prevpoint(),thinpen);
    newpoint(extension(A,B,xpt[0],xpt[1]),pname,npos);
    return lastpoint();
  }

  pair leftPoint(pair A1, pair B1, pair A2, pair B2, string pname="", pair npos=(0,0)){
    guide p,q;
    pair[] xpts;
    p=newcirc(A1,B1,thinpen);
    q=newcirc(A2,B2,thinpen);
    xpts=intersectionpoints(p,q);
    newpoint((pqr(A1,A2,xpts[0]))?xpts[0]:xpts[1],pname,npos);
    return lastpoint();
  }

  pair rightPoint(pair A1, pair B1, pair A2, pair B2, string pname="", pair npos=(0,0)){
    guide p,q;
    pair[] xpts;
    p=newcirc(A1,B1,thinpen);
    q=newcirc(A2,B2,thinpen);
    xpts=intersectionpoints(p,q);
    newpoint((pqr(A1,A2,xpts[0]))?xpts[1]:xpts[0],pname,npos);
    return lastpoint();
  }

  pair at_dist(pair A, pair B, pair C, string pname="", pair npos=(0,0)){
    newcirc(A,C,thinpen);
    newpoint(A+dir(B-A)*arclength(A--C),pname,npos);
    return lastpoint();
  }

  void showStraights(){
    for(int i=0;i<straight.length;++i){
      draw(straight[i],straightPen[i]);
    }  
  }

  void showCircs(){
    for(int i=0;i<circ.length;++i){
      draw(circ[i],circPen[i]);
    }
  }

  void showDots(){
    for(int i=0;i<loc.length;++i){
      dot(loc[i],UnFill);
    }
  }

  void showLabels(){
    for(int i=0;i<loc.length;++i){
      label("$"+name[i]+"$",loc[i],namePos[i]);
    }
  }

  void operator init(pen thinpen=gray+0.3bp){
    this.loc=new pair[];
    this.name=new string[];
    this.namePos=new pair[];
    this.thinpen=thinpen;
  }
}
//=================================

size(250);
import graph;
import math;
import fontsize;
defaultpen(fontsize(9pt));

real w=1.2bp;
pen ABpen=blue+w;
pen BCpen=red+w;
pen ACpen=deepgreen+w;
pen ADpen=gray(0.4)+w;
pen CDpen=orange+w;
pen thinpen=gray+0.4bp;
pen arcpen=black+w;

construct ABCD=construct();

// Construct two arbitrary points A and B
pair A=ABCD.newpoint((1,5),"A",NE);
pair B=ABCD.newpoint((0,0),"B",S);

// Construct measuring marks on AB, assuming |AB|=8 
pair H4=ABCD.halve(A, B,"_4",SE);
pair H2=ABCD.halve(B,H4,"_2",SE);
pair H1=ABCD.halve(B,H2,"_1",SE);
pair H6=ABCD.halve(A,H4,"_6",SE);
pair H7=ABCD.halve(H6,A,"_7",SE);

// Construct point C: |AH1|=7, |BH6|=6
pair C=ABCD.leftPoint(A,H1,B,H6,"C",SE);

// Construct A' as a point of untersection of Circle(B,|BH7|) and Circle(A,|AH2|)   
pair Ap=ABCD.leftPoint(B,H7,A,H2,"A^\prime",N);

// Construct C' as a point of untersection of the line through AA' and a Circle(A,|AC|)   
pair Cp=ABCD.at_dist(A,Ap,C,"C^\prime",S);

// Construct Q6 as a point of untersection of the line through AC' and a Circle(A,|AH7|)   
pair Q6=ABCD.at_dist(A,Cp,H7,"_6",NW);

// Construct B' as a point of untersection of Circle(C',|C'Q6|) and Circle(A,|AB|)   
pair Bp=ABCD.leftPoint(Cp,Q6,A,B,"B^\prime",NE);

// Construct D as a point of untersection of the line through B',A and the line through B,C
pair D=ABCD.newpoint(extension(Bp,A,B,C),"D",S);

ABCD.showStraights();
ABCD.showCircs();

// draw helper lines
draw(Ap--B,thinpen);
drawline(A,Ap,thinpen);
drawline(B,C,thinpen);

// mark angles    
draw(arc(A,arcpoint(A--B,arclength(B--H1)),C),arcpen);
draw(arc(A,arcpoint(A--Bp,arclength(B--H1)),Cp),arcpen);
draw(arc(D,arcpoint(D--A,arclength(B--H1)),C),arcpen);

// draw sides
draw(A--B,ABpen);
draw(A--Bp,ABpen);
draw(A--C,ACpen);
draw(A--Cp,ACpen);
draw(B--C,BCpen);
draw(Bp--Cp,BCpen);
draw(A--D,ADpen);
draw(C--D,CDpen);

ABCD.showDots();
ABCD.showLabels();
\end{asy}
\end{document}

Source: TeX.SE

Author: g.kov (License)