diff --git a/caustic.js b/caustic.js index badd269..c9eb0a1 100644 --- a/caustic.js +++ b/caustic.js @@ -64,10 +64,45 @@ function caustic_dual(a) { // assume incircle at 0,0 // R=1+a; -function caustic_poristic(a) { +function caustic_bicentric(a) { return [1, 1]; } +// derived by R. Garcia, Aug. 2024 +// ctr=[a^2*c/(2*a^2 - c^2), 0] e raio=a*(a^2 - c^2)/(2*a^2 - c^2) tem X4=[c,0] +function caustic_orthofocal(a) { + const a2 = a*a, b2 = b*b; + const c2 = a2-b2; + const c = Math.sqrt(c); + const cx = (a2*c)/(2*a2 - c2); + return [cx, 0]; +} + +function porism_orthofocal(a) { + const a2 = a*a, b2 = 1; + const c2 = a2-b2; + const c = Math.sqrt(c2); + const k = 2*a2 - c2; + const cx = (a2*c)/k; + const r = a*(a2 - c2)/k; + return { ctr: [cx, 0], r: r }; +} + +function caustic_incenterfocal(a) { + const c = Math.sqrt(Math.abs(a*a - b*b)); + return [c, 0]; + } + + // DSR 8/7/24 + function porism_incenterfocal(a) { + const a2 = a*a, b2 = 1; + const c2 = a2-b2; + const c = Math.sqrt(c2); + const denom2 = 3*a2 + 2*a*Math.sqrt(2*a2-1) - 1; + const r = 1/Math.sqrt(denom2); + return { ctr: [c, 0], r: r }; + } + function caustic_brocard(a) { const isos = getBrocardInellipseIsosceles(a, 1); const x3 = get_Xn_cartesians(3, isos[0], tri_sides(isos[0])); @@ -75,7 +110,7 @@ function caustic_brocard(a) { return [R, R]; } -function brocard_porism(a) { +function porism_brocard(a) { const isos = getBrocardInellipseIsosceles(a, 1); const x3 = get_Xn_cartesians(3, isos[0], tri_sides(isos[0])); const R = edist(isos[0][0], x3); @@ -88,7 +123,7 @@ function caustic_macbeath(a) { return [R, R]; } -function macbeath_porism(a) { +function porism_macbeath(a) { const R = 2*a; const c = Math.sqrt(a*a-1); return { R: R, x3: [-c,0] }; diff --git a/circles.js b/circles.js index 16704f5..3ff131a 100644 --- a/circles.js +++ b/circles.js @@ -415,8 +415,9 @@ function circle_polar(tri,sides) { const x4 = get_Xn_cartesians(4,tri,sides); const R = get_circumradius(sides); const l2 = sum(sides.map(s => s * s)); - const rpol2 = 4*R*R - l2/2; - return { ctr:x4, R:sqrt(Math.abs(rpol2)), n:4 }; + const rpol2 = 4*R*R - l2/2; + const rpol = sqrt(Math.abs(rpol2)); + return { ctr: x4, R: rpol, n:4 }; } function circle_mandart(tri,sides) { diff --git a/components.js b/components.js index 70985c8..a618002 100644 --- a/components.js +++ b/components.js @@ -46,9 +46,11 @@ var html = function(xn_number, trilins_selected, tri_selected, rgb_color, hex_co - + - `+ + + + `+ //needs to draw external ellipse as caustic assuming [a,1] of interface is its caustic // ` diff --git a/locus.js b/locus.js index a1bbcd2..d0b99ae 100644 --- a/locus.js +++ b/locus.js @@ -132,11 +132,14 @@ const dict_caustic = { incircle: caustic_incircle, inellipse: caustic_inellipse, dual: caustic_dual, - poristic: caustic_poristic, - brocard: caustic_brocard, excentral: caustic_excentral, excentral_affine: caustic_excentral_affine, - macbeath: caustic_macbeath + // non concentric + poristic: caustic_bicentric, + brocard: caustic_brocard, + macbeath: caustic_macbeath, + incenterfocal: caustic_incenterfocal, + orthofocal: caustic_orthofocal }; const dict_two_point = { @@ -167,11 +170,14 @@ const dict_orbit_fn = { incircle: orbit_incircle, inellipse: orbit_inellipse, dual: orbit_dual, - poristic: orbit_poristic, + excentral: orbit_excentral, + excentral_affine: orbit_excentral_affine, + // non-concentric + poristic: orbit_bicentric, brocard: orbit_brocard, macbeath: orbit_macbeath, - excentral: orbit_excentral, - excentral_affine: orbit_excentral_affine + incenterfocal: orbit_incenterfocal, + orthofocal: orbit_orthofocal }; function get_mounted_derived(a, tDeg, mounting, tri_type, cpn, pn, circ, inv) { @@ -292,17 +298,31 @@ function draw_poncelet_locus_branched(n, a, tDeg, rot, orbit_fn, mounting, locus draw_boundary(1 + a, 1 + a, clr_caustic, stroke_w); pop(); } else if (mounting == "brocard") { - const bp = brocard_porism(a); + const bp = porism_brocard(a); push(); translate(...bp.x3); // true center draw_boundary(bp.R, bp.R, clr_caustic, stroke_w); pop(); } else if (mounting == "macbeath") { - const bp = macbeath_porism(a); + const bp = porism_macbeath(a); push(); translate(...bp.x3); // true center draw_boundary(bp.R, bp.R, clr_caustic, stroke_w); pop(); + } else if (mounting == "orthofocal") { + const op = porism_orthofocal(a); + push(); + translate(...op.ctr); + draw_boundary(op.r, op.r, clr_caustic, stroke_w); + draw_point2([0,0], clr_caustic, stroke_w / 2); + pop(); + } else if (mounting == "incenterfocal") { + const ip = porism_incenterfocal(a); + push(); + translate(...ip.ctr); + draw_boundary(ip.r, ip.r, clr_caustic, stroke_w); + draw_point2([0,0], clr_caustic, stroke_w / 2); + pop(); } else { const caustic_axes = dict_caustic[mounting](a); draw_boundary(...caustic_axes, clr_caustic, stroke_w); diff --git a/poncelet.js b/poncelet.js index 5d62be5..c7427ad 100644 --- a/poncelet.js +++ b/poncelet.js @@ -241,7 +241,7 @@ function chapple_d(r,R) { return sqrt(R*R - 2*r*R); } -function orbit_poristic(a, tDeg) { +function orbit_bicentric(a, tDeg) { const R=1+a; const r = 1; // assume const R2 = R*R; @@ -307,12 +307,12 @@ function orbit_brocard(a, tDeg) { return { o: tri, s: tri_sides(tri) }; } -// what parameter "x" must be passed to orbit_poristic so that its +// what parameter "x" must be passed to orbit_bicentric so that its // excentral's MacBeath (call it E) has aspect ratio a, the UI-established caustic major axis? // Let a', b' be the semiaxes of E. Observing E, a' = Rpor = (1+a). // since we want a'/b' = (1+a)/b' = a, then b' must be (1+a)/a. // per Peter Moses, b' = sqrt(Rexc^2-|OH|^2)/2. Per odehnal, Rexc = 2*(1+a). -// observing the poristic: H (resp. O) of the excentral is X1 (resp. X40) of the poristic. +// observing the bicentric: H (resp. O) of the excentral is X1 (resp. X40) of the bicentric. // X40 is the reflection of X1 on X3. Euler's formula: |X1X3|^2 = R(R-2r). // so |OH| of the excentral will be 2*sqrt(R(R-2r)), with rpor = 1. // So |OH|^2 = 4*R*(R-2) = 4*(a+1)*(a-1) = 4*(a^2-1) = 4*c^2 [Rpor = 1+a]. @@ -324,9 +324,9 @@ function orbit_brocard(a, tDeg) { function orbit_macbeath(a, tDeg) { const x = 2*a*a-1; // Excentral's Macbeath should have aspect ratio of "a". - const op = orbit_poristic(x, tDeg); + const op = orbit_bicentric(x, tDeg); const exc_ts = excentral_triangle(op.s); - // the excentral of orbit_poristic has a caustic whose axes are a'=Rpor=1+a and b'=?. + // the excentral of orbit_bicentric has a caustic whose axes are a'=Rpor=1+a and b'=?. // however, I want the caustic to have a' = a. // const exc = generic_triangle(op.o,op.s,exc_ts); @@ -334,9 +334,35 @@ function orbit_macbeath(a, tDeg) { const x3e = get_Xn_cartesians(40,op.o,op.s); // X(40) of ref is X(3) if excentral const c = sqrt(a*a-1); const ctr = [-c,0]; - const Rexc = 2*(1+x); // twice what's calc'd in orbit_poristic. + const Rexc = 2*(1+x); // twice what's calc'd in orbit_bicentric. const Rmb = 2*a; // from caustic_macbeath. const exc_adj = exc.map(v=>vsum(vscale(vdiff(v,x3e),Rmb/Rexc),ctr)); return { o: exc_adj, s: tri_sides(exc_adj) }; } +function orbit_orthofocal(a, tDeg) { + // cannnot assume caustic ctr always at [0,0] + const t = tDeg*Math.PI/180.; + const op = porism_orthofocal(a); + const p1 = [a*Math.cos(t),Math.sin(t)]; + const p1_adj = vdiff(p1, op.ctr); + const ts = ellTangentsb(op.r, op.r, p1_adj).map(tg => vsum(tg,op.ctr)); + const ints = ts.map(tg => ellInterRaybBoth(a, 1, p1, vdiff(tg, p1))); + const [p2, p3] = ints.map(ints => farthestPoint(ints, p1)); + const tri = [p1, p2, p3] + return { o: tri, s: tri_sides(tri) }; +} + +function orbit_incenterfocal(a, tDeg) { + // cannnot assume caustic ctr always at [0,0] + const t = tDeg*Math.PI/180.; + const op = porism_incenterfocal(a); + const p1 = [a*Math.cos(t),Math.sin(t)]; + const p1_adj = vdiff(p1, op.ctr); + const ts = ellTangentsb(op.r, op.r, p1_adj).map(tg => vsum(tg,op.ctr)); + const ints = ts.map(tg => ellInterRaybBoth(a, 1, p1, vdiff(tg, p1))); + const [p2, p3] = ints.map(ints => farthestPoint(ints, p1)); + const tri = [p1, p2, p3] +return { o: tri, s: tri_sides(tri) }; +} + diff --git a/triangles.js b/triangles.js index 7d7e4f5..ae661cd 100644 --- a/triangles.js +++ b/triangles.js @@ -962,14 +962,11 @@ function mixtilinear9th_triangle([a, b, c]) { return ts; } - - function get_graves_triangle(p1, ta /* true axes */) { const ts = ellTangentsb(ta.ac, ta.bc, p1); return [p1, ts[0], ts[1]]; } - // not used: caustic will close poncelet. function get_ellcevian1_triangle(p1, ta) { // assume caustic ctr always at [0,0]