// -----------------------------------------------------------------------
//
// Original Triangle code by Jonathan Richard Shewchuk, http://www.cs.cmu.edu/~quake/triangle.html
// Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/
//
// -----------------------------------------------------------------------
namespace UnityEngine.U2D.Animation.TriangleNet
{
using System;
using Animation.TriangleNet.Geometry;
using Animation.TriangleNet.Tools;
///
/// Adaptive exact arithmetic geometric predicates.
///
///
/// The adaptive exact arithmetic geometric predicates implemented herein are described in
/// detail in the paper "Adaptive Precision Floating-Point Arithmetic and Fast Robust
/// Geometric Predicates." by Jonathan Richard Shewchuk, see
/// http://www.cs.cmu.edu/~quake/robust.html
///
/// The macros of the original C code were automatically expanded using the Visual Studio
/// command prompt with the command "CL /P /C EXACT.C", see
/// http://msdn.microsoft.com/en-us/library/8z9z0bx6.aspx
///
internal class RobustPredicates : IPredicates
{
#region Default predicates instance (Singleton)
private static readonly object creationLock = new object();
private static RobustPredicates _default;
///
/// Gets the default configuration instance.
///
internal static RobustPredicates Default
{
get
{
if (_default == null)
{
lock (creationLock)
{
if (_default == null)
{
_default = new RobustPredicates();
}
}
}
return _default;
}
}
#endregion
#region Static initialization
private static double epsilon, splitter, resulterrbound;
private static double ccwerrboundA, ccwerrboundB, ccwerrboundC;
private static double iccerrboundA, iccerrboundB, iccerrboundC;
//private static double o3derrboundA, o3derrboundB, o3derrboundC;
///
/// Initialize the variables used for exact arithmetic.
///
///
/// 'epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in
/// floating-point arithmetic. 'epsilon' bounds the relative roundoff
/// error. It is used for floating-point error analysis.
///
/// 'splitter' is used to split floating-point numbers into two half-
/// length significands for exact multiplication.
///
/// I imagine that a highly optimizing compiler might be too smart for its
/// own good, and somehow cause this routine to fail, if it pretends that
/// floating-point arithmetic is too much like double arithmetic.
///
/// Don't change this routine unless you fully understand it.
///
static RobustPredicates()
{
double half;
double check, lastcheck;
bool every_other;
every_other = true;
half = 0.5;
epsilon = 1.0;
splitter = 1.0;
check = 1.0;
// Repeatedly divide 'epsilon' by two until it is too small to add to
// one without causing roundoff. (Also check if the sum is equal to
// the previous sum, for machines that round up instead of using exact
// rounding. Not that these routines will work on such machines.)
do
{
lastcheck = check;
epsilon *= half;
if (every_other)
{
splitter *= 2.0;
}
every_other = !every_other;
check = 1.0 + epsilon;
}
while ((check != 1.0) && (check != lastcheck));
splitter += 1.0;
// Error bounds for orientation and incircle tests.
resulterrbound = (3.0 + 8.0 * epsilon) * epsilon;
ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon;
ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon;
ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon;
iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon;
iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon;
iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon;
//o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon;
//o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon;
//o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon;
}
#endregion
public RobustPredicates()
{
AllocateWorkspace();
}
///
/// Check, if the three points appear in counterclockwise order. The result is
/// also a rough approximation of twice the signed area of the triangle defined
/// by the three points.
///
/// Point a.
/// Point b.
/// Point c.
/// Return a positive value if the points pa, pb, and pc occur in
/// counterclockwise order; a negative value if they occur in clockwise order;
/// and zero if they are collinear.
public double CounterClockwise(Point pa, Point pb, Point pc)
{
double detleft, detright, det;
double detsum, errbound;
Statistic.CounterClockwiseCount++;
detleft = (pa.x - pc.x) * (pb.y - pc.y);
detright = (pa.y - pc.y) * (pb.x - pc.x);
det = detleft - detright;
if (Behavior.NoExact)
{
return det;
}
if (detleft > 0.0)
{
if (detright <= 0.0)
{
return det;
}
else
{
detsum = detleft + detright;
}
}
else if (detleft < 0.0)
{
if (detright >= 0.0)
{
return det;
}
else
{
detsum = -detleft - detright;
}
}
else
{
return det;
}
errbound = ccwerrboundA * detsum;
if ((det >= errbound) || (-det >= errbound))
{
return det;
}
Statistic.CounterClockwiseAdaptCount++;
return CounterClockwiseAdapt(pa, pb, pc, detsum);
}
///
/// Check if the point pd lies inside the circle passing through pa, pb, and pc. The
/// points pa, pb, and pc must be in counterclockwise order, or the sign of the result
/// will be reversed.
///
/// Point a.
/// Point b.
/// Point c.
/// Point d.
/// Return a positive value if the point pd lies inside the circle passing through
/// pa, pb, and pc; a negative value if it lies outside; and zero if the four points
/// are cocircular.
public double InCircle(Point pa, Point pb, Point pc, Point pd)
{
double adx, bdx, cdx, ady, bdy, cdy;
double bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
double alift, blift, clift;
double det;
double permanent, errbound;
Statistic.InCircleCount++;
adx = pa.x - pd.x;
bdx = pb.x - pd.x;
cdx = pc.x - pd.x;
ady = pa.y - pd.y;
bdy = pb.y - pd.y;
cdy = pc.y - pd.y;
bdxcdy = bdx * cdy;
cdxbdy = cdx * bdy;
alift = adx * adx + ady * ady;
cdxady = cdx * ady;
adxcdy = adx * cdy;
blift = bdx * bdx + bdy * bdy;
adxbdy = adx * bdy;
bdxady = bdx * ady;
clift = cdx * cdx + cdy * cdy;
det = alift * (bdxcdy - cdxbdy)
+ blift * (cdxady - adxcdy)
+ clift * (adxbdy - bdxady);
if (Behavior.NoExact)
{
return det;
}
permanent = (Math.Abs(bdxcdy) + Math.Abs(cdxbdy)) * alift
+ (Math.Abs(cdxady) + Math.Abs(adxcdy)) * blift
+ (Math.Abs(adxbdy) + Math.Abs(bdxady)) * clift;
errbound = iccerrboundA * permanent;
if ((det > errbound) || (-det > errbound))
{
return det;
}
Statistic.InCircleAdaptCount++;
return InCircleAdapt(pa, pb, pc, pd, permanent);
}
///
/// Return a positive value if the point pd is incompatible with the circle
/// or plane passing through pa, pb, and pc (meaning that pd is inside the
/// circle or below the plane); a negative value if it is compatible; and
/// zero if the four points are cocircular/coplanar. The points pa, pb, and
/// pc must be in counterclockwise order, or the sign of the result will be
/// reversed.
///
/// Point a.
/// Point b.
/// Point c.
/// Point d.
/// Return a positive value if the point pd lies inside the circle passing through
/// pa, pb, and pc; a negative value if it lies outside; and zero if the four points
/// are cocircular.
public double NonRegular(Point pa, Point pb, Point pc, Point pd)
{
return InCircle(pa, pb, pc, pd);
}
///
/// Find the circumcenter of a triangle.
///
/// Triangle point.
/// Triangle point.
/// Triangle point.
/// Relative coordinate of new location.
/// Relative coordinate of new location.
/// Off-center constant.
/// Coordinates of the circumcenter (or off-center)
public Point FindCircumcenter(Point org, Point dest, Point apex,
ref double xi, ref double eta, double offconstant)
{
double xdo, ydo, xao, yao;
double dodist, aodist, dadist;
double denominator;
double dx, dy, dxoff, dyoff;
Statistic.CircumcenterCount++;
// Compute the circumcenter of the triangle.
xdo = dest.x - org.x;
ydo = dest.y - org.y;
xao = apex.x - org.x;
yao = apex.y - org.y;
dodist = xdo * xdo + ydo * ydo;
aodist = xao * xao + yao * yao;
dadist = (dest.x - apex.x) * (dest.x - apex.x) +
(dest.y - apex.y) * (dest.y - apex.y);
if (Behavior.NoExact)
{
denominator = 0.5 / (xdo * yao - xao * ydo);
}
else
{
// Use the counterclockwise() routine to ensure a positive (and
// reasonably accurate) result, avoiding any possibility of
// division by zero.
denominator = 0.5 / CounterClockwise(dest, apex, org);
// Don't count the above as an orientation test.
Statistic.CounterClockwiseCount--;
}
dx = (yao * dodist - ydo * aodist) * denominator;
dy = (xdo * aodist - xao * dodist) * denominator;
// Find the (squared) length of the triangle's shortest edge. This
// serves as a conservative estimate of the insertion radius of the
// circumcenter's parent. The estimate is used to ensure that
// the algorithm terminates even if very small angles appear in
// the input PSLG.
if ((dodist < aodist) && (dodist < dadist))
{
if (offconstant > 0.0)
{
// Find the position of the off-center, as described by Alper Ungor.
dxoff = 0.5 * xdo - offconstant * ydo;
dyoff = 0.5 * ydo + offconstant * xdo;
// If the off-center is closer to the origin than the
// circumcenter, use the off-center instead.
if (dxoff * dxoff + dyoff * dyoff < dx * dx + dy * dy)
{
dx = dxoff;
dy = dyoff;
}
}
}
else if (aodist < dadist)
{
if (offconstant > 0.0)
{
dxoff = 0.5 * xao + offconstant * yao;
dyoff = 0.5 * yao - offconstant * xao;
// If the off-center is closer to the origin than the
// circumcenter, use the off-center instead.
if (dxoff * dxoff + dyoff * dyoff < dx * dx + dy * dy)
{
dx = dxoff;
dy = dyoff;
}
}
}
else
{
if (offconstant > 0.0)
{
dxoff = 0.5 * (apex.x - dest.x) - offconstant * (apex.y - dest.y);
dyoff = 0.5 * (apex.y - dest.y) + offconstant * (apex.x - dest.x);
// If the off-center is closer to the destination than the
// circumcenter, use the off-center instead.
if (dxoff * dxoff + dyoff * dyoff <
(dx - xdo) * (dx - xdo) + (dy - ydo) * (dy - ydo))
{
dx = xdo + dxoff;
dy = ydo + dyoff;
}
}
}
// To interpolate vertex attributes for the new vertex inserted at
// the circumcenter, define a coordinate system with a xi-axis,
// directed from the triangle's origin to its destination, and
// an eta-axis, directed from its origin to its apex.
// Calculate the xi and eta coordinates of the circumcenter.
xi = (yao * dx - xao * dy) * (2.0 * denominator);
eta = (xdo * dy - ydo * dx) * (2.0 * denominator);
return new Point(org.x + dx, org.y + dy);
}
///
/// Find the circumcenter of a triangle.
///
/// Triangle point.
/// Triangle point.
/// Triangle point.
/// Relative coordinate of new location.
/// Relative coordinate of new location.
/// Coordinates of the circumcenter
///
/// The result is returned both in terms of x-y coordinates and xi-eta
/// (barycentric) coordinates. The xi-eta coordinate system is defined in
/// terms of the triangle: the origin of the triangle is the origin of the
/// coordinate system; the destination of the triangle is one unit along the
/// xi axis; and the apex of the triangle is one unit along the eta axis.
/// This procedure also returns the square of the length of the triangle's
/// shortest edge.
///
public Point FindCircumcenter(Point org, Point dest, Point apex,
ref double xi, ref double eta)
{
double xdo, ydo, xao, yao;
double dodist, aodist;
double denominator;
double dx, dy;
Statistic.CircumcenterCount++;
// Compute the circumcenter of the triangle.
xdo = dest.x - org.x;
ydo = dest.y - org.y;
xao = apex.x - org.x;
yao = apex.y - org.y;
dodist = xdo * xdo + ydo * ydo;
aodist = xao * xao + yao * yao;
if (Behavior.NoExact)
{
denominator = 0.5 / (xdo * yao - xao * ydo);
}
else
{
// Use the counterclockwise() routine to ensure a positive (and
// reasonably accurate) result, avoiding any possibility of
// division by zero.
denominator = 0.5 / CounterClockwise(dest, apex, org);
// Don't count the above as an orientation test.
Statistic.CounterClockwiseCount--;
}
dx = (yao * dodist - ydo * aodist) * denominator;
dy = (xdo * aodist - xao * dodist) * denominator;
// To interpolate vertex attributes for the new vertex inserted at
// the circumcenter, define a coordinate system with a xi-axis,
// directed from the triangle's origin to its destination, and
// an eta-axis, directed from its origin to its apex.
// Calculate the xi and eta coordinates of the circumcenter.
xi = (yao * dx - xao * dy) * (2.0 * denominator);
eta = (xdo * dy - ydo * dx) * (2.0 * denominator);
return new Point(org.x + dx, org.y + dy);
}
#region Exact arithmetics
///
/// Sum two expansions, eliminating zero components from the output expansion.
///
///
///
///
///
///
///
///
/// Sets h = e + f. See the Robust Predicates paper for details.
///
/// If round-to-even is used (as with IEEE 754), maintains the strongly nonoverlapping
/// property. (That is, if e is strongly nonoverlapping, h will be also.) Does NOT
/// maintain the nonoverlapping or nonadjacent properties.
///
private int FastExpansionSumZeroElim(int elen, double[] e, int flen, double[] f, double[] h)
{
double Q;
double Qnew;
double hh;
double bvirt;
double avirt, bround, around;
int eindex, findex, hindex;
double enow, fnow;
enow = e[0];
fnow = f[0];
eindex = findex = 0;
if ((fnow > enow) == (fnow > -enow))
{
Q = enow;
enow = e[++eindex];
}
else
{
Q = fnow;
fnow = f[++findex];
}
hindex = 0;
if ((eindex < elen) && (findex < flen))
{
if ((fnow > enow) == (fnow > -enow))
{
Qnew = (double)(enow + Q); bvirt = Qnew - enow; hh = Q - bvirt;
enow = e[++eindex];
}
else
{
Qnew = (double)(fnow + Q); bvirt = Qnew - fnow; hh = Q - bvirt;
fnow = f[++findex];
}
Q = Qnew;
if (hh != 0.0)
{
h[hindex++] = hh;
}
while ((eindex < elen) && (findex < flen))
{
if ((fnow > enow) == (fnow > -enow))
{
Qnew = (double)(Q + enow);
bvirt = (double)(Qnew - Q);
avirt = Qnew - bvirt;
bround = enow - bvirt;
around = Q - avirt;
hh = around + bround;
enow = e[++eindex];
}
else
{
Qnew = (double)(Q + fnow);
bvirt = (double)(Qnew - Q);
avirt = Qnew - bvirt;
bround = fnow - bvirt;
around = Q - avirt;
hh = around + bround;
fnow = f[++findex];
}
Q = Qnew;
if (hh != 0.0)
{
h[hindex++] = hh;
}
}
}
while (eindex < elen)
{
Qnew = (double)(Q + enow);
bvirt = (double)(Qnew - Q);
avirt = Qnew - bvirt;
bround = enow - bvirt;
around = Q - avirt;
hh = around + bround;
enow = e[++eindex];
Q = Qnew;
if (hh != 0.0)
{
h[hindex++] = hh;
}
}
while (findex < flen)
{
Qnew = (double)(Q + fnow);
bvirt = (double)(Qnew - Q);
avirt = Qnew - bvirt;
bround = fnow - bvirt;
around = Q - avirt;
hh = around + bround;
fnow = f[++findex];
Q = Qnew;
if (hh != 0.0)
{
h[hindex++] = hh;
}
}
if ((Q != 0.0) || (hindex == 0))
{
h[hindex++] = Q;
}
return hindex;
}
///
/// Multiply an expansion by a scalar, eliminating zero components from the output expansion.
///
///
///
///
///
///
///
/// Sets h = be. See my Robust Predicates paper for details.
///
/// Maintains the nonoverlapping property. If round-to-even is used (as with IEEE 754),
/// maintains the strongly nonoverlapping and nonadjacent properties as well. (That is,
/// if e has one of these properties, so will h.)
///
private int ScaleExpansionZeroElim(int elen, double[] e, double b, double[] h)
{
double Q, sum;
double hh;
double product1;
double product0;
int eindex, hindex;
double enow;
double bvirt;
double avirt, bround, around;
double c;
double abig;
double ahi, alo, bhi, blo;
double err1, err2, err3;
c = (double)(splitter * b); abig = (double)(c - b); bhi = c - abig; blo = b - bhi;
Q = (double)(e[0] * b); c = (double)(splitter * e[0]); abig = (double)(c - e[0]); ahi = c - abig; alo = e[0] - ahi; err1 = Q - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); hh = (alo * blo) - err3;
hindex = 0;
if (hh != 0)
{
h[hindex++] = hh;
}
for (eindex = 1; eindex < elen; eindex++)
{
enow = e[eindex];
product1 = (double)(enow * b); c = (double)(splitter * enow); abig = (double)(c - enow); ahi = c - abig; alo = enow - ahi; err1 = product1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); product0 = (alo * blo) - err3;
sum = (double)(Q + product0); bvirt = (double)(sum - Q); avirt = sum - bvirt; bround = product0 - bvirt; around = Q - avirt; hh = around + bround;
if (hh != 0)
{
h[hindex++] = hh;
}
Q = (double)(product1 + sum); bvirt = Q - product1; hh = sum - bvirt;
if (hh != 0)
{
h[hindex++] = hh;
}
}
if ((Q != 0.0) || (hindex == 0))
{
h[hindex++] = Q;
}
return hindex;
}
///
/// Produce a one-word estimate of an expansion's value.
///
///
///
///
private double Estimate(int elen, double[] e)
{
double Q;
int eindex;
Q = e[0];
for (eindex = 1; eindex < elen; eindex++)
{
Q += e[eindex];
}
return Q;
}
///
/// Return a positive value if the points pa, pb, and pc occur in counterclockwise
/// order; a negative value if they occur in clockwise order; and zero if they are
/// collinear. The result is also a rough approximation of twice the signed area of
/// the triangle defined by the three points.
///
///
///
///
///
///
///
/// Uses exact arithmetic if necessary to ensure a correct answer. The result returned
/// is the determinant of a matrix. This determinant is computed adaptively, in the
/// sense that exact arithmetic is used only to the degree it is needed to ensure that
/// the returned value has the correct sign. Hence, this function is usually quite fast,
/// but will run more slowly when the input points are collinear or nearly so.
///
private double CounterClockwiseAdapt(Point pa, Point pb, Point pc, double detsum)
{
double acx, acy, bcx, bcy;
double acxtail, acytail, bcxtail, bcytail;
double detleft, detright;
double detlefttail, detrighttail;
double det, errbound;
// Edited to work around index out of range exceptions (changed array length from 4 to 5).
// See unsafe indexing in FastExpansionSumZeroElim.
double[] B = new double[5], u = new double[5];
double[] C1 = new double[8], C2 = new double[12], D = new double[16];
double B3;
int C1length, C2length, Dlength;
double u3;
double s1, t1;
double s0, t0;
double bvirt;
double avirt, bround, around;
double c;
double abig;
double ahi, alo, bhi, blo;
double err1, err2, err3;
double _i, _j;
double _0;
acx = (double)(pa.x - pc.x);
bcx = (double)(pb.x - pc.x);
acy = (double)(pa.y - pc.y);
bcy = (double)(pb.y - pc.y);
detleft = (double)(acx * bcy); c = (double)(splitter * acx); abig = (double)(c - acx); ahi = c - abig; alo = acx - ahi; c = (double)(splitter * bcy); abig = (double)(c - bcy); bhi = c - abig; blo = bcy - bhi; err1 = detleft - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); detlefttail = (alo * blo) - err3;
detright = (double)(acy * bcx); c = (double)(splitter * acy); abig = (double)(c - acy); ahi = c - abig; alo = acy - ahi; c = (double)(splitter * bcx); abig = (double)(c - bcx); bhi = c - abig; blo = bcx - bhi; err1 = detright - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); detrighttail = (alo * blo) - err3;
_i = (double)(detlefttail - detrighttail); bvirt = (double)(detlefttail - _i); avirt = _i + bvirt; bround = bvirt - detrighttail; around = detlefttail - avirt; B[0] = around + bround; _j = (double)(detleft + _i); bvirt = (double)(_j - detleft); avirt = _j - bvirt; bround = _i - bvirt; around = detleft - avirt; _0 = around + bround; _i = (double)(_0 - detright); bvirt = (double)(_0 - _i); avirt = _i + bvirt; bround = bvirt - detright; around = _0 - avirt; B[1] = around + bround; B3 = (double)(_j + _i); bvirt = (double)(B3 - _j); avirt = B3 - bvirt; bround = _i - bvirt; around = _j - avirt; B[2] = around + bround;
B[3] = B3;
det = Estimate(4, B);
errbound = ccwerrboundB * detsum;
if ((det >= errbound) || (-det >= errbound))
{
return det;
}
bvirt = (double)(pa.x - acx); avirt = acx + bvirt; bround = bvirt - pc.x; around = pa.x - avirt; acxtail = around + bround;
bvirt = (double)(pb.x - bcx); avirt = bcx + bvirt; bround = bvirt - pc.x; around = pb.x - avirt; bcxtail = around + bround;
bvirt = (double)(pa.y - acy); avirt = acy + bvirt; bround = bvirt - pc.y; around = pa.y - avirt; acytail = around + bround;
bvirt = (double)(pb.y - bcy); avirt = bcy + bvirt; bround = bvirt - pc.y; around = pb.y - avirt; bcytail = around + bround;
if ((acxtail == 0.0) && (acytail == 0.0)
&& (bcxtail == 0.0) && (bcytail == 0.0))
{
return det;
}
errbound = ccwerrboundC * detsum + resulterrbound * ((det) >= 0.0 ? (det) : -(det));
det += (acx * bcytail + bcy * acxtail)
- (acy * bcxtail + bcx * acytail);
if ((det >= errbound) || (-det >= errbound))
{
return det;
}
s1 = (double)(acxtail * bcy); c = (double)(splitter * acxtail); abig = (double)(c - acxtail); ahi = c - abig; alo = acxtail - ahi; c = (double)(splitter * bcy); abig = (double)(c - bcy); bhi = c - abig; blo = bcy - bhi; err1 = s1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); s0 = (alo * blo) - err3;
t1 = (double)(acytail * bcx); c = (double)(splitter * acytail); abig = (double)(c - acytail); ahi = c - abig; alo = acytail - ahi; c = (double)(splitter * bcx); abig = (double)(c - bcx); bhi = c - abig; blo = bcx - bhi; err1 = t1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); t0 = (alo * blo) - err3;
_i = (double)(s0 - t0); bvirt = (double)(s0 - _i); avirt = _i + bvirt; bround = bvirt - t0; around = s0 - avirt; u[0] = around + bround; _j = (double)(s1 + _i); bvirt = (double)(_j - s1); avirt = _j - bvirt; bround = _i - bvirt; around = s1 - avirt; _0 = around + bround; _i = (double)(_0 - t1); bvirt = (double)(_0 - _i); avirt = _i + bvirt; bround = bvirt - t1; around = _0 - avirt; u[1] = around + bround; u3 = (double)(_j + _i); bvirt = (double)(u3 - _j); avirt = u3 - bvirt; bround = _i - bvirt; around = _j - avirt; u[2] = around + bround;
u[3] = u3;
C1length = FastExpansionSumZeroElim(4, B, 4, u, C1);
s1 = (double)(acx * bcytail); c = (double)(splitter * acx); abig = (double)(c - acx); ahi = c - abig; alo = acx - ahi; c = (double)(splitter * bcytail); abig = (double)(c - bcytail); bhi = c - abig; blo = bcytail - bhi; err1 = s1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); s0 = (alo * blo) - err3;
t1 = (double)(acy * bcxtail); c = (double)(splitter * acy); abig = (double)(c - acy); ahi = c - abig; alo = acy - ahi; c = (double)(splitter * bcxtail); abig = (double)(c - bcxtail); bhi = c - abig; blo = bcxtail - bhi; err1 = t1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); t0 = (alo * blo) - err3;
_i = (double)(s0 - t0); bvirt = (double)(s0 - _i); avirt = _i + bvirt; bround = bvirt - t0; around = s0 - avirt; u[0] = around + bround; _j = (double)(s1 + _i); bvirt = (double)(_j - s1); avirt = _j - bvirt; bround = _i - bvirt; around = s1 - avirt; _0 = around + bround; _i = (double)(_0 - t1); bvirt = (double)(_0 - _i); avirt = _i + bvirt; bround = bvirt - t1; around = _0 - avirt; u[1] = around + bround; u3 = (double)(_j + _i); bvirt = (double)(u3 - _j); avirt = u3 - bvirt; bround = _i - bvirt; around = _j - avirt; u[2] = around + bround;
u[3] = u3;
C2length = FastExpansionSumZeroElim(C1length, C1, 4, u, C2);
s1 = (double)(acxtail * bcytail); c = (double)(splitter * acxtail); abig = (double)(c - acxtail); ahi = c - abig; alo = acxtail - ahi; c = (double)(splitter * bcytail); abig = (double)(c - bcytail); bhi = c - abig; blo = bcytail - bhi; err1 = s1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); s0 = (alo * blo) - err3;
t1 = (double)(acytail * bcxtail); c = (double)(splitter * acytail); abig = (double)(c - acytail); ahi = c - abig; alo = acytail - ahi; c = (double)(splitter * bcxtail); abig = (double)(c - bcxtail); bhi = c - abig; blo = bcxtail - bhi; err1 = t1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); t0 = (alo * blo) - err3;
_i = (double)(s0 - t0); bvirt = (double)(s0 - _i); avirt = _i + bvirt; bround = bvirt - t0; around = s0 - avirt; u[0] = around + bround; _j = (double)(s1 + _i); bvirt = (double)(_j - s1); avirt = _j - bvirt; bround = _i - bvirt; around = s1 - avirt; _0 = around + bround; _i = (double)(_0 - t1); bvirt = (double)(_0 - _i); avirt = _i + bvirt; bround = bvirt - t1; around = _0 - avirt; u[1] = around + bround; u3 = (double)(_j + _i); bvirt = (double)(u3 - _j); avirt = u3 - bvirt; bround = _i - bvirt; around = _j - avirt; u[2] = around + bround;
u[3] = u3;
Dlength = FastExpansionSumZeroElim(C2length, C2, 4, u, D);
return (D[Dlength - 1]);
}
///
/// Return a positive value if the point pd lies inside the circle passing through
/// pa, pb, and pc; a negative value if it lies outside; and zero if the four points
/// are cocircular. The points pa, pb, and pc must be in counterclockwise order, or
/// the sign of the result will be reversed.
///
///
///
///
///
///
///
///
/// Uses exact arithmetic if necessary to ensure a correct answer. The result returned
/// is the determinant of a matrix. This determinant is computed adaptively, in the
/// sense that exact arithmetic is used only to the degree it is needed to ensure that
/// the returned value has the correct sign. Hence, this function is usually quite fast,
/// but will run more slowly when the input points are cocircular or nearly so.
///
private double InCircleAdapt(Point pa, Point pb, Point pc, Point pd, double permanent)
{
double adx, bdx, cdx, ady, bdy, cdy;
double det, errbound;
double bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
double bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
double[] bc = new double[4], ca = new double[4], ab = new double[4];
double bc3, ca3, ab3;
int axbclen, axxbclen, aybclen, ayybclen, alen;
int bxcalen, bxxcalen, bycalen, byycalen, blen;
int cxablen, cxxablen, cyablen, cyyablen, clen;
int ablen;
double[] finnow, finother, finswap;
int finlength;
double adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail;
double adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1;
double adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0;
double[] aa = new double[4], bb = new double[4], cc = new double[4];
double aa3, bb3, cc3;
double ti1, tj1;
double ti0, tj0;
// Edited to work around index out of range exceptions (changed array length from 4 to 5).
// See unsafe indexing in FastExpansionSumZeroElim.
double[] u = new double[5], v = new double[5];
double u3, v3;
int temp8len, temp16alen, temp16blen, temp16clen;
int temp32alen, temp32blen, temp48len, temp64len;
double[] axtbb = new double[8], axtcc = new double[8], aytbb = new double[8], aytcc = new double[8];
int axtbblen, axtcclen, aytbblen, aytcclen;
double[] bxtaa = new double[8], bxtcc = new double[8], bytaa = new double[8], bytcc = new double[8];
int bxtaalen, bxtcclen, bytaalen, bytcclen;
double[] cxtaa = new double[8], cxtbb = new double[8], cytaa = new double[8], cytbb = new double[8];
int cxtaalen, cxtbblen, cytaalen, cytbblen;
double[] axtbc = new double[8], aytbc = new double[8], bxtca = new double[8], bytca = new double[8], cxtab = new double[8], cytab = new double[8];
int axtbclen = 0, aytbclen = 0, bxtcalen = 0, bytcalen = 0, cxtablen = 0, cytablen = 0;
double[] axtbct = new double[16], aytbct = new double[16], bxtcat = new double[16], bytcat = new double[16], cxtabt = new double[16], cytabt = new double[16];
int axtbctlen, aytbctlen, bxtcatlen, bytcatlen, cxtabtlen, cytabtlen;
double[] axtbctt = new double[8], aytbctt = new double[8], bxtcatt = new double[8];
double[] bytcatt = new double[8], cxtabtt = new double[8], cytabtt = new double[8];
int axtbcttlen, aytbcttlen, bxtcattlen, bytcattlen, cxtabttlen, cytabttlen;
double[] abt = new double[8], bct = new double[8], cat = new double[8];
int abtlen, bctlen, catlen;
double[] abtt = new double[4], bctt = new double[4], catt = new double[4];
int abttlen, bcttlen, cattlen;
double abtt3, bctt3, catt3;
double negate;
double bvirt;
double avirt, bround, around;
double c;
double abig;
double ahi, alo, bhi, blo;
double err1, err2, err3;
double _i, _j;
double _0;
adx = (double)(pa.x - pd.x);
bdx = (double)(pb.x - pd.x);
cdx = (double)(pc.x - pd.x);
ady = (double)(pa.y - pd.y);
bdy = (double)(pb.y - pd.y);
cdy = (double)(pc.y - pd.y);
adx = (double)(pa.x - pd.x);
bdx = (double)(pb.x - pd.x);
cdx = (double)(pc.x - pd.x);
ady = (double)(pa.y - pd.y);
bdy = (double)(pb.y - pd.y);
cdy = (double)(pc.y - pd.y);
bdxcdy1 = (double)(bdx * cdy); c = (double)(splitter * bdx); abig = (double)(c - bdx); ahi = c - abig; alo = bdx - ahi; c = (double)(splitter * cdy); abig = (double)(c - cdy); bhi = c - abig; blo = cdy - bhi; err1 = bdxcdy1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); bdxcdy0 = (alo * blo) - err3;
cdxbdy1 = (double)(cdx * bdy); c = (double)(splitter * cdx); abig = (double)(c - cdx); ahi = c - abig; alo = cdx - ahi; c = (double)(splitter * bdy); abig = (double)(c - bdy); bhi = c - abig; blo = bdy - bhi; err1 = cdxbdy1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); cdxbdy0 = (alo * blo) - err3;
_i = (double)(bdxcdy0 - cdxbdy0); bvirt = (double)(bdxcdy0 - _i); avirt = _i + bvirt; bround = bvirt - cdxbdy0; around = bdxcdy0 - avirt; bc[0] = around + bround; _j = (double)(bdxcdy1 + _i); bvirt = (double)(_j - bdxcdy1); avirt = _j - bvirt; bround = _i - bvirt; around = bdxcdy1 - avirt; _0 = around + bround; _i = (double)(_0 - cdxbdy1); bvirt = (double)(_0 - _i); avirt = _i + bvirt; bround = bvirt - cdxbdy1; around = _0 - avirt; bc[1] = around + bround; bc3 = (double)(_j + _i); bvirt = (double)(bc3 - _j); avirt = bc3 - bvirt; bround = _i - bvirt; around = _j - avirt; bc[2] = around + bround;
bc[3] = bc3;
axbclen = ScaleExpansionZeroElim(4, bc, adx, axbc);
axxbclen = ScaleExpansionZeroElim(axbclen, axbc, adx, axxbc);
aybclen = ScaleExpansionZeroElim(4, bc, ady, aybc);
ayybclen = ScaleExpansionZeroElim(aybclen, aybc, ady, ayybc);
alen = FastExpansionSumZeroElim(axxbclen, axxbc, ayybclen, ayybc, adet);
cdxady1 = (double)(cdx * ady); c = (double)(splitter * cdx); abig = (double)(c - cdx); ahi = c - abig; alo = cdx - ahi; c = (double)(splitter * ady); abig = (double)(c - ady); bhi = c - abig; blo = ady - bhi; err1 = cdxady1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); cdxady0 = (alo * blo) - err3;
adxcdy1 = (double)(adx * cdy); c = (double)(splitter * adx); abig = (double)(c - adx); ahi = c - abig; alo = adx - ahi; c = (double)(splitter * cdy); abig = (double)(c - cdy); bhi = c - abig; blo = cdy - bhi; err1 = adxcdy1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); adxcdy0 = (alo * blo) - err3;
_i = (double)(cdxady0 - adxcdy0); bvirt = (double)(cdxady0 - _i); avirt = _i + bvirt; bround = bvirt - adxcdy0; around = cdxady0 - avirt; ca[0] = around + bround; _j = (double)(cdxady1 + _i); bvirt = (double)(_j - cdxady1); avirt = _j - bvirt; bround = _i - bvirt; around = cdxady1 - avirt; _0 = around + bround; _i = (double)(_0 - adxcdy1); bvirt = (double)(_0 - _i); avirt = _i + bvirt; bround = bvirt - adxcdy1; around = _0 - avirt; ca[1] = around + bround; ca3 = (double)(_j + _i); bvirt = (double)(ca3 - _j); avirt = ca3 - bvirt; bround = _i - bvirt; around = _j - avirt; ca[2] = around + bround;
ca[3] = ca3;
bxcalen = ScaleExpansionZeroElim(4, ca, bdx, bxca);
bxxcalen = ScaleExpansionZeroElim(bxcalen, bxca, bdx, bxxca);
bycalen = ScaleExpansionZeroElim(4, ca, bdy, byca);
byycalen = ScaleExpansionZeroElim(bycalen, byca, bdy, byyca);
blen = FastExpansionSumZeroElim(bxxcalen, bxxca, byycalen, byyca, bdet);
adxbdy1 = (double)(adx * bdy); c = (double)(splitter * adx); abig = (double)(c - adx); ahi = c - abig; alo = adx - ahi; c = (double)(splitter * bdy); abig = (double)(c - bdy); bhi = c - abig; blo = bdy - bhi; err1 = adxbdy1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); adxbdy0 = (alo * blo) - err3;
bdxady1 = (double)(bdx * ady); c = (double)(splitter * bdx); abig = (double)(c - bdx); ahi = c - abig; alo = bdx - ahi; c = (double)(splitter * ady); abig = (double)(c - ady); bhi = c - abig; blo = ady - bhi; err1 = bdxady1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); bdxady0 = (alo * blo) - err3;
_i = (double)(adxbdy0 - bdxady0); bvirt = (double)(adxbdy0 - _i); avirt = _i + bvirt; bround = bvirt - bdxady0; around = adxbdy0 - avirt; ab[0] = around + bround; _j = (double)(adxbdy1 + _i); bvirt = (double)(_j - adxbdy1); avirt = _j - bvirt; bround = _i - bvirt; around = adxbdy1 - avirt; _0 = around + bround; _i = (double)(_0 - bdxady1); bvirt = (double)(_0 - _i); avirt = _i + bvirt; bround = bvirt - bdxady1; around = _0 - avirt; ab[1] = around + bround; ab3 = (double)(_j + _i); bvirt = (double)(ab3 - _j); avirt = ab3 - bvirt; bround = _i - bvirt; around = _j - avirt; ab[2] = around + bround;
ab[3] = ab3;
cxablen = ScaleExpansionZeroElim(4, ab, cdx, cxab);
cxxablen = ScaleExpansionZeroElim(cxablen, cxab, cdx, cxxab);
cyablen = ScaleExpansionZeroElim(4, ab, cdy, cyab);
cyyablen = ScaleExpansionZeroElim(cyablen, cyab, cdy, cyyab);
clen = FastExpansionSumZeroElim(cxxablen, cxxab, cyyablen, cyyab, cdet);
ablen = FastExpansionSumZeroElim(alen, adet, blen, bdet, abdet);
finlength = FastExpansionSumZeroElim(ablen, abdet, clen, cdet, fin1);
det = Estimate(finlength, fin1);
errbound = iccerrboundB * permanent;
if ((det >= errbound) || (-det >= errbound))
{
return det;
}
bvirt = (double)(pa.x - adx); avirt = adx + bvirt; bround = bvirt - pd.x; around = pa.x - avirt; adxtail = around + bround;
bvirt = (double)(pa.y - ady); avirt = ady + bvirt; bround = bvirt - pd.y; around = pa.y - avirt; adytail = around + bround;
bvirt = (double)(pb.x - bdx); avirt = bdx + bvirt; bround = bvirt - pd.x; around = pb.x - avirt; bdxtail = around + bround;
bvirt = (double)(pb.y - bdy); avirt = bdy + bvirt; bround = bvirt - pd.y; around = pb.y - avirt; bdytail = around + bround;
bvirt = (double)(pc.x - cdx); avirt = cdx + bvirt; bround = bvirt - pd.x; around = pc.x - avirt; cdxtail = around + bround;
bvirt = (double)(pc.y - cdy); avirt = cdy + bvirt; bround = bvirt - pd.y; around = pc.y - avirt; cdytail = around + bround;
if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0)
&& (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0))
{
return det;
}
errbound = iccerrboundC * permanent + resulterrbound * ((det) >= 0.0 ? (det) : -(det));
det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail) - (bdy * cdxtail + cdx * bdytail))
+ 2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx))
+ ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail) - (cdy * adxtail + adx * cdytail))
+ 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx))
+ ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail) - (ady * bdxtail + bdx * adytail))
+ 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx));
if ((det >= errbound) || (-det >= errbound))
{
return det;
}
finnow = fin1;
finother = fin2;
if ((bdxtail != 0.0) || (bdytail != 0.0) || (cdxtail != 0.0) || (cdytail != 0.0))
{
adxadx1 = (double)(adx * adx); c = (double)(splitter * adx); abig = (double)(c - adx); ahi = c - abig; alo = adx - ahi; err1 = adxadx1 - (ahi * ahi); err3 = err1 - ((ahi + ahi) * alo); adxadx0 = (alo * alo) - err3;
adyady1 = (double)(ady * ady); c = (double)(splitter * ady); abig = (double)(c - ady); ahi = c - abig; alo = ady - ahi; err1 = adyady1 - (ahi * ahi); err3 = err1 - ((ahi + ahi) * alo); adyady0 = (alo * alo) - err3;
_i = (double)(adxadx0 + adyady0); bvirt = (double)(_i - adxadx0); avirt = _i - bvirt; bround = adyady0 - bvirt; around = adxadx0 - avirt; aa[0] = around + bround; _j = (double)(adxadx1 + _i); bvirt = (double)(_j - adxadx1); avirt = _j - bvirt; bround = _i - bvirt; around = adxadx1 - avirt; _0 = around + bround; _i = (double)(_0 + adyady1); bvirt = (double)(_i - _0); avirt = _i - bvirt; bround = adyady1 - bvirt; around = _0 - avirt; aa[1] = around + bround; aa3 = (double)(_j + _i); bvirt = (double)(aa3 - _j); avirt = aa3 - bvirt; bround = _i - bvirt; around = _j - avirt; aa[2] = around + bround;
aa[3] = aa3;
}
if ((cdxtail != 0.0) || (cdytail != 0.0) || (adxtail != 0.0) || (adytail != 0.0))
{
bdxbdx1 = (double)(bdx * bdx); c = (double)(splitter * bdx); abig = (double)(c - bdx); ahi = c - abig; alo = bdx - ahi; err1 = bdxbdx1 - (ahi * ahi); err3 = err1 - ((ahi + ahi) * alo); bdxbdx0 = (alo * alo) - err3;
bdybdy1 = (double)(bdy * bdy); c = (double)(splitter * bdy); abig = (double)(c - bdy); ahi = c - abig; alo = bdy - ahi; err1 = bdybdy1 - (ahi * ahi); err3 = err1 - ((ahi + ahi) * alo); bdybdy0 = (alo * alo) - err3;
_i = (double)(bdxbdx0 + bdybdy0); bvirt = (double)(_i - bdxbdx0); avirt = _i - bvirt; bround = bdybdy0 - bvirt; around = bdxbdx0 - avirt; bb[0] = around + bround; _j = (double)(bdxbdx1 + _i); bvirt = (double)(_j - bdxbdx1); avirt = _j - bvirt; bround = _i - bvirt; around = bdxbdx1 - avirt; _0 = around + bround; _i = (double)(_0 + bdybdy1); bvirt = (double)(_i - _0); avirt = _i - bvirt; bround = bdybdy1 - bvirt; around = _0 - avirt; bb[1] = around + bround; bb3 = (double)(_j + _i); bvirt = (double)(bb3 - _j); avirt = bb3 - bvirt; bround = _i - bvirt; around = _j - avirt; bb[2] = around + bround;
bb[3] = bb3;
}
if ((adxtail != 0.0) || (adytail != 0.0) || (bdxtail != 0.0) || (bdytail != 0.0))
{
cdxcdx1 = (double)(cdx * cdx); c = (double)(splitter * cdx); abig = (double)(c - cdx); ahi = c - abig; alo = cdx - ahi; err1 = cdxcdx1 - (ahi * ahi); err3 = err1 - ((ahi + ahi) * alo); cdxcdx0 = (alo * alo) - err3;
cdycdy1 = (double)(cdy * cdy); c = (double)(splitter * cdy); abig = (double)(c - cdy); ahi = c - abig; alo = cdy - ahi; err1 = cdycdy1 - (ahi * ahi); err3 = err1 - ((ahi + ahi) * alo); cdycdy0 = (alo * alo) - err3;
_i = (double)(cdxcdx0 + cdycdy0); bvirt = (double)(_i - cdxcdx0); avirt = _i - bvirt; bround = cdycdy0 - bvirt; around = cdxcdx0 - avirt; cc[0] = around + bround; _j = (double)(cdxcdx1 + _i); bvirt = (double)(_j - cdxcdx1); avirt = _j - bvirt; bround = _i - bvirt; around = cdxcdx1 - avirt; _0 = around + bround; _i = (double)(_0 + cdycdy1); bvirt = (double)(_i - _0); avirt = _i - bvirt; bround = cdycdy1 - bvirt; around = _0 - avirt; cc[1] = around + bround; cc3 = (double)(_j + _i); bvirt = (double)(cc3 - _j); avirt = cc3 - bvirt; bround = _i - bvirt; around = _j - avirt; cc[2] = around + bround;
cc[3] = cc3;
}
if (adxtail != 0.0)
{
axtbclen = ScaleExpansionZeroElim(4, bc, adxtail, axtbc);
temp16alen = ScaleExpansionZeroElim(axtbclen, axtbc, 2.0 * adx, temp16a);
axtcclen = ScaleExpansionZeroElim(4, cc, adxtail, axtcc);
temp16blen = ScaleExpansionZeroElim(axtcclen, axtcc, bdy, temp16b);
axtbblen = ScaleExpansionZeroElim(4, bb, adxtail, axtbb);
temp16clen = ScaleExpansionZeroElim(axtbblen, axtbb, -cdy, temp16c);
temp32alen = FastExpansionSumZeroElim(temp16alen, temp16a, temp16blen, temp16b, temp32a);
temp48len = FastExpansionSumZeroElim(temp16clen, temp16c, temp32alen, temp32a, temp48);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp48len, temp48, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
if (adytail != 0.0)
{
aytbclen = ScaleExpansionZeroElim(4, bc, adytail, aytbc);
temp16alen = ScaleExpansionZeroElim(aytbclen, aytbc, 2.0 * ady, temp16a);
aytbblen = ScaleExpansionZeroElim(4, bb, adytail, aytbb);
temp16blen = ScaleExpansionZeroElim(aytbblen, aytbb, cdx, temp16b);
aytcclen = ScaleExpansionZeroElim(4, cc, adytail, aytcc);
temp16clen = ScaleExpansionZeroElim(aytcclen, aytcc, -bdx, temp16c);
temp32alen = FastExpansionSumZeroElim(temp16alen, temp16a, temp16blen, temp16b, temp32a);
temp48len = FastExpansionSumZeroElim(temp16clen, temp16c, temp32alen, temp32a, temp48);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp48len, temp48, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
if (bdxtail != 0.0)
{
bxtcalen = ScaleExpansionZeroElim(4, ca, bdxtail, bxtca);
temp16alen = ScaleExpansionZeroElim(bxtcalen, bxtca, 2.0 * bdx, temp16a);
bxtaalen = ScaleExpansionZeroElim(4, aa, bdxtail, bxtaa);
temp16blen = ScaleExpansionZeroElim(bxtaalen, bxtaa, cdy, temp16b);
bxtcclen = ScaleExpansionZeroElim(4, cc, bdxtail, bxtcc);
temp16clen = ScaleExpansionZeroElim(bxtcclen, bxtcc, -ady, temp16c);
temp32alen = FastExpansionSumZeroElim(temp16alen, temp16a, temp16blen, temp16b, temp32a);
temp48len = FastExpansionSumZeroElim(temp16clen, temp16c, temp32alen, temp32a, temp48);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp48len, temp48, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
if (bdytail != 0.0)
{
bytcalen = ScaleExpansionZeroElim(4, ca, bdytail, bytca);
temp16alen = ScaleExpansionZeroElim(bytcalen, bytca, 2.0 * bdy, temp16a);
bytcclen = ScaleExpansionZeroElim(4, cc, bdytail, bytcc);
temp16blen = ScaleExpansionZeroElim(bytcclen, bytcc, adx, temp16b);
bytaalen = ScaleExpansionZeroElim(4, aa, bdytail, bytaa);
temp16clen = ScaleExpansionZeroElim(bytaalen, bytaa, -cdx, temp16c);
temp32alen = FastExpansionSumZeroElim(temp16alen, temp16a, temp16blen, temp16b, temp32a);
temp48len = FastExpansionSumZeroElim(temp16clen, temp16c, temp32alen, temp32a, temp48);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp48len, temp48, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
if (cdxtail != 0.0)
{
cxtablen = ScaleExpansionZeroElim(4, ab, cdxtail, cxtab);
temp16alen = ScaleExpansionZeroElim(cxtablen, cxtab, 2.0 * cdx, temp16a);
cxtbblen = ScaleExpansionZeroElim(4, bb, cdxtail, cxtbb);
temp16blen = ScaleExpansionZeroElim(cxtbblen, cxtbb, ady, temp16b);
cxtaalen = ScaleExpansionZeroElim(4, aa, cdxtail, cxtaa);
temp16clen = ScaleExpansionZeroElim(cxtaalen, cxtaa, -bdy, temp16c);
temp32alen = FastExpansionSumZeroElim(temp16alen, temp16a, temp16blen, temp16b, temp32a);
temp48len = FastExpansionSumZeroElim(temp16clen, temp16c, temp32alen, temp32a, temp48);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp48len, temp48, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
if (cdytail != 0.0)
{
cytablen = ScaleExpansionZeroElim(4, ab, cdytail, cytab);
temp16alen = ScaleExpansionZeroElim(cytablen, cytab, 2.0 * cdy, temp16a);
cytaalen = ScaleExpansionZeroElim(4, aa, cdytail, cytaa);
temp16blen = ScaleExpansionZeroElim(cytaalen, cytaa, bdx, temp16b);
cytbblen = ScaleExpansionZeroElim(4, bb, cdytail, cytbb);
temp16clen = ScaleExpansionZeroElim(cytbblen, cytbb, -adx, temp16c);
temp32alen = FastExpansionSumZeroElim(temp16alen, temp16a, temp16blen, temp16b, temp32a);
temp48len = FastExpansionSumZeroElim(temp16clen, temp16c, temp32alen, temp32a, temp48);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp48len, temp48, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
if ((adxtail != 0.0) || (adytail != 0.0))
{
if ((bdxtail != 0.0) || (bdytail != 0.0)
|| (cdxtail != 0.0) || (cdytail != 0.0))
{
ti1 = (double)(bdxtail * cdy); c = (double)(splitter * bdxtail); abig = (double)(c - bdxtail); ahi = c - abig; alo = bdxtail - ahi; c = (double)(splitter * cdy); abig = (double)(c - cdy); bhi = c - abig; blo = cdy - bhi; err1 = ti1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); ti0 = (alo * blo) - err3;
tj1 = (double)(bdx * cdytail); c = (double)(splitter * bdx); abig = (double)(c - bdx); ahi = c - abig; alo = bdx - ahi; c = (double)(splitter * cdytail); abig = (double)(c - cdytail); bhi = c - abig; blo = cdytail - bhi; err1 = tj1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); tj0 = (alo * blo) - err3;
_i = (double)(ti0 + tj0); bvirt = (double)(_i - ti0); avirt = _i - bvirt; bround = tj0 - bvirt; around = ti0 - avirt; u[0] = around + bround; _j = (double)(ti1 + _i); bvirt = (double)(_j - ti1); avirt = _j - bvirt; bround = _i - bvirt; around = ti1 - avirt; _0 = around + bround; _i = (double)(_0 + tj1); bvirt = (double)(_i - _0); avirt = _i - bvirt; bround = tj1 - bvirt; around = _0 - avirt; u[1] = around + bround; u3 = (double)(_j + _i); bvirt = (double)(u3 - _j); avirt = u3 - bvirt; bround = _i - bvirt; around = _j - avirt; u[2] = around + bround;
u[3] = u3;
negate = -bdy;
ti1 = (double)(cdxtail * negate); c = (double)(splitter * cdxtail); abig = (double)(c - cdxtail); ahi = c - abig; alo = cdxtail - ahi; c = (double)(splitter * negate); abig = (double)(c - negate); bhi = c - abig; blo = negate - bhi; err1 = ti1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); ti0 = (alo * blo) - err3;
negate = -bdytail;
tj1 = (double)(cdx * negate); c = (double)(splitter * cdx); abig = (double)(c - cdx); ahi = c - abig; alo = cdx - ahi; c = (double)(splitter * negate); abig = (double)(c - negate); bhi = c - abig; blo = negate - bhi; err1 = tj1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); tj0 = (alo * blo) - err3;
_i = (double)(ti0 + tj0); bvirt = (double)(_i - ti0); avirt = _i - bvirt; bround = tj0 - bvirt; around = ti0 - avirt; v[0] = around + bround; _j = (double)(ti1 + _i); bvirt = (double)(_j - ti1); avirt = _j - bvirt; bround = _i - bvirt; around = ti1 - avirt; _0 = around + bround; _i = (double)(_0 + tj1); bvirt = (double)(_i - _0); avirt = _i - bvirt; bround = tj1 - bvirt; around = _0 - avirt; v[1] = around + bround; v3 = (double)(_j + _i); bvirt = (double)(v3 - _j); avirt = v3 - bvirt; bround = _i - bvirt; around = _j - avirt; v[2] = around + bround;
v[3] = v3;
bctlen = FastExpansionSumZeroElim(4, u, 4, v, bct);
ti1 = (double)(bdxtail * cdytail); c = (double)(splitter * bdxtail); abig = (double)(c - bdxtail); ahi = c - abig; alo = bdxtail - ahi; c = (double)(splitter * cdytail); abig = (double)(c - cdytail); bhi = c - abig; blo = cdytail - bhi; err1 = ti1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); ti0 = (alo * blo) - err3;
tj1 = (double)(cdxtail * bdytail); c = (double)(splitter * cdxtail); abig = (double)(c - cdxtail); ahi = c - abig; alo = cdxtail - ahi; c = (double)(splitter * bdytail); abig = (double)(c - bdytail); bhi = c - abig; blo = bdytail - bhi; err1 = tj1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); tj0 = (alo * blo) - err3;
_i = (double)(ti0 - tj0); bvirt = (double)(ti0 - _i); avirt = _i + bvirt; bround = bvirt - tj0; around = ti0 - avirt; bctt[0] = around + bround; _j = (double)(ti1 + _i); bvirt = (double)(_j - ti1); avirt = _j - bvirt; bround = _i - bvirt; around = ti1 - avirt; _0 = around + bround; _i = (double)(_0 - tj1); bvirt = (double)(_0 - _i); avirt = _i + bvirt; bround = bvirt - tj1; around = _0 - avirt; bctt[1] = around + bround; bctt3 = (double)(_j + _i); bvirt = (double)(bctt3 - _j); avirt = bctt3 - bvirt; bround = _i - bvirt; around = _j - avirt; bctt[2] = around + bround;
bctt[3] = bctt3;
bcttlen = 4;
}
else
{
bct[0] = 0.0;
bctlen = 1;
bctt[0] = 0.0;
bcttlen = 1;
}
if (adxtail != 0.0)
{
temp16alen = ScaleExpansionZeroElim(axtbclen, axtbc, adxtail, temp16a);
axtbctlen = ScaleExpansionZeroElim(bctlen, bct, adxtail, axtbct);
temp32alen = ScaleExpansionZeroElim(axtbctlen, axtbct, 2.0 * adx, temp32a);
temp48len = FastExpansionSumZeroElim(temp16alen, temp16a, temp32alen, temp32a, temp48);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp48len, temp48, finother);
finswap = finnow; finnow = finother; finother = finswap;
if (bdytail != 0.0)
{
temp8len = ScaleExpansionZeroElim(4, cc, adxtail, temp8);
temp16alen = ScaleExpansionZeroElim(temp8len, temp8, bdytail, temp16a);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp16alen, temp16a, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
if (cdytail != 0.0)
{
temp8len = ScaleExpansionZeroElim(4, bb, -adxtail, temp8);
temp16alen = ScaleExpansionZeroElim(temp8len, temp8, cdytail, temp16a);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp16alen, temp16a, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
temp32alen = ScaleExpansionZeroElim(axtbctlen, axtbct, adxtail, temp32a);
axtbcttlen = ScaleExpansionZeroElim(bcttlen, bctt, adxtail, axtbctt);
temp16alen = ScaleExpansionZeroElim(axtbcttlen, axtbctt, 2.0 * adx, temp16a);
temp16blen = ScaleExpansionZeroElim(axtbcttlen, axtbctt, adxtail, temp16b);
temp32blen = FastExpansionSumZeroElim(temp16alen, temp16a, temp16blen, temp16b, temp32b);
temp64len = FastExpansionSumZeroElim(temp32alen, temp32a, temp32blen, temp32b, temp64);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp64len, temp64, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
if (adytail != 0.0)
{
temp16alen = ScaleExpansionZeroElim(aytbclen, aytbc, adytail, temp16a);
aytbctlen = ScaleExpansionZeroElim(bctlen, bct, adytail, aytbct);
temp32alen = ScaleExpansionZeroElim(aytbctlen, aytbct, 2.0 * ady, temp32a);
temp48len = FastExpansionSumZeroElim(temp16alen, temp16a, temp32alen, temp32a, temp48);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp48len, temp48, finother);
finswap = finnow; finnow = finother; finother = finswap;
temp32alen = ScaleExpansionZeroElim(aytbctlen, aytbct, adytail, temp32a);
aytbcttlen = ScaleExpansionZeroElim(bcttlen, bctt, adytail, aytbctt);
temp16alen = ScaleExpansionZeroElim(aytbcttlen, aytbctt, 2.0 * ady, temp16a);
temp16blen = ScaleExpansionZeroElim(aytbcttlen, aytbctt, adytail, temp16b);
temp32blen = FastExpansionSumZeroElim(temp16alen, temp16a, temp16blen, temp16b, temp32b);
temp64len = FastExpansionSumZeroElim(temp32alen, temp32a, temp32blen, temp32b, temp64);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp64len, temp64, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
}
if ((bdxtail != 0.0) || (bdytail != 0.0))
{
if ((cdxtail != 0.0) || (cdytail != 0.0)
|| (adxtail != 0.0) || (adytail != 0.0))
{
ti1 = (double)(cdxtail * ady); c = (double)(splitter * cdxtail); abig = (double)(c - cdxtail); ahi = c - abig; alo = cdxtail - ahi; c = (double)(splitter * ady); abig = (double)(c - ady); bhi = c - abig; blo = ady - bhi; err1 = ti1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); ti0 = (alo * blo) - err3;
tj1 = (double)(cdx * adytail); c = (double)(splitter * cdx); abig = (double)(c - cdx); ahi = c - abig; alo = cdx - ahi; c = (double)(splitter * adytail); abig = (double)(c - adytail); bhi = c - abig; blo = adytail - bhi; err1 = tj1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); tj0 = (alo * blo) - err3;
_i = (double)(ti0 + tj0); bvirt = (double)(_i - ti0); avirt = _i - bvirt; bround = tj0 - bvirt; around = ti0 - avirt; u[0] = around + bround; _j = (double)(ti1 + _i); bvirt = (double)(_j - ti1); avirt = _j - bvirt; bround = _i - bvirt; around = ti1 - avirt; _0 = around + bround; _i = (double)(_0 + tj1); bvirt = (double)(_i - _0); avirt = _i - bvirt; bround = tj1 - bvirt; around = _0 - avirt; u[1] = around + bround; u3 = (double)(_j + _i); bvirt = (double)(u3 - _j); avirt = u3 - bvirt; bround = _i - bvirt; around = _j - avirt; u[2] = around + bround;
u[3] = u3;
negate = -cdy;
ti1 = (double)(adxtail * negate); c = (double)(splitter * adxtail); abig = (double)(c - adxtail); ahi = c - abig; alo = adxtail - ahi; c = (double)(splitter * negate); abig = (double)(c - negate); bhi = c - abig; blo = negate - bhi; err1 = ti1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); ti0 = (alo * blo) - err3;
negate = -cdytail;
tj1 = (double)(adx * negate); c = (double)(splitter * adx); abig = (double)(c - adx); ahi = c - abig; alo = adx - ahi; c = (double)(splitter * negate); abig = (double)(c - negate); bhi = c - abig; blo = negate - bhi; err1 = tj1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); tj0 = (alo * blo) - err3;
_i = (double)(ti0 + tj0); bvirt = (double)(_i - ti0); avirt = _i - bvirt; bround = tj0 - bvirt; around = ti0 - avirt; v[0] = around + bround; _j = (double)(ti1 + _i); bvirt = (double)(_j - ti1); avirt = _j - bvirt; bround = _i - bvirt; around = ti1 - avirt; _0 = around + bround; _i = (double)(_0 + tj1); bvirt = (double)(_i - _0); avirt = _i - bvirt; bround = tj1 - bvirt; around = _0 - avirt; v[1] = around + bround; v3 = (double)(_j + _i); bvirt = (double)(v3 - _j); avirt = v3 - bvirt; bround = _i - bvirt; around = _j - avirt; v[2] = around + bround;
v[3] = v3;
catlen = FastExpansionSumZeroElim(4, u, 4, v, cat);
ti1 = (double)(cdxtail * adytail); c = (double)(splitter * cdxtail); abig = (double)(c - cdxtail); ahi = c - abig; alo = cdxtail - ahi; c = (double)(splitter * adytail); abig = (double)(c - adytail); bhi = c - abig; blo = adytail - bhi; err1 = ti1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); ti0 = (alo * blo) - err3;
tj1 = (double)(adxtail * cdytail); c = (double)(splitter * adxtail); abig = (double)(c - adxtail); ahi = c - abig; alo = adxtail - ahi; c = (double)(splitter * cdytail); abig = (double)(c - cdytail); bhi = c - abig; blo = cdytail - bhi; err1 = tj1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); tj0 = (alo * blo) - err3;
_i = (double)(ti0 - tj0); bvirt = (double)(ti0 - _i); avirt = _i + bvirt; bround = bvirt - tj0; around = ti0 - avirt; catt[0] = around + bround; _j = (double)(ti1 + _i); bvirt = (double)(_j - ti1); avirt = _j - bvirt; bround = _i - bvirt; around = ti1 - avirt; _0 = around + bround; _i = (double)(_0 - tj1); bvirt = (double)(_0 - _i); avirt = _i + bvirt; bround = bvirt - tj1; around = _0 - avirt; catt[1] = around + bround; catt3 = (double)(_j + _i); bvirt = (double)(catt3 - _j); avirt = catt3 - bvirt; bround = _i - bvirt; around = _j - avirt; catt[2] = around + bround;
catt[3] = catt3;
cattlen = 4;
}
else
{
cat[0] = 0.0;
catlen = 1;
catt[0] = 0.0;
cattlen = 1;
}
if (bdxtail != 0.0)
{
temp16alen = ScaleExpansionZeroElim(bxtcalen, bxtca, bdxtail, temp16a);
bxtcatlen = ScaleExpansionZeroElim(catlen, cat, bdxtail, bxtcat);
temp32alen = ScaleExpansionZeroElim(bxtcatlen, bxtcat, 2.0 * bdx, temp32a);
temp48len = FastExpansionSumZeroElim(temp16alen, temp16a, temp32alen, temp32a, temp48);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp48len, temp48, finother);
finswap = finnow; finnow = finother; finother = finswap;
if (cdytail != 0.0)
{
temp8len = ScaleExpansionZeroElim(4, aa, bdxtail, temp8);
temp16alen = ScaleExpansionZeroElim(temp8len, temp8, cdytail, temp16a);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp16alen, temp16a, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
if (adytail != 0.0)
{
temp8len = ScaleExpansionZeroElim(4, cc, -bdxtail, temp8);
temp16alen = ScaleExpansionZeroElim(temp8len, temp8, adytail, temp16a);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp16alen, temp16a, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
temp32alen = ScaleExpansionZeroElim(bxtcatlen, bxtcat, bdxtail, temp32a);
bxtcattlen = ScaleExpansionZeroElim(cattlen, catt, bdxtail, bxtcatt);
temp16alen = ScaleExpansionZeroElim(bxtcattlen, bxtcatt, 2.0 * bdx, temp16a);
temp16blen = ScaleExpansionZeroElim(bxtcattlen, bxtcatt, bdxtail, temp16b);
temp32blen = FastExpansionSumZeroElim(temp16alen, temp16a, temp16blen, temp16b, temp32b);
temp64len = FastExpansionSumZeroElim(temp32alen, temp32a, temp32blen, temp32b, temp64);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp64len, temp64, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
if (bdytail != 0.0)
{
temp16alen = ScaleExpansionZeroElim(bytcalen, bytca, bdytail, temp16a);
bytcatlen = ScaleExpansionZeroElim(catlen, cat, bdytail, bytcat);
temp32alen = ScaleExpansionZeroElim(bytcatlen, bytcat, 2.0 * bdy, temp32a);
temp48len = FastExpansionSumZeroElim(temp16alen, temp16a, temp32alen, temp32a, temp48);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp48len, temp48, finother);
finswap = finnow; finnow = finother; finother = finswap;
temp32alen = ScaleExpansionZeroElim(bytcatlen, bytcat, bdytail, temp32a);
bytcattlen = ScaleExpansionZeroElim(cattlen, catt, bdytail, bytcatt);
temp16alen = ScaleExpansionZeroElim(bytcattlen, bytcatt, 2.0 * bdy, temp16a);
temp16blen = ScaleExpansionZeroElim(bytcattlen, bytcatt, bdytail, temp16b);
temp32blen = FastExpansionSumZeroElim(temp16alen, temp16a, temp16blen, temp16b, temp32b);
temp64len = FastExpansionSumZeroElim(temp32alen, temp32a, temp32blen, temp32b, temp64);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp64len, temp64, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
}
if ((cdxtail != 0.0) || (cdytail != 0.0))
{
if ((adxtail != 0.0) || (adytail != 0.0)
|| (bdxtail != 0.0) || (bdytail != 0.0))
{
ti1 = (double)(adxtail * bdy); c = (double)(splitter * adxtail); abig = (double)(c - adxtail); ahi = c - abig; alo = adxtail - ahi; c = (double)(splitter * bdy); abig = (double)(c - bdy); bhi = c - abig; blo = bdy - bhi; err1 = ti1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); ti0 = (alo * blo) - err3;
tj1 = (double)(adx * bdytail); c = (double)(splitter * adx); abig = (double)(c - adx); ahi = c - abig; alo = adx - ahi; c = (double)(splitter * bdytail); abig = (double)(c - bdytail); bhi = c - abig; blo = bdytail - bhi; err1 = tj1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); tj0 = (alo * blo) - err3;
_i = (double)(ti0 + tj0); bvirt = (double)(_i - ti0); avirt = _i - bvirt; bround = tj0 - bvirt; around = ti0 - avirt; u[0] = around + bround; _j = (double)(ti1 + _i); bvirt = (double)(_j - ti1); avirt = _j - bvirt; bround = _i - bvirt; around = ti1 - avirt; _0 = around + bround; _i = (double)(_0 + tj1); bvirt = (double)(_i - _0); avirt = _i - bvirt; bround = tj1 - bvirt; around = _0 - avirt; u[1] = around + bround; u3 = (double)(_j + _i); bvirt = (double)(u3 - _j); avirt = u3 - bvirt; bround = _i - bvirt; around = _j - avirt; u[2] = around + bround;
u[3] = u3;
negate = -ady;
ti1 = (double)(bdxtail * negate); c = (double)(splitter * bdxtail); abig = (double)(c - bdxtail); ahi = c - abig; alo = bdxtail - ahi; c = (double)(splitter * negate); abig = (double)(c - negate); bhi = c - abig; blo = negate - bhi; err1 = ti1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); ti0 = (alo * blo) - err3;
negate = -adytail;
tj1 = (double)(bdx * negate); c = (double)(splitter * bdx); abig = (double)(c - bdx); ahi = c - abig; alo = bdx - ahi; c = (double)(splitter * negate); abig = (double)(c - negate); bhi = c - abig; blo = negate - bhi; err1 = tj1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); tj0 = (alo * blo) - err3;
_i = (double)(ti0 + tj0); bvirt = (double)(_i - ti0); avirt = _i - bvirt; bround = tj0 - bvirt; around = ti0 - avirt; v[0] = around + bround; _j = (double)(ti1 + _i); bvirt = (double)(_j - ti1); avirt = _j - bvirt; bround = _i - bvirt; around = ti1 - avirt; _0 = around + bround; _i = (double)(_0 + tj1); bvirt = (double)(_i - _0); avirt = _i - bvirt; bround = tj1 - bvirt; around = _0 - avirt; v[1] = around + bround; v3 = (double)(_j + _i); bvirt = (double)(v3 - _j); avirt = v3 - bvirt; bround = _i - bvirt; around = _j - avirt; v[2] = around + bround;
v[3] = v3;
abtlen = FastExpansionSumZeroElim(4, u, 4, v, abt);
ti1 = (double)(adxtail * bdytail); c = (double)(splitter * adxtail); abig = (double)(c - adxtail); ahi = c - abig; alo = adxtail - ahi; c = (double)(splitter * bdytail); abig = (double)(c - bdytail); bhi = c - abig; blo = bdytail - bhi; err1 = ti1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); ti0 = (alo * blo) - err3;
tj1 = (double)(bdxtail * adytail); c = (double)(splitter * bdxtail); abig = (double)(c - bdxtail); ahi = c - abig; alo = bdxtail - ahi; c = (double)(splitter * adytail); abig = (double)(c - adytail); bhi = c - abig; blo = adytail - bhi; err1 = tj1 - (ahi * bhi); err2 = err1 - (alo * bhi); err3 = err2 - (ahi * blo); tj0 = (alo * blo) - err3;
_i = (double)(ti0 - tj0); bvirt = (double)(ti0 - _i); avirt = _i + bvirt; bround = bvirt - tj0; around = ti0 - avirt; abtt[0] = around + bround; _j = (double)(ti1 + _i); bvirt = (double)(_j - ti1); avirt = _j - bvirt; bround = _i - bvirt; around = ti1 - avirt; _0 = around + bround; _i = (double)(_0 - tj1); bvirt = (double)(_0 - _i); avirt = _i + bvirt; bround = bvirt - tj1; around = _0 - avirt; abtt[1] = around + bround; abtt3 = (double)(_j + _i); bvirt = (double)(abtt3 - _j); avirt = abtt3 - bvirt; bround = _i - bvirt; around = _j - avirt; abtt[2] = around + bround;
abtt[3] = abtt3;
abttlen = 4;
}
else
{
abt[0] = 0.0;
abtlen = 1;
abtt[0] = 0.0;
abttlen = 1;
}
if (cdxtail != 0.0)
{
temp16alen = ScaleExpansionZeroElim(cxtablen, cxtab, cdxtail, temp16a);
cxtabtlen = ScaleExpansionZeroElim(abtlen, abt, cdxtail, cxtabt);
temp32alen = ScaleExpansionZeroElim(cxtabtlen, cxtabt, 2.0 * cdx, temp32a);
temp48len = FastExpansionSumZeroElim(temp16alen, temp16a, temp32alen, temp32a, temp48);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp48len, temp48, finother);
finswap = finnow; finnow = finother; finother = finswap;
if (adytail != 0.0)
{
temp8len = ScaleExpansionZeroElim(4, bb, cdxtail, temp8);
temp16alen = ScaleExpansionZeroElim(temp8len, temp8, adytail, temp16a);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp16alen, temp16a, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
if (bdytail != 0.0)
{
temp8len = ScaleExpansionZeroElim(4, aa, -cdxtail, temp8);
temp16alen = ScaleExpansionZeroElim(temp8len, temp8, bdytail, temp16a);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp16alen, temp16a, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
temp32alen = ScaleExpansionZeroElim(cxtabtlen, cxtabt, cdxtail, temp32a);
cxtabttlen = ScaleExpansionZeroElim(abttlen, abtt, cdxtail, cxtabtt);
temp16alen = ScaleExpansionZeroElim(cxtabttlen, cxtabtt, 2.0 * cdx, temp16a);
temp16blen = ScaleExpansionZeroElim(cxtabttlen, cxtabtt, cdxtail, temp16b);
temp32blen = FastExpansionSumZeroElim(temp16alen, temp16a, temp16blen, temp16b, temp32b);
temp64len = FastExpansionSumZeroElim(temp32alen, temp32a, temp32blen, temp32b, temp64);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp64len, temp64, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
if (cdytail != 0.0)
{
temp16alen = ScaleExpansionZeroElim(cytablen, cytab, cdytail, temp16a);
cytabtlen = ScaleExpansionZeroElim(abtlen, abt, cdytail, cytabt);
temp32alen = ScaleExpansionZeroElim(cytabtlen, cytabt, 2.0 * cdy, temp32a);
temp48len = FastExpansionSumZeroElim(temp16alen, temp16a, temp32alen, temp32a, temp48);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp48len, temp48, finother);
finswap = finnow; finnow = finother; finother = finswap;
temp32alen = ScaleExpansionZeroElim(cytabtlen, cytabt, cdytail, temp32a);
cytabttlen = ScaleExpansionZeroElim(abttlen, abtt, cdytail, cytabtt);
temp16alen = ScaleExpansionZeroElim(cytabttlen, cytabtt, 2.0 * cdy, temp16a);
temp16blen = ScaleExpansionZeroElim(cytabttlen, cytabtt, cdytail, temp16b);
temp32blen = FastExpansionSumZeroElim(temp16alen, temp16a, temp16blen, temp16b, temp32b);
temp64len = FastExpansionSumZeroElim(temp32alen, temp32a, temp32blen, temp32b, temp64);
finlength = FastExpansionSumZeroElim(finlength, finnow, temp64len, temp64, finother);
finswap = finnow; finnow = finother; finother = finswap;
}
}
return finnow[finlength - 1];
}
#region Workspace
// InCircleAdapt workspace:
double[] fin1, fin2, abdet;
double[] axbc, axxbc, aybc, ayybc, adet;
double[] bxca, bxxca, byca, byyca, bdet;
double[] cxab, cxxab, cyab, cyyab, cdet;
double[] temp8, temp16a, temp16b, temp16c;
double[] temp32a, temp32b, temp48, temp64;
private void AllocateWorkspace()
{
fin1 = new double[1152];
fin2 = new double[1152];
abdet = new double[64];
axbc = new double[8];
axxbc = new double[16];
aybc = new double[8];
ayybc = new double[16];
adet = new double[32];
bxca = new double[8];
bxxca = new double[16];
byca = new double[8];
byyca = new double[16];
bdet = new double[32];
cxab = new double[8];
cxxab = new double[16];
cyab = new double[8];
cyyab = new double[16];
cdet = new double[32];
temp8 = new double[8];
temp16a = new double[16];
temp16b = new double[16];
temp16c = new double[16];
temp32a = new double[32];
temp32b = new double[32];
temp48 = new double[48];
temp64 = new double[64];
}
private void ClearWorkspace()
{
}
#endregion
#endregion
}
}