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]