Skip to content

Commit 65222cf

Browse files
committed
v.1.0.0 in progress
* solve quartic, quadratic/quadratic, ellipse/ellipse intersection
1 parent 2b2ef92 commit 65222cf

File tree

3 files changed

+202
-6
lines changed

3 files changed

+202
-6
lines changed

build/Geometrize.js

+102-4
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
* Geometrize
33
* computational geometry and rendering library for JavaScript
44
*
5-
* @version 1.0.0 (2023-02-20 20:33:09)
5+
* @version 1.0.0 (2023-02-21 01:06:11)
66
* https://github.com/foo123/Geometrize
77
*
88
**//**
99
* Geometrize
1010
* computational geometry and rendering library for JavaScript
1111
*
12-
* @version 1.0.0 (2023-02-20 20:33:09)
12+
* @version 1.0.0 (2023-02-21 01:06:11)
1313
* https://github.com/foo123/Geometrize
1414
*
1515
**/
@@ -4307,12 +4307,14 @@ var Ellipse = makeClass(EllipticArc2D, {
43074307
}
43084308
else if (Geometrize.Circle && (other instanceof Geometrize.Circle))
43094309
{
4310-
i = polyline_circle_intersection(self._lines, other.center, other.radius);
4310+
//i = polyline_circle_intersection(self._lines, other.center, other.radius);
4311+
i = ellipse_ellipse_intersection(self.center, self.radiusX, self.radiusY, self.cs, other.center, other.radius, other.radius, [1, 0]);
43114312
return i ? i.map(Point2D) : false
43124313
}
43134314
else if (other instanceof Ellipse)
43144315
{
4315-
i = polyline_ellipse_intersection(self._lines, other.center, other.radiusX, other.radiusY, other.cs);
4316+
//i = polyline_ellipse_intersection(self._lines, other.center, other.radiusX, other.radiusY, other.cs);
4317+
i = ellipse_ellipse_intersection(self.center, self.radiusX, self.radiusY, self. cs, other.center, other.radiusX, other.radiusY, other.cs);
43164318
return i ? i.map(Point2D) : false
43174319
}
43184320
else if (other instanceof Object2D)
@@ -5273,6 +5275,11 @@ function circle_circle_intersection(c1, r1, c2, r2)
52735275
;
52745276
return is_strictly_equal(h, 0) ? [{x:px, y:py}] : [{x:px + h*dy, y:py - h*dx}, {x:px - h*dy, y:py + h*dx}];
52755277
}
5278+
function ellipse_ellipse_intersection(c1, rx1, ry1, cs1, c2, rx2, ry2, cs2)
5279+
{
5280+
var q1 = ellipse2quadratic(c1, rx1, ry1, cs1), q2 = ellipse2quadratic(c2, rx2, ry2, cs2);
5281+
return solve_quadratic_quadratic_system(q1[0], q1[1], q1[2], q1[3], q1[4], q1[5], q2[0], q2[1], q2[2], q2[3], q2[4], q2[5]);
5282+
}
52765283
function polyline_line_intersection(polyline_points, p1, p2)
52775284
{
52785285
var i = [], j, p, n = polyline_points.length-1;
@@ -5522,6 +5529,53 @@ function solve_cubic(a, b, c, d)
55225529
];
55235530
}
55245531
}
5532+
function solve_quartic(e, a, b, c, d)
5533+
{
5534+
if (is_strictly_equal(e, 0)) return solve_cubic(a, b, c, d);
5535+
a /= e; b /= e; c /= e; d /= e;
5536+
// v^2 + (-2 b^3 + 9 a b c - 27 c^2 - 27 a^2 d + 72 b d)v + (b^2 - 3 a c + 12 d)^3 = 0
5537+
var v, v1, v2, u, ur, D1, D2, p;
5538+
v = solve_quadratic(1, -2*pow(b, 3) + 9*a*b*c - 27*c*c - 27*a*a*d + 72*b*d, pow(b*b - 3*a*c + 12*d, 3));
5539+
if (!v) return false;
5540+
// u = \frac{a^2}{4} +\frac{-2b+v_1^{1/3}+v_2^{1/3}}{3}
5541+
v1 = v[0];
5542+
v2 = v[1] || v1;
5543+
u = a*a/4 + (-2*b + sign(v1)*pow(abs(v1), 1/3) + sign(v2)*pow(abs(v2), 1/3))/3;
5544+
if (0 >= u) return false;
5545+
ur = sqrt(u);
5546+
// x_{1,2} = -\tfrac{1}{4}a+\tfrac{1}{2}\sqrt{u}\pm\tfrac{1}{4}\sqrt{3a^2-8b-4u+\frac{-a^3+4ab-8c}{\sqrt{u}}}
5547+
// x_{3,4} = -\tfrac{1}{4}a-\tfrac{1}{2}\sqrt{u}\pm\tfrac{1}{4}\sqrt{3a^2-8b-4u-\frac{-a^3+4ab-8c}{\sqrt{u}}}
5548+
D1 = 3*a*a - 8*b - 4*u + (-pow(a, 3) + 4*a*b - 8*c)/ur;
5549+
D2 = 3*a*a - 8*b - 4*u - (-pow(a, 3) + 4*a*b - 8*c)/ur;
5550+
p = [];
5551+
if (0 <= D1)
5552+
{
5553+
if (is_strictly_equal(D1, 0))
5554+
{
5555+
p.push(ur/2 - a/4);
5556+
}
5557+
else
5558+
{
5559+
D1 = sqrt(D1)/4;
5560+
p.push(ur/2 - a/4 + D1);
5561+
p.push(ur/2 - a/4 - D1);
5562+
}
5563+
}
5564+
if (0 <= D2)
5565+
{
5566+
if (is_strictly_equal(D2, 0))
5567+
{
5568+
p.push(-ur/2 - a/4);
5569+
}
5570+
else
5571+
{
5572+
D2 = sqrt(D2)/4;
5573+
p.push(-ur/2 - a/4 + D2);
5574+
p.push(-ur/2 - a/4 - D2);
5575+
}
5576+
}
5577+
return p.length ? p : false;
5578+
}
55255579
function solve_linear_linear_system(a, b, c, k, l, m)
55265580
{
55275581
/*
@@ -5566,10 +5620,54 @@ function solve_linear_quadratic_system(m, n, k, a, b, c, d, e, f)
55665620
return [{x:-(k + n*((-m*D - F)/R))/m, y:(-m*D - F)/R},{x:-(k + n*((m*D - F)/R))/m, y:(m*D - F)/R}];
55675621
}
55685622
}
5623+
function solve_quadratic_quadratic_system(a1, b1, c1, d1, e1, f1, a2, b2, c2, d2, e2, f2)
5624+
{
5625+
/*
5626+
a1 x^2 + b1 y^2 + c1 xy + d1 x + e1 y + f1 = 0
5627+
a2 x^2 + b2 y^2 + c2 xy + d2 x + e2 y + f2 = 0
5628+
*/
5629+
var q, x, y, n, p, i, j;
5630+
q = quadratics2quartic(a1, b1, c1, d1, e1, f1, a2, b2, c2, d2, e2, f2);
5631+
x = solve_quartic(q[0], q[1], q[2], q[3], q[4]);
5632+
if (!x) return false;
5633+
p = new Array(8);
5634+
j = 0;
5635+
for (i=0,n=x.length; i<n; ++i)
5636+
{
5637+
y = solve_quadratic(b1, c1*x[i] + e1, x[i]*(a1*x[i] + d1) + f1);
5638+
if (y)
5639+
{
5640+
p[j++] = {x:x[i], y:y[0]};
5641+
if (1 < y.length) p[j++] = {x:x[i], y:y[1]};
5642+
}
5643+
}
5644+
p.length = j;
5645+
return p.length ? p : false;
5646+
}
55695647
function line2linear(p1, p2)
55705648
{
55715649
return [p2.y - p1.y, p1.x - p2.x, p2.x*p1.y - p1.x*p2.y];
55725650
}
5651+
function quadratics2quartic(a_1, b_1, c_1, d_1, e_1, f_1, a_2, b_2, c_2, d_2, e_2, f_2)
5652+
{
5653+
/*
5654+
Eliminate[{a_1x^2+b_1y^2+c_1xy+d_1x+e_1y+f_1 == 0, a_2x^2+b_2y^2+c_2xy+d_2x+e_2y+f_2 == 0}, y]
5655+
f_1 (2 a_1 b_2^2 x^2 - 2 a_2 b_1 b_2 x^2 - b_2 c_2 e_1 x - b_2 c_1 e_2 x + 2 b_1 c_2 e_2 x + b_1 c_2^2 x^2 - b_2 c_1 c_2 x^2 + 2 b_2^2 d_1 x - 2 b_1 b_2 d_2 x + b_1 e_2^2 - b_2 e_1 e_2 - 2 b_1 b_2 f_2) + b_2^2 f_1^2 = -2 a_2 b_2 c_1 e_1 x^3 + a_2 b_1 c_2 e_1 x^3 + a_1 b_2 c_2 e_1 x^3 + a_2 b_1 c_1 e_2 x^3 + a_1 b_2 c_1 e_2 x^3 - 2 a_1 b_1 c_2 e_2 x^3 - a_2 b_2 c_1^2 x^4 - a_1 b_1 c_2^2 x^4 + a_2 b_1 c_1 c_2 x^4 + a_1 b_2 c_1 c_2 x^4 - 2 a_1 b_2^2 d_1 x^3 + 2 a_2 b_1 b_2 d_1 x^3 - 2 a_2 b_1^2 d_2 x^3 + 2 a_1 b_1 b_2 d_2 x^3 - a_2 b_2 e_1^2 x^2 - a_1 b_1 e_2^2 x^2 + a_2 b_1 e_1 e_2 x^2 + a_1 b_2 e_1 e_2 x^2 - 2 a_2 b_1^2 f_2 x^2 + 2 a_1 b_1 b_2 f_2 x^2 - a_2^2 b_1^2 x^4 - a_1^2 b_2^2 x^4 + 2 a_1 a_2 b_1 b_2 x^4 + b_2 c_2 d_1 e_1 x^2 - 2 b_2 c_1 d_2 e_1 x^2 + b_1 c_2 d_2 e_1 x^2 + b_2 c_1 d_1 e_2 x^2 - 2 b_1 c_2 d_1 e_2 x^2 + b_1 c_1 d_2 e_2 x^2 - b_1 c_2^2 d_1 x^3 + b_2 c_1 c_2 d_1 x^3 - b_2 c_1^2 d_2 x^3 + b_1 c_1 c_2 d_2 x^3 - 2 b_2 c_1 e_1 f_2 x + b_1 c_2 e_1 f_2 x + b_1 c_1 e_2 f_2 x - b_2 c_1^2 f_2 x^2 + b_1 c_1 c_2 f_2 x^2 - b_2 d_2 e_1^2 x - b_1 d_1 e_2^2 x + b_2 d_1 e_1 e_2 x + b_1 d_2 e_1 e_2 x + 2 b_1 b_2 d_1 f_2 x - 2 b_1^2 d_2 f_2 x - b_2^2 d_1^2 x^2 - b_1^2 d_2^2 x^2 + 2 b_1 b_2 d_1 d_2 x^2 - b_2 e_1^2 f_2 + b_1 e_1 e_2 f_2 - b_1^2 f_2^2
5656+
*/
5657+
/*
5658+
https://live.sympy.org/
5659+
e = -2*a_2*b_2*c_1*e_1*x**3 + a_2*b_1*c_2*e_1*x**3 + a_1*b_2*c_2*e_1*x**3 + a_2*b_1*c_1*e_2*x**3 + a_1*b_2*c_1*e_2*x**3 - 2*a_1*b_1*c_2*e_2*x**3 - a_2*b_2*c_1**2*x**4 - a_1*b_1*c_2**2*x**4 + a_2*b_1*c_1*c_2*x**4 + a_1*b_2*c_1*c_2*x**4 - 2*a_1*b_2**2*d_1*x**3 + 2*a_2*b_1*b_2*d_1*x**3 - 2*a_2*b_1**2*d_2*x**3 + 2*a_1*b_1*b_2*d_2*x**3 - a_2*b_2*e_1**2*x**2 - a_1*b_1*e_2**2*x**2 + a_2*b_1*e_1*e_2*x**2 + a_1*b_2*e_1*e_2*x**2 - 2*a_2*b_1**2*f_2*x**2 + 2*a_1*b_1*b_2*f_2*x**2 - a_2**2*b_1**2*x**4 - a_1**2*b_2**2*x**4 + 2*a_1*a_2*b_1*b_2*x**4 + b_2*c_2*d_1*e_1*x**2 - 2*b_2*c_1*d_2*e_1*x**2 + b_1*c_2*d_2*e_1*x**2 + b_2*c_1*d_1*e_2*x**2 - 2*b_1*c_2*d_1*e_2*x**2 + b_1*c_1*d_2*e_2*x**2 - b_1*c_2**2*d_1*x**3 + b_2*c_1*c_2*d_1*x**3 - b_2*c_1**2*d_2*x**3 + b_1*c_1*c_2*d_2*x**3 - 2*b_2*c_1*e_1*f_2*x + b_1*c_2*e_1*f_2*x + b_1*c_1*e_2*f_2*x - b_2*c_1**2*f_2*x**2 + b_1*c_1*c_2*f_2*x**2 - b_2*d_2*e_1**2*x - b_1*d_1*e_2**2*x + b_2*d_1*e_1*e_2*x + b_1*d_2*e_1*e_2*x + 2*b_1*b_2*d_1*f_2*x - 2*b_1**2*d_2*f_2*x - b_2**2*d_1**2*x**2 - b_1**2*d_2**2*x**2 + 2*b_1*b_2*d_1*d_2*x**2 - b_2*e_1**2*f_2 + b_1*e_1*e_2*f_2 - b_1**2*f_2**2 - (f_1*(2*a_1*b_2**2*x**2 - 2*a_2*b_1*b_2*x**2 - b_2*c_2*e_1*x - b_2*c_1*e_2*x + 2*b_1*c_2*e_2*x + b_1*c_2**2*x**2 - b_2*c_1*c_2*x**2 + 2*b_2**2*d_1*x - 2*b_1*b_2*d_2*x + b_1*e_2**2 - b_2*e_1*e_2 - 2*b_1*b_2*f_2) + b_2**2*f_1**2)
5660+
collect(expand(e), x)
5661+
-b_1**2*f_2**2 + 2*b_1*b_2*f_1*f_2 + b_1*e_1*e_2*f_2 - b_1*e_2**2*f_1 - b_2**2*f_1**2 - b_2*e_1**2*f_2 + b_2*e_1*e_2*f_1 + x**4*(-a_1**2*b_2**2 + 2*a_1*a_2*b_1*b_2 - a_1*b_1*c_2**2 + a_1*b_2*c_1*c_2 - a_2**2*b_1**2 + a_2*b_1*c_1*c_2 - a_2*b_2*c_1**2) + x**3*(2*a_1*b_1*b_2*d_2 - 2*a_1*b_1*c_2*e_2 - 2*a_1*b_2**2*d_1 + a_1*b_2*c_1*e_2 + a_1*b_2*c_2*e_1 - 2*a_2*b_1**2*d_2 + 2*a_2*b_1*b_2*d_1 + a_2*b_1*c_1*e_2 + a_2*b_1*c_2*e_1 - 2*a_2*b_2*c_1*e_1 + b_1*c_1*c_2*d_2 - b_1*c_2**2*d_1 - b_2*c_1**2*d_2 + b_2*c_1*c_2*d_1) + x**2*(2*a_1*b_1*b_2*f_2 - a_1*b_1*e_2**2 - 2*a_1*b_2**2*f_1 + a_1*b_2*e_1*e_2 - 2*a_2*b_1**2*f_2 + 2*a_2*b_1*b_2*f_1 + a_2*b_1*e_1*e_2 - a_2*b_2*e_1**2 - b_1**2*d_2**2 + 2*b_1*b_2*d_1*d_2 + b_1*c_1*c_2*f_2 + b_1*c_1*d_2*e_2 - b_1*c_2**2*f_1 - 2*b_1*c_2*d_1*e_2 + b_1*c_2*d_2*e_1 - b_2**2*d_1**2 - b_2*c_1**2*f_2 + b_2*c_1*c_2*f_1 + b_2*c_1*d_1*e_2 - 2*b_2*c_1*d_2*e_1 + b_2*c_2*d_1*e_1) + x*(-2*b_1**2*d_2*f_2 + 2*b_1*b_2*d_1*f_2 + 2*b_1*b_2*d_2*f_1 + b_1*c_1*e_2*f_2 + b_1*c_2*e_1*f_2 - 2*b_1*c_2*e_2*f_1 - b_1*d_1*e_2**2 + b_1*d_2*e_1*e_2 - 2*b_2**2*d_1*f_1 - 2*b_2*c_1*e_1*f_2 + b_2*c_1*e_2*f_1 + b_2*c_2*e_1*f_1 + b_2*d_1*e_1*e_2 - b_2*d_2*e_1**2)
5662+
*/
5663+
return [
5664+
-pow(a_1,2)*pow(b_2,2) + 2*a_1*a_2*b_1*b_2 - a_1*b_1*pow(c_2,2) + a_1*b_2*c_1*c_2 - pow(a_2,2)*pow(b_1,2) + a_2*b_1*c_1*c_2 - a_2*b_2*pow(c_1,2),
5665+
2*a_1*b_1*b_2*d_2 - 2*a_1*b_1*c_2*e_2 - 2*a_1*pow(b_2,2)*d_1 + a_1*b_2*c_1*e_2 + a_1*b_2*c_2*e_1 - 2*a_2*pow(b_1,2)*d_2 + 2*a_2*b_1*b_2*d_1 + a_2*b_1*c_1*e_2 + a_2*b_1*c_2*e_1 - 2*a_2*b_2*c_1*e_1 + b_1*c_1*c_2*d_2 - b_1*pow(c_2,2)*d_1 - b_2*pow(c_1,2)*d_2 + b_2*c_1*c_2*d_1,
5666+
2*a_1*b_1*b_2*f_2 - a_1*b_1*pow(e_2,2) - 2*a_1*pow(b_2,2)*f_1 + a_1*b_2*e_1*e_2 - 2*a_2*pow(b_1,2)*f_2 + 2*a_2*b_1*b_2*f_1 + a_2*b_1*e_1*e_2 - a_2*b_2*pow(e_1,2) - pow(b_1,2)*d_2**2 + 2*b_1*b_2*d_1*d_2 + b_1*c_1*c_2*f_2 + b_1*c_1*d_2*e_2 - b_1*pow(c_2,2)*f_1 - 2*b_1*c_2*d_1*e_2 + b_1*c_2*d_2*e_1 - pow(b_2,2)*pow(d_1,2) - b_2*pow(c_1,2)*f_2 + b_2*c_1*c_2*f_1 + b_2*c_1*d_1*e_2 - 2*b_2*c_1*d_2*e_1 + b_2*c_2*d_1*e_1,
5667+
-2*pow(b_1,2)*d_2*f_2 + 2*b_1*b_2*d_1*f_2 + 2*b_1*b_2*d_2*f_1 + b_1*c_1*e_2*f_2 + b_1*c_2*e_1*f_2 - 2*b_1*c_2*e_2*f_1 - b_1*d_1*pow(e_2,2) + b_1*d_2*e_1*e_2 - 2*pow(b_2,2)*d_1*f_1 - 2*b_2*c_1*e_1*f_2 + b_2*c_1*e_2*f_1 + b_2*c_2*e_1*f_1 + b_2*d_1*e_1*e_2 - b_2*d_2*pow(e_1,2),
5668+
-pow(b_1,2)*pow(f_2,2) + 2*b_1*b_2*f_1*f_2 + b_1*e_1*e_2*f_2 - b_1*pow(e_2,2)*f_1 - pow(b_2,2)*pow(f_1,2) - b_2*pow(e_1,2)*f_2 + b_2*e_1*e_2*f_1
5669+
];
5670+
}
55735671
function circle2quadratic(center, radius)
55745672
{
55755673
var x0 = center.x, y0 = center.y;

src/Ellipse.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -238,12 +238,14 @@ var Ellipse = makeClass(EllipticArc2D, {
238238
}
239239
else if (Geometrize.Circle && (other instanceof Geometrize.Circle))
240240
{
241-
i = polyline_circle_intersection(self._lines, other.center, other.radius);
241+
//i = polyline_circle_intersection(self._lines, other.center, other.radius);
242+
i = ellipse_ellipse_intersection(self.center, self.radiusX, self.radiusY, self.cs, other.center, other.radius, other.radius, [1, 0]);
242243
return i ? i.map(Point2D) : false
243244
}
244245
else if (other instanceof Ellipse)
245246
{
246-
i = polyline_ellipse_intersection(self._lines, other.center, other.radiusX, other.radiusY, other.cs);
247+
//i = polyline_ellipse_intersection(self._lines, other.center, other.radiusX, other.radiusY, other.cs);
248+
i = ellipse_ellipse_intersection(self.center, self.radiusX, self.radiusY, self. cs, other.center, other.radiusX, other.radiusY, other.cs);
247249
return i ? i.map(Point2D) : false
248250
}
249251
else if (other instanceof Object2D)

src/utils.js

+96
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,11 @@ function circle_circle_intersection(c1, r1, c2, r2)
388388
;
389389
return is_strictly_equal(h, 0) ? [{x:px, y:py}] : [{x:px + h*dy, y:py - h*dx}, {x:px - h*dy, y:py + h*dx}];
390390
}
391+
function ellipse_ellipse_intersection(c1, rx1, ry1, cs1, c2, rx2, ry2, cs2)
392+
{
393+
var q1 = ellipse2quadratic(c1, rx1, ry1, cs1), q2 = ellipse2quadratic(c2, rx2, ry2, cs2);
394+
return solve_quadratic_quadratic_system(q1[0], q1[1], q1[2], q1[3], q1[4], q1[5], q2[0], q2[1], q2[2], q2[3], q2[4], q2[5]);
395+
}
391396
function polyline_line_intersection(polyline_points, p1, p2)
392397
{
393398
var i = [], j, p, n = polyline_points.length-1;
@@ -637,6 +642,53 @@ function solve_cubic(a, b, c, d)
637642
];
638643
}
639644
}
645+
function solve_quartic(e, a, b, c, d)
646+
{
647+
if (is_strictly_equal(e, 0)) return solve_cubic(a, b, c, d);
648+
a /= e; b /= e; c /= e; d /= e;
649+
// v^2 + (-2 b^3 + 9 a b c - 27 c^2 - 27 a^2 d + 72 b d)v + (b^2 - 3 a c + 12 d)^3 = 0
650+
var v, v1, v2, u, ur, D1, D2, p;
651+
v = solve_quadratic(1, -2*pow(b, 3) + 9*a*b*c - 27*c*c - 27*a*a*d + 72*b*d, pow(b*b - 3*a*c + 12*d, 3));
652+
if (!v) return false;
653+
// u = \frac{a^2}{4} +\frac{-2b+v_1^{1/3}+v_2^{1/3}}{3}
654+
v1 = v[0];
655+
v2 = v[1] || v1;
656+
u = a*a/4 + (-2*b + sign(v1)*pow(abs(v1), 1/3) + sign(v2)*pow(abs(v2), 1/3))/3;
657+
if (0 >= u) return false;
658+
ur = sqrt(u);
659+
// x_{1,2} = -\tfrac{1}{4}a+\tfrac{1}{2}\sqrt{u}\pm\tfrac{1}{4}\sqrt{3a^2-8b-4u+\frac{-a^3+4ab-8c}{\sqrt{u}}}
660+
// x_{3,4} = -\tfrac{1}{4}a-\tfrac{1}{2}\sqrt{u}\pm\tfrac{1}{4}\sqrt{3a^2-8b-4u-\frac{-a^3+4ab-8c}{\sqrt{u}}}
661+
D1 = 3*a*a - 8*b - 4*u + (-pow(a, 3) + 4*a*b - 8*c)/ur;
662+
D2 = 3*a*a - 8*b - 4*u - (-pow(a, 3) + 4*a*b - 8*c)/ur;
663+
p = [];
664+
if (0 <= D1)
665+
{
666+
if (is_strictly_equal(D1, 0))
667+
{
668+
p.push(ur/2 - a/4);
669+
}
670+
else
671+
{
672+
D1 = sqrt(D1)/4;
673+
p.push(ur/2 - a/4 + D1);
674+
p.push(ur/2 - a/4 - D1);
675+
}
676+
}
677+
if (0 <= D2)
678+
{
679+
if (is_strictly_equal(D2, 0))
680+
{
681+
p.push(-ur/2 - a/4);
682+
}
683+
else
684+
{
685+
D2 = sqrt(D2)/4;
686+
p.push(-ur/2 - a/4 + D2);
687+
p.push(-ur/2 - a/4 - D2);
688+
}
689+
}
690+
return p.length ? p : false;
691+
}
640692
function solve_linear_linear_system(a, b, c, k, l, m)
641693
{
642694
/*
@@ -681,10 +733,54 @@ function solve_linear_quadratic_system(m, n, k, a, b, c, d, e, f)
681733
return [{x:-(k + n*((-m*D - F)/R))/m, y:(-m*D - F)/R},{x:-(k + n*((m*D - F)/R))/m, y:(m*D - F)/R}];
682734
}
683735
}
736+
function solve_quadratic_quadratic_system(a1, b1, c1, d1, e1, f1, a2, b2, c2, d2, e2, f2)
737+
{
738+
/*
739+
a1 x^2 + b1 y^2 + c1 xy + d1 x + e1 y + f1 = 0
740+
a2 x^2 + b2 y^2 + c2 xy + d2 x + e2 y + f2 = 0
741+
*/
742+
var q, x, y, n, p, i, j;
743+
q = quadratics2quartic(a1, b1, c1, d1, e1, f1, a2, b2, c2, d2, e2, f2);
744+
x = solve_quartic(q[0], q[1], q[2], q[3], q[4]);
745+
if (!x) return false;
746+
p = new Array(8);
747+
j = 0;
748+
for (i=0,n=x.length; i<n; ++i)
749+
{
750+
y = solve_quadratic(b1, c1*x[i] + e1, x[i]*(a1*x[i] + d1) + f1);
751+
if (y)
752+
{
753+
p[j++] = {x:x[i], y:y[0]};
754+
if (1 < y.length) p[j++] = {x:x[i], y:y[1]};
755+
}
756+
}
757+
p.length = j;
758+
return p.length ? p : false;
759+
}
684760
function line2linear(p1, p2)
685761
{
686762
return [p2.y - p1.y, p1.x - p2.x, p2.x*p1.y - p1.x*p2.y];
687763
}
764+
function quadratics2quartic(a_1, b_1, c_1, d_1, e_1, f_1, a_2, b_2, c_2, d_2, e_2, f_2)
765+
{
766+
/*
767+
Eliminate[{a_1x^2+b_1y^2+c_1xy+d_1x+e_1y+f_1 == 0, a_2x^2+b_2y^2+c_2xy+d_2x+e_2y+f_2 == 0}, y]
768+
f_1 (2 a_1 b_2^2 x^2 - 2 a_2 b_1 b_2 x^2 - b_2 c_2 e_1 x - b_2 c_1 e_2 x + 2 b_1 c_2 e_2 x + b_1 c_2^2 x^2 - b_2 c_1 c_2 x^2 + 2 b_2^2 d_1 x - 2 b_1 b_2 d_2 x + b_1 e_2^2 - b_2 e_1 e_2 - 2 b_1 b_2 f_2) + b_2^2 f_1^2 = -2 a_2 b_2 c_1 e_1 x^3 + a_2 b_1 c_2 e_1 x^3 + a_1 b_2 c_2 e_1 x^3 + a_2 b_1 c_1 e_2 x^3 + a_1 b_2 c_1 e_2 x^3 - 2 a_1 b_1 c_2 e_2 x^3 - a_2 b_2 c_1^2 x^4 - a_1 b_1 c_2^2 x^4 + a_2 b_1 c_1 c_2 x^4 + a_1 b_2 c_1 c_2 x^4 - 2 a_1 b_2^2 d_1 x^3 + 2 a_2 b_1 b_2 d_1 x^3 - 2 a_2 b_1^2 d_2 x^3 + 2 a_1 b_1 b_2 d_2 x^3 - a_2 b_2 e_1^2 x^2 - a_1 b_1 e_2^2 x^2 + a_2 b_1 e_1 e_2 x^2 + a_1 b_2 e_1 e_2 x^2 - 2 a_2 b_1^2 f_2 x^2 + 2 a_1 b_1 b_2 f_2 x^2 - a_2^2 b_1^2 x^4 - a_1^2 b_2^2 x^4 + 2 a_1 a_2 b_1 b_2 x^4 + b_2 c_2 d_1 e_1 x^2 - 2 b_2 c_1 d_2 e_1 x^2 + b_1 c_2 d_2 e_1 x^2 + b_2 c_1 d_1 e_2 x^2 - 2 b_1 c_2 d_1 e_2 x^2 + b_1 c_1 d_2 e_2 x^2 - b_1 c_2^2 d_1 x^3 + b_2 c_1 c_2 d_1 x^3 - b_2 c_1^2 d_2 x^3 + b_1 c_1 c_2 d_2 x^3 - 2 b_2 c_1 e_1 f_2 x + b_1 c_2 e_1 f_2 x + b_1 c_1 e_2 f_2 x - b_2 c_1^2 f_2 x^2 + b_1 c_1 c_2 f_2 x^2 - b_2 d_2 e_1^2 x - b_1 d_1 e_2^2 x + b_2 d_1 e_1 e_2 x + b_1 d_2 e_1 e_2 x + 2 b_1 b_2 d_1 f_2 x - 2 b_1^2 d_2 f_2 x - b_2^2 d_1^2 x^2 - b_1^2 d_2^2 x^2 + 2 b_1 b_2 d_1 d_2 x^2 - b_2 e_1^2 f_2 + b_1 e_1 e_2 f_2 - b_1^2 f_2^2
769+
*/
770+
/*
771+
https://live.sympy.org/
772+
e = -2*a_2*b_2*c_1*e_1*x**3 + a_2*b_1*c_2*e_1*x**3 + a_1*b_2*c_2*e_1*x**3 + a_2*b_1*c_1*e_2*x**3 + a_1*b_2*c_1*e_2*x**3 - 2*a_1*b_1*c_2*e_2*x**3 - a_2*b_2*c_1**2*x**4 - a_1*b_1*c_2**2*x**4 + a_2*b_1*c_1*c_2*x**4 + a_1*b_2*c_1*c_2*x**4 - 2*a_1*b_2**2*d_1*x**3 + 2*a_2*b_1*b_2*d_1*x**3 - 2*a_2*b_1**2*d_2*x**3 + 2*a_1*b_1*b_2*d_2*x**3 - a_2*b_2*e_1**2*x**2 - a_1*b_1*e_2**2*x**2 + a_2*b_1*e_1*e_2*x**2 + a_1*b_2*e_1*e_2*x**2 - 2*a_2*b_1**2*f_2*x**2 + 2*a_1*b_1*b_2*f_2*x**2 - a_2**2*b_1**2*x**4 - a_1**2*b_2**2*x**4 + 2*a_1*a_2*b_1*b_2*x**4 + b_2*c_2*d_1*e_1*x**2 - 2*b_2*c_1*d_2*e_1*x**2 + b_1*c_2*d_2*e_1*x**2 + b_2*c_1*d_1*e_2*x**2 - 2*b_1*c_2*d_1*e_2*x**2 + b_1*c_1*d_2*e_2*x**2 - b_1*c_2**2*d_1*x**3 + b_2*c_1*c_2*d_1*x**3 - b_2*c_1**2*d_2*x**3 + b_1*c_1*c_2*d_2*x**3 - 2*b_2*c_1*e_1*f_2*x + b_1*c_2*e_1*f_2*x + b_1*c_1*e_2*f_2*x - b_2*c_1**2*f_2*x**2 + b_1*c_1*c_2*f_2*x**2 - b_2*d_2*e_1**2*x - b_1*d_1*e_2**2*x + b_2*d_1*e_1*e_2*x + b_1*d_2*e_1*e_2*x + 2*b_1*b_2*d_1*f_2*x - 2*b_1**2*d_2*f_2*x - b_2**2*d_1**2*x**2 - b_1**2*d_2**2*x**2 + 2*b_1*b_2*d_1*d_2*x**2 - b_2*e_1**2*f_2 + b_1*e_1*e_2*f_2 - b_1**2*f_2**2 - (f_1*(2*a_1*b_2**2*x**2 - 2*a_2*b_1*b_2*x**2 - b_2*c_2*e_1*x - b_2*c_1*e_2*x + 2*b_1*c_2*e_2*x + b_1*c_2**2*x**2 - b_2*c_1*c_2*x**2 + 2*b_2**2*d_1*x - 2*b_1*b_2*d_2*x + b_1*e_2**2 - b_2*e_1*e_2 - 2*b_1*b_2*f_2) + b_2**2*f_1**2)
773+
collect(expand(e), x)
774+
-b_1**2*f_2**2 + 2*b_1*b_2*f_1*f_2 + b_1*e_1*e_2*f_2 - b_1*e_2**2*f_1 - b_2**2*f_1**2 - b_2*e_1**2*f_2 + b_2*e_1*e_2*f_1 + x**4*(-a_1**2*b_2**2 + 2*a_1*a_2*b_1*b_2 - a_1*b_1*c_2**2 + a_1*b_2*c_1*c_2 - a_2**2*b_1**2 + a_2*b_1*c_1*c_2 - a_2*b_2*c_1**2) + x**3*(2*a_1*b_1*b_2*d_2 - 2*a_1*b_1*c_2*e_2 - 2*a_1*b_2**2*d_1 + a_1*b_2*c_1*e_2 + a_1*b_2*c_2*e_1 - 2*a_2*b_1**2*d_2 + 2*a_2*b_1*b_2*d_1 + a_2*b_1*c_1*e_2 + a_2*b_1*c_2*e_1 - 2*a_2*b_2*c_1*e_1 + b_1*c_1*c_2*d_2 - b_1*c_2**2*d_1 - b_2*c_1**2*d_2 + b_2*c_1*c_2*d_1) + x**2*(2*a_1*b_1*b_2*f_2 - a_1*b_1*e_2**2 - 2*a_1*b_2**2*f_1 + a_1*b_2*e_1*e_2 - 2*a_2*b_1**2*f_2 + 2*a_2*b_1*b_2*f_1 + a_2*b_1*e_1*e_2 - a_2*b_2*e_1**2 - b_1**2*d_2**2 + 2*b_1*b_2*d_1*d_2 + b_1*c_1*c_2*f_2 + b_1*c_1*d_2*e_2 - b_1*c_2**2*f_1 - 2*b_1*c_2*d_1*e_2 + b_1*c_2*d_2*e_1 - b_2**2*d_1**2 - b_2*c_1**2*f_2 + b_2*c_1*c_2*f_1 + b_2*c_1*d_1*e_2 - 2*b_2*c_1*d_2*e_1 + b_2*c_2*d_1*e_1) + x*(-2*b_1**2*d_2*f_2 + 2*b_1*b_2*d_1*f_2 + 2*b_1*b_2*d_2*f_1 + b_1*c_1*e_2*f_2 + b_1*c_2*e_1*f_2 - 2*b_1*c_2*e_2*f_1 - b_1*d_1*e_2**2 + b_1*d_2*e_1*e_2 - 2*b_2**2*d_1*f_1 - 2*b_2*c_1*e_1*f_2 + b_2*c_1*e_2*f_1 + b_2*c_2*e_1*f_1 + b_2*d_1*e_1*e_2 - b_2*d_2*e_1**2)
775+
*/
776+
return [
777+
-pow(a_1,2)*pow(b_2,2) + 2*a_1*a_2*b_1*b_2 - a_1*b_1*pow(c_2,2) + a_1*b_2*c_1*c_2 - pow(a_2,2)*pow(b_1,2) + a_2*b_1*c_1*c_2 - a_2*b_2*pow(c_1,2),
778+
2*a_1*b_1*b_2*d_2 - 2*a_1*b_1*c_2*e_2 - 2*a_1*pow(b_2,2)*d_1 + a_1*b_2*c_1*e_2 + a_1*b_2*c_2*e_1 - 2*a_2*pow(b_1,2)*d_2 + 2*a_2*b_1*b_2*d_1 + a_2*b_1*c_1*e_2 + a_2*b_1*c_2*e_1 - 2*a_2*b_2*c_1*e_1 + b_1*c_1*c_2*d_2 - b_1*pow(c_2,2)*d_1 - b_2*pow(c_1,2)*d_2 + b_2*c_1*c_2*d_1,
779+
2*a_1*b_1*b_2*f_2 - a_1*b_1*pow(e_2,2) - 2*a_1*pow(b_2,2)*f_1 + a_1*b_2*e_1*e_2 - 2*a_2*pow(b_1,2)*f_2 + 2*a_2*b_1*b_2*f_1 + a_2*b_1*e_1*e_2 - a_2*b_2*pow(e_1,2) - pow(b_1,2)*d_2**2 + 2*b_1*b_2*d_1*d_2 + b_1*c_1*c_2*f_2 + b_1*c_1*d_2*e_2 - b_1*pow(c_2,2)*f_1 - 2*b_1*c_2*d_1*e_2 + b_1*c_2*d_2*e_1 - pow(b_2,2)*pow(d_1,2) - b_2*pow(c_1,2)*f_2 + b_2*c_1*c_2*f_1 + b_2*c_1*d_1*e_2 - 2*b_2*c_1*d_2*e_1 + b_2*c_2*d_1*e_1,
780+
-2*pow(b_1,2)*d_2*f_2 + 2*b_1*b_2*d_1*f_2 + 2*b_1*b_2*d_2*f_1 + b_1*c_1*e_2*f_2 + b_1*c_2*e_1*f_2 - 2*b_1*c_2*e_2*f_1 - b_1*d_1*pow(e_2,2) + b_1*d_2*e_1*e_2 - 2*pow(b_2,2)*d_1*f_1 - 2*b_2*c_1*e_1*f_2 + b_2*c_1*e_2*f_1 + b_2*c_2*e_1*f_1 + b_2*d_1*e_1*e_2 - b_2*d_2*pow(e_1,2),
781+
-pow(b_1,2)*pow(f_2,2) + 2*b_1*b_2*f_1*f_2 + b_1*e_1*e_2*f_2 - b_1*pow(e_2,2)*f_1 - pow(b_2,2)*pow(f_1,2) - b_2*pow(e_1,2)*f_2 + b_2*e_1*e_2*f_1
782+
];
783+
}
688784
function circle2quadratic(center, radius)
689785
{
690786
var x0 = center.x, y0 = center.y;

0 commit comments

Comments
 (0)