geometry.tst 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. % Author H.-G. Graebe | Univ. Leipzig | Version 6.9.1998
  2. % graebe@informatik.uni-leipzig.de
  3. comment
  4. Test suite for the package GEOMETRY 1.1
  5. end comment;
  6. algebraic;
  7. load cali,geometry;
  8. off nat;
  9. on echo;
  10. showtime;
  11. % #####################
  12. % Some one line proofs
  13. % #####################
  14. % A generic triangle ABC
  15. A:=Point(a1,a2); B:=Point(b1,b2); C:=Point(c1,c2);
  16. % Its midpoint perpendiculars have a point in common:
  17. concurrent(mp(a,b),mp(b,c),mp(c,a));
  18. % This point
  19. M:=intersection_point(mp(a,b),mp(b,c));
  20. % is the center of the circumscribed circle
  21. sqrdist(M,A) - sqrdist(M,B);
  22. % The altitutes intersection theorem
  23. concurrent(altitude(a,b,c),altitude(b,c,a),altitude(c,a,b));
  24. % The median intersection theorem
  25. concurrent(median(a,b,c),median(b,c,a),median(c,a,b));
  26. % Euler's line
  27. M:=intersection_point(mp(a,b),mp(b,c));
  28. H:=intersection_point(altitude(a,b,c),altitude(b,c,a));
  29. S:=intersection_point(median(a,b,c),median(b,c,a));
  30. collinear(M,H,S);
  31. sqrdist(S,varpoint(M,H,2/3));
  32. % Feuerbach's circle
  33. % Choose a special coordinate system
  34. A:=Point(0,0); B:=Point(u1,0); C:=Point(u2,u3);
  35. M:=intersection_point(mp(a,b),mp(b,c));
  36. H:=intersection_point(altitude(a,b,c),altitude(b,c,a));
  37. N:=midpoint(M,H);
  38. sqrdist(N,midpoint(A,B))-sqrdist(N,midpoint(B,C));
  39. sqrdist(N,midpoint(A,B))-sqrdist(N,midpoint(H,C));
  40. D:=intersection_point(pp_line(A,B),pp_line(H,C));
  41. sqrdist(N,midpoint(A,B))-sqrdist(N,D);
  42. clear_ndg(); clear(A,B,C,D,M,H,S,N);
  43. % #############################
  44. % Non-linear Geometric Objects
  45. % #############################
  46. % Bisector intersection theorem
  47. A:=Point(0,0); B:=Point(1,0); C:=Point(u1,u2);
  48. P:=Point(x1,x2);
  49. polys:={
  50. point_on_bisector(P,A,B,C),
  51. point_on_bisector(P,B,C,A),
  52. point_on_bisector(P,C,A,B)};
  53. con1:=num(sqrdist(P,pedalpoint(p,pp_line(A,C)))-x2^2);
  54. con2:=num(sqrdist(p,pedalpoint(p,pp_line(B,C)))-x2^2);
  55. setring({x1,x2},{},lex);
  56. setideal(polys,polys);
  57. gbasis polys;
  58. {con1,con2} mod gbasis polys;
  59. % Bisector intersection theorem. A constructive proof.
  60. A:=Point(0,0); B:=Point(1,0); P:=Point(u1,u2);
  61. l1:=pp_line(A,B);
  62. l2:=symline(l1,pp_line(A,P));
  63. l3:=symline(l1,pp_line(B,P));
  64. point_on_bisector(P,A,B,intersection_point(l2,l3));
  65. clear_ndg(); clear(A,B,C,P,l1,l2,l3);
  66. % Miquel's theorem
  67. on gcd;
  68. A:=Point(0,0); B:=Point(1,0); C:=Point(c1,c2);
  69. P:=choose_pl(pp_line(A,B),u1);
  70. Q:=choose_pl(pp_line(B,C),u2);
  71. R:=choose_pl(pp_line(A,C),u3);
  72. X:=other_cc_point(P,p3_circle(A,P,R),p3_circle(B,P,Q))$
  73. point_on_circle(X,p3_circle(C,Q,R));
  74. off gcd;
  75. clear_ndg(); clear(A,B,C,P,Q,R,X);
  76. % ########################
  77. % Theorems of linear type
  78. % ########################
  79. % Pappus' theorem
  80. A:=Point(u1,u2); B:=Point(u3,u4); C:=Point(x1,u5);
  81. P:=Point(u6,u7); Q:=Point(u8,u9); R:=Point(u0,x2);
  82. polys:={collinear(A,B,C), collinear(P,Q,R)};
  83. con:=collinear(
  84. intersection_point(pp_line(A,Q),pp_line(P,B)),
  85. intersection_point(pp_line(A,R),pp_line(P,C)),
  86. intersection_point(pp_line(B,R),pp_line(Q,C)))$
  87. vars:={x1,x2};
  88. sol:=solve(polys,vars);
  89. sub(sol,con);
  90. % Pappus' theorem. A constructive approach
  91. A:=Point(u1,u2); B:=Point(u3,u4);
  92. P:=Point(u6,u7); Q:=Point(u8,u9);
  93. C:=choose_pl(pp_line(A,B),u5);
  94. R:=choose_pl(pp_line(P,Q),u0);
  95. con:=collinear(intersection_point(pp_line(A,Q),pp_line(P,B)),
  96. intersection_point(pp_line(A,R),pp_line(P,C)),
  97. intersection_point(pp_line(B,R),pp_line(Q,C)));
  98. clear_ndg(); clear(A,B,C,P,Q,R);
  99. % ###########################
  100. % Theorems of non linear type
  101. % ###########################
  102. % Fermat Point
  103. A:=Point(0,0); B:=Point(0,2); C:=Point(u1,u2);
  104. P:=Point(x1,x2); Q:=Point(x3,x4); R:=Point(x5,x6);
  105. polys1:={sqrdist(P,B)-sqrdist(B,C), sqrdist(P,C)-sqrdist(B,C),
  106. sqrdist(Q,A)-sqrdist(A,C), sqrdist(Q,C)-sqrdist(A,C),
  107. sqrdist(R,B)-sqrdist(A,B), sqrdist(R,A)-sqrdist(A,B)};
  108. con:=concurrent(pp_line(A,P), pp_line(B,Q), pp_line(C,R));
  109. vars:={x1,x2,x3,x4,x5,x6};
  110. setring(vars,{},lex);
  111. iso:=isolatedprimes polys1;
  112. for each u in iso collect con mod u;
  113. polys2:={sqrdist(P,B)-sqrdist(P,C),
  114. sqrdist(Q,A)-sqrdist(Q,C),
  115. sqrdist(R,A)-sqrdist(R,B),
  116. num(p3_angle(R,A,B)-p3_angle(P,B,C)),
  117. num(p3_angle(Q,C,A)-p3_angle(P,B,C))};
  118. sol:=solve(polys2,{x1,x2,x3,x4,x6});
  119. sub(sol,con);
  120. clear_ndg(); clear(A,B,C,P,Q,R);
  121. % ####################
  122. % Desargue's theorem
  123. % ####################
  124. % A constructive proof.
  125. A:=Point(a1,a2); B:=Point(b1,b2);
  126. C:=Point(c1,c2); R:=Point(d1,d2);
  127. S:=choose_pl(par(R,pp_line(A,B)),u);
  128. T:=intersection_point(par(R,pp_line(A,C)),par(S,pp_line(B,C)));
  129. con:=concurrent(pp_line(A,R),pp_line(B,S),pp_line(C,T));
  130. % Desargue's theorem as theorem of linear type.
  131. A:=Point(u1,u2); B:=Point(u3,u4); C:=Point(u5,u6);
  132. R:=Point(u7,u8); S:=Point(u9,x1); T:=Point(x2,x3);
  133. polys:={parallel(pp_line(R,S),pp_line(A,B)),
  134. parallel(pp_line(S,T),pp_line(B,C)),
  135. parallel(pp_line(R,T),pp_line(A,C))};
  136. con:=concurrent(pp_line(A,R),pp_line(B,S),pp_line(C,T));
  137. sol:=solve(polys,{x1,x2,x3});
  138. sub(sol,con);
  139. % The general theorem of Desargue.
  140. A:=Point(0,0); B:=Point(0,1); C:=Point(u5,u6);
  141. R:=Point(u7,u8); S:=Point(u9,u1); T:=Point(u2,x1);
  142. con1:=collinear(intersection_point(pp_line(R,S),pp_line(A,B)),
  143. intersection_point(pp_line(S,T),pp_line(B,C)),
  144. intersection_point(pp_line(R,T),pp_line(A,C)));
  145. con2:=concurrent(pp_line(A,R),pp_line(B,S),pp_line(C,T));
  146. sol:=solve(con2,x1);
  147. sub(sol,con1);
  148. clear_ndg(); clear(A,B,C,R,S,T);
  149. % #################
  150. % Brocard points
  151. % #################
  152. A:=Point(0,0); B:=Point(1,0); C:=Point(u1,u2);
  153. c1:=Circle(1,x1,x2,x3);
  154. c2:=Circle(1,x4,x5,x6);
  155. c3:=Circle(1,x7,x8,x9);
  156. polys:={
  157. cl_tangent(c1,pp_line(A,C)),
  158. point_on_circle(A,c1),
  159. point_on_circle(B,c1),
  160. cl_tangent(c2,pp_line(A,B)),
  161. point_on_circle(B,c2),
  162. point_on_circle(C,c2),
  163. cl_tangent(c3,pp_line(B,C)),
  164. point_on_circle(A,c3),
  165. point_on_circle(C,c3)};
  166. vars:={x1,x2,x3,x4,x5,x6,x7,x8,x9};
  167. sol:=solve(polys,vars);
  168. P:=other_cc_point(B,sub(sol,c1),sub(sol,c2));
  169. con:=point_on_circle(P,sub(sol,c3));
  170. clear_ndg(); clear A,B,C,c1,c2,c3;
  171. % ##################
  172. % Simson's theorem
  173. % ##################
  174. % A constructive proof
  175. M:=Point(0,0);
  176. A:=choose_pc(M,r,u1);
  177. B:=choose_pc(M,r,u2);
  178. C:=choose_pc(M,r,u3);
  179. P:=choose_pc(M,r,u4);
  180. X:=pedalpoint(P,pp_line(A,B))$
  181. Y:=pedalpoint(P,pp_line(B,C))$
  182. Z:=pedalpoint(P,pp_line(A,C))$
  183. collinear(X,Y,Z);
  184. clear_ndg(); clear(M,A,B,C,P,X,Y,Z);
  185. % Simson's theorem almost constructive
  186. clear_ndg();
  187. A:=Point(0,0); B:=Point(u1,u2);
  188. C:=Point(u3,u4); P:=Point(u5,x1);
  189. X:=pedalpoint(P,pp_line(A,B));
  190. Y:=pedalpoint(P,pp_line(B,C));
  191. Z:=pedalpoint(P,pp_line(A,C));
  192. poly:=p4_circle(A,B,C,P);
  193. con:=collinear(X,Y,Z);
  194. remainder(num con,poly);
  195. print_ndg();
  196. % Equational proof, first version:
  197. M:=Point(0,0); A:=Point(0,1);
  198. B:=Point(u1,x1); C:=Point(u2,x2); P:=Point(u3,x3);
  199. X:=varpoint(A,B,x4); Y:=varpoint(B,C,x5); Z:=varpoint(A,C,x6);
  200. polys:={sqrdist(M,B)-1, sqrdist(M,C)-1, sqrdist(M,P)-1,
  201. orthogonal(pp_line(A,B),pp_line(P,X)),
  202. orthogonal(pp_line(A,C),pp_line(P,Z)),
  203. orthogonal(pp_line(B,C),pp_line(P,Y))};
  204. con:=collinear(X,Y,Z);
  205. vars:={x4,x5,x6,x1,x2,x3};
  206. setring(vars,{},lex);
  207. setideal(polys,polys);
  208. con mod gbasis polys;
  209. % Second version:
  210. A:=Point(0,0);
  211. B:=Point(1,0);
  212. C:=Point(u1,u2);
  213. P:=Point(u3,x1);
  214. X:=Point(x2,0); % => on the line AB
  215. Y:=varpoint(B,C,x3);
  216. Z:=varpoint(A,C,x4);
  217. polys:={orthogonal(pp_line(A,C),pp_line(P,Z)),
  218. orthogonal(pp_line(B,C),pp_line(P,Y)),
  219. orthogonal(pp_line(A,B),pp_line(P,X)),
  220. p4_circle(A,B,C,P)};
  221. con:=collinear(X,Y,Z);
  222. vars:={x2,x3,x4,x1};
  223. setring(vars,{},lex);
  224. con mod interreduce polys;
  225. % The inverse theorem
  226. polys:={orthogonal(pp_line(A,C),pp_line(P,Z)),
  227. orthogonal(pp_line(B,C),pp_line(P,Y)),
  228. orthogonal(pp_line(A,B),pp_line(P,X)),
  229. collinear(X,Y,Z)};
  230. con:=p4_circle(A,B,C,P);
  231. con mod interreduce polys;
  232. clear_ndg(); clear(M,A,B,C,P,Y,Z);
  233. % ########################
  234. % The butterfly theorem
  235. % ########################
  236. % An equational proof with groebner factorizer and constraints.
  237. P:=Point(0,0);
  238. O:=Point(u1,0);
  239. A:=Point(u2,u3);
  240. B:=Point(u4,x1);
  241. C:=Point(x2,x3);
  242. D:=Point(x4,x5);
  243. F:=Point(0,x6);
  244. G:=Point(0,x7);
  245. polys:={sqrdist(O,B)-sqrdist(O,A),
  246. sqrdist(O,C)-sqrdist(O,A),
  247. sqrdist(O,D)-sqrdist(O,A),
  248. point_on_line(P,pp_line(A,C)),
  249. point_on_line(P,pp_line(B,D)),
  250. point_on_line(F,pp_line(A,D)),
  251. point_on_line(G,pp_line(B,C))
  252. };
  253. con:=num sqrdist(P,midpoint(F,G));
  254. vars:={x6,x7,x3,x5,x1,x2,x4};
  255. setring(vars,{},lex);
  256. sol:=groebfactor(polys,{sqrdist(A,C),sqrdist(B,D)});
  257. for each u in sol collect con mod u;
  258. % A constructive proof
  259. on gcd;
  260. O:=Point(0,0);
  261. A:=Point(1,0);
  262. B:=choose_pc(O,1,u1);
  263. C:=choose_pc(O,1,u2);
  264. D:=choose_pc(O,1,u3);
  265. P:=intersection_point(pp_line(A,C),pp_line(B,D));
  266. h:=lot(P,pp_line(O,P));
  267. F:=intersection_point(h,pp_line(A,D));
  268. G:=intersection_point(h,pp_line(B,C));
  269. con:=sqrdist(P,midpoint(F,G));
  270. off gcd;
  271. clear_ndg(); clear(O,A,B,C,D,P,h,F,G);
  272. % ################################
  273. % Tangency of Feuerbach's circle
  274. % ################################
  275. A:=Point(0,0); B:=Point(2,0); C:=Point(u1,u2);
  276. M:=intersection_point(mp(A,B),mp(B,C));
  277. H:=intersection_point(altitude(A,B,C),altitude(B,C,A));
  278. N:=midpoint(M,H);
  279. c1:=c1_circle(N,sqrdist(N,midpoint(A,B)));
  280. % Feuerbach's circle
  281. P:=Point(x1,x2); % => x2 is the radius of the inscribed circle.
  282. polys:={point_on_bisector(P,A,B,C), point_on_bisector(P,B,C,A)};
  283. con:=cc_tangent(c1_circle(P,x2^2),c1);
  284. vars:={x1,x2};
  285. setring(vars,{},lex);
  286. setideal(polys,polys);
  287. num con mod gbasis polys;
  288. % Now let P be the incenter of the triangle ABH
  289. polys1:={point_on_bisector(P,A,B,H), point_on_bisector(P,B,H,A)};
  290. con1:=cc_tangent(c1_circle(P,x2^2),c1);
  291. setideal(polys1,polys1);
  292. num con1 mod gbasis polys1;
  293. clear_ndg(); clear A,B,C,P,M,N,H,c1;
  294. % #############################
  295. % Solutions to the exercises
  296. % #############################
  297. % 1)
  298. A:=Point(0,0); B:=Point(1,0); C:=Point(1,1); D:=Point(0,1);
  299. P:=Point(x1,x2); Q:=Point(x3,1);
  300. polys:={point_on_line(P,par(C,pp_line(B,D))),
  301. sqrdist(B,D)-sqrdist(B,P),
  302. point_on_line(Q,pp_line(B,P))};
  303. con:=sqrdist(D,P)-sqrdist(D,Q);
  304. setring({x1,x2,x3},{},lex);
  305. setideal(polys,polys);
  306. con mod gbasis polys;
  307. clear_ndg(); clear(A,B,C,D,P,Q);
  308. % 2)
  309. A:=Point(u1,0); B:=Point(u2,0); C:=Point(0,u3);
  310. Q:=Point(0,0); % the pedal point on AB
  311. R:=pedalpoint(B,pp_line(A,C));
  312. P:=pedalpoint(A,pp_line(B,C));
  313. con1:=point_on_bisector(C,P,Q,R);
  314. con2:=angle_sum(p3_angle(P,Q,C),p3_angle(R,Q,C));
  315. clear_ndg(); clear(A,B,C,P,Q,R);
  316. % 3)
  317. A:=Point(u1,0); B:=Point(u2,0); C:=Point(0,u3);
  318. P:=pedalpoint(A,pp_line(B,C));
  319. Q:=pedalpoint(B,pp_line(A,C));
  320. R:=pedalpoint(C,pp_line(A,B));
  321. P1:=pedalpoint(P,pp_line(A,B));
  322. P2:=pedalpoint(P,pp_line(A,C));
  323. Q1:=pedalpoint(Q,pp_line(A,B));
  324. Q2:=pedalpoint(Q,pp_line(B,C));
  325. R1:=pedalpoint(R,pp_line(A,C));
  326. R2:=pedalpoint(R,pp_line(B,C));
  327. con:=for each X in {Q2,R1,R2} collect p4_circle(P1,P2,Q1,X);
  328. clear_ndg(); clear(O,A,B,C,P,Q,R,P1,P2,Q1,Q2,R1,R2);
  329. % 4)
  330. A:=Point(u1,0); B:=Point(u2,0); C:=Point(0,u3);
  331. % => Pedalpoint from C is (0,0)
  332. M:=intersection_point(mp(A,B),mp(B,C));
  333. % Prove (2*h_c*R = a*b)^2
  334. con:=4*u3^2*sqrdist(M,A)-sqrdist(C,B)*sqrdist(A,C);
  335. clear_ndg(); clear(A,B,C,M);
  336. % 5. A solution of constructive type.
  337. on gcd;
  338. O:=Point(0,u1); A:=Point(0,0); % hence k has radius u1.
  339. B:=Point(u2,0);
  340. M:=midpoint(A,B);
  341. D:=choose_pc(O,u1,u3);
  342. k:=c1_circle(O,u1^2);
  343. C:=other_cl_point(D,k,pp_line(M,D));
  344. Eh:=other_cl_point(D,k,pp_line(B,D));
  345. F:=other_cl_point(C,k,pp_line(B,C));
  346. con:=parallel(pp_line(A,B),pp_line(Eh,F));
  347. off gcd;
  348. clear_ndg(); clear(O,A,B,C,D,Eh,F,M,k);
  349. % 6)
  350. Z:=Point(0,0); X:=Point(0,1); Y:=Point(0,-1);
  351. B:=Point(u1,0); C:=Point(u2,0); P:=Point(0,u3);
  352. M:=Point(x1,x2); N:=Point(x3,x4);
  353. A:=Point(x5,0); D:=Point(x6,0);
  354. polys:={p4_circle(X,Y,B,N), p4_circle(X,Y,C,M),
  355. p4_circle(X,Y,B,D), p4_circle(X,Y,C,A),
  356. collinear(B,P,N), collinear(C,P,M)};
  357. con:=concurrent(pp_line(A,M),pp_line(D,N),pp_line(X,Y));
  358. vars:={x1,x2,x3,x4,x5,x6};
  359. setring(vars,{},lex);
  360. res:=groebfactor(polys,{x5-u2,x1-u2,x6-u1,x3-u1});
  361. % constraints A\neq C, M\neq C, D\neq B, N\neq B
  362. for each u in res collect con mod u;
  363. clear_ndg(); clear(Z,X,Y,B,C,P,M,N,A,D);
  364. % 7)
  365. M:=Point(0,0);
  366. A:=Point(0,u1); B:=Point(-1,0); C:=Point(1,0);
  367. Eh:=varpoint(A,B,x1); F:=varpoint(A,C,x2);
  368. O:=intersection_point(pp_line(A,M),lot(B,pp_line(A,B)));
  369. Q:=intersection_point(pp_line(Eh,F),pp_line(B,C));
  370. con1:=num orthogonal(pp_line(O,Q),pp_line(Eh,Q));
  371. con2:=num sqrdist(Q,midpoint(Eh,F));
  372. vars:={x1,x2};
  373. setring(vars,{},lex);
  374. p1:=groebfactor({con1},{x1-1,x2-1,x1,x2});
  375. p2:=groebfactor({con2},{x1-1,x2-1,x1,x2});
  376. % constraint A,C\neq Eh, B,C\neq F
  377. for each u in p1 collect con2 mod u;
  378. for each u in p2 collect con1 mod u;
  379. % Note that the second component of p2 has no relevant *real* roots,
  380. % since it factors as u1^2 * (x1 - x2)^2 + (x1 + x2 -2)^2 :
  381. u1^2 * (x1 - x2)^2 + (x1 + x2 -2)^2 mod second p2;
  382. clear_ndg(); clear(M,A,B,C,O,Eh,F,Q);
  383. % 8)
  384. on gcd;
  385. A:=Point(u1,0); B:=Point(u2,0); l1:=pp_line(A,B);
  386. M:=Point(0,u3); % the incenter, hence u3 = incircle radius
  387. C:=intersection_point(symline(l1,pp_line(A,M)),
  388. symline(l1,pp_line(B,M)));
  389. N:=intersection_point(mp(A,B),mp(B,C)); % the outcenter
  390. sqr_rad:=sqrdist(A,N); % the outcircle sqradius.
  391. (sqr_rad-sqrdist(M,N))^2-4*u3^2*sqr_rad;
  392. off gcd;
  393. clear_ndg(); clear A,B,C,M,N,l1,sqr_rad;
  394. % 9)
  395. on gcd;
  396. A:=Point(0,0); B:=Point(1,0); M:=Point(u1,0);
  397. C:=Point(u1,u1); F:=Point(u1,1-u1);
  398. c1:=red_hom_coords p3_circle(A,M,C);
  399. c2:=red_hom_coords p3_circle(B,M,F);
  400. N:=other_cc_point(M,c1,c2);
  401. point_on_line(N,pp_line(A,F));
  402. point_on_line(N,pp_line(B,C));
  403. l1:=red_hom_coords pp_line(M,N);
  404. l2:=sub(u1=u2,l1);
  405. intersection_point(l1,l2); % = (1/2,-1/2)
  406. off gcd;
  407. clear_ndg(); clear A,B,C,F,M,N,c1,c2,l1,l2;
  408. % ####################
  409. % Some more examples
  410. % ####################
  411. % Origin: D. Wang at
  412. % http://cosmos.imag.fr/ATINF/Dongming.Wang/geother.html
  413. % --------------------------
  414. % Given triangle ABC, H orthocenter, O circumcenter, A1 circumcenter
  415. % of BHC, B1 circumcenter of AHC.
  416. %
  417. % Claim: OH, AA1, BB1 are concurrent.
  418. % --------------------------
  419. A:=Point(u1,0); B:=Point(u2,0); C:=Point(0,u3);
  420. H:=intersection_point(altitude(C,A,B),altitude(A,B,C));
  421. O:=circle_center(p3_circle(A,B,C));
  422. A1:=circle_center(p3_circle(H,B,C));
  423. B1:=circle_center(p3_circle(H,A,C));
  424. con:=concurrent(pp_line(O,H),pp_line(A,A1),pp_line(B,B1));
  425. end;