You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1974 lines
76 KiB
1974 lines
76 KiB
/****************************************************************************
|
|
* Indirect predicates for geometric constructions *
|
|
* *
|
|
* Consiglio Nazionale delle Ricerche *
|
|
* Istituto di Matematica Applicata e Tecnologie Informatiche *
|
|
* Sezione di Genova *
|
|
* IMATI-GE / CNR *
|
|
* *
|
|
* Authors: Marco Attene *
|
|
* Copyright(C) 2019: IMATI-GE / CNR *
|
|
* All rights reserved. *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU Lesser General Public License as published *
|
|
* by the Free Software Foundation; either version 3 of the License, or (at *
|
|
* your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, but *
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
|
|
* General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Lesser General Public License *
|
|
* along with this program. If not, see http://www.gnu.org/licenses/. *
|
|
* *
|
|
****************************************************************************/
|
|
|
|
#include "implicit_point.h"
|
|
#include "indirect_predicates.h"
|
|
|
|
int orient2d(double p1x, double p1y, double p2x, double p2y, double p3x, double p3y);
|
|
int orient3d(double px,
|
|
double py,
|
|
double pz,
|
|
double qx,
|
|
double qy,
|
|
double qz,
|
|
double rx,
|
|
double ry,
|
|
double rz,
|
|
double sx,
|
|
double sy,
|
|
double sz);
|
|
|
|
inline int lessThan_EE(double x1, double y1, double z1, double x2, double y2, double z2)
|
|
{
|
|
int ret;
|
|
if ((ret = ((x1 > x2) - (x1 < x2)))) return ret;
|
|
if ((ret = ((y1 > y2) - (y1 < y2)))) return ret;
|
|
return ((z1 > z2) - (z1 < z2));
|
|
}
|
|
|
|
inline int lessThan_IE(const genericPoint& p1, double x2, double y2, double z2)
|
|
{
|
|
int ret;
|
|
if ((ret = lessThanOnX_IE(p1, x2))) return ret;
|
|
if ((ret = lessThanOnY_IE(p1, y2))) return ret;
|
|
return lessThanOnZ_IE(p1, z2);
|
|
}
|
|
|
|
inline int lessThan_II(const genericPoint& p1, const genericPoint& p2)
|
|
{
|
|
int ret;
|
|
if ((ret = lessThanOnX_II(p1, p2))) return ret;
|
|
if ((ret = lessThanOnY_II(p1, p2))) return ret;
|
|
return lessThanOnZ_II(p1, p2);
|
|
}
|
|
|
|
inline int lessThan_EE(const genericPoint& a, const genericPoint& b)
|
|
{
|
|
return lessThan_EE(a.toExplicit3D().X(),
|
|
a.toExplicit3D().Y(),
|
|
a.toExplicit3D().Z(),
|
|
b.toExplicit3D().X(),
|
|
b.toExplicit3D().Y(),
|
|
b.toExplicit3D().Z());
|
|
}
|
|
|
|
inline int lessThan_IE(const genericPoint& a, const genericPoint& b)
|
|
{
|
|
return lessThan_IE(a, b.toExplicit3D().X(), b.toExplicit3D().Y(), b.toExplicit3D().Z());
|
|
}
|
|
|
|
inline int genericPoint::lessThan(const genericPoint& a, const genericPoint& b)
|
|
{
|
|
if (a.isExplicit3D() && b.isExplicit3D()) return lessThan_EE(a, b);
|
|
if (!a.isExplicit3D() && b.isExplicit3D()) return lessThan_IE(a, b);
|
|
if (a.isExplicit3D() && !b.isExplicit3D()) return -lessThan_IE(b, a);
|
|
return lessThan_II(a, b);
|
|
}
|
|
|
|
inline int lessThanOnX_IE(const genericPoint& a, const genericPoint& b) { return lessThanOnX_IE(a, b.toExplicit3D().X()); }
|
|
|
|
inline int genericPoint::lessThanOnX(const genericPoint& a, const genericPoint& b)
|
|
{
|
|
if (a.isExplicit3D() && b.isExplicit3D()) {
|
|
double av = a.toExplicit3D().X(), bv = b.toExplicit3D().X();
|
|
return ((av > bv) - (av < bv));
|
|
}
|
|
|
|
if (!a.isExplicit3D() && b.isExplicit3D()) return lessThanOnX_IE(a, b);
|
|
if (a.isExplicit3D() && !b.isExplicit3D()) return -lessThanOnX_IE(b, a);
|
|
return lessThanOnX_II(a, b);
|
|
}
|
|
|
|
inline int lessThanOnY_IE(const genericPoint& a, const genericPoint& b) { return lessThanOnY_IE(a, b.toExplicit3D().Y()); }
|
|
|
|
inline int genericPoint::lessThanOnY(const genericPoint& a, const genericPoint& b)
|
|
{
|
|
if (a.isExplicit3D() && b.isExplicit3D()) {
|
|
double av = a.toExplicit3D().Y(), bv = b.toExplicit3D().Y();
|
|
return ((av > bv) - (av < bv));
|
|
}
|
|
if (!a.isExplicit3D() && b.isExplicit3D()) return lessThanOnY_IE(a, b);
|
|
if (a.isExplicit3D() && !b.isExplicit3D()) return -lessThanOnY_IE(b, a);
|
|
return lessThanOnY_II(a, b);
|
|
}
|
|
|
|
inline int lessThanOnZ_IE(const genericPoint& a, const genericPoint& b) { return lessThanOnZ_IE(a, b.toExplicit3D().Z()); }
|
|
|
|
inline int genericPoint::lessThanOnZ(const genericPoint& a, const genericPoint& b)
|
|
{
|
|
if (a.isExplicit3D() && b.isExplicit3D()) {
|
|
double av = a.toExplicit3D().Z(), bv = b.toExplicit3D().Z();
|
|
return ((av > bv) - (av < bv));
|
|
}
|
|
if (!a.isExplicit3D() && b.isExplicit3D()) return lessThanOnZ_IE(a, b);
|
|
if (a.isExplicit3D() && !b.isExplicit3D()) return -lessThanOnZ_IE(b, a);
|
|
return lessThanOnZ_II(a, b);
|
|
}
|
|
|
|
inline int dotproductSign2D_EEE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return dotProductSign2D(a.toExplicit2D().X(),
|
|
a.toExplicit2D().Y(),
|
|
b.toExplicit2D().X(),
|
|
b.toExplicit2D().Y(),
|
|
c.toExplicit2D().X(),
|
|
c.toExplicit2D().Y());
|
|
}
|
|
|
|
inline int dotproductSign2D_IEE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return dotProductSign2D_IEE(a, b.toExplicit2D().X(), b.toExplicit2D().Y(), c.toExplicit2D().X(), c.toExplicit2D().Y());
|
|
}
|
|
|
|
inline int dotproductSign2D_IIE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return dotProductSign2D_IIE(a, b, c.toExplicit2D().X(), c.toExplicit2D().Y());
|
|
}
|
|
|
|
inline int dotproductSign2D_III(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return dotProductSign2D_III(a, b, c);
|
|
}
|
|
|
|
inline int dotproductSign2D_EEI(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return dotProductSign2D_EEI(c, a.toExplicit2D().X(), a.toExplicit2D().Y(), b.toExplicit2D().X(), b.toExplicit2D().Y());
|
|
}
|
|
|
|
inline int dotproductSign2D_IEI(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return dotProductSign2D_IEI(a, c, b.toExplicit2D().X(), b.toExplicit2D().Y());
|
|
}
|
|
|
|
inline int genericPoint::dotProductSign2D(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
if (a.isExplicit2D() && b.isExplicit2D() && c.isExplicit2D()) return dotproductSign2D_EEE(a, b, c);
|
|
if (a.isSSI() && b.isExplicit2D() && c.isExplicit2D()) return dotproductSign2D_IEE(a, b, c);
|
|
if (a.isExplicit2D() && b.isSSI() && c.isExplicit2D()) return dotproductSign2D_IEE(b, a, c);
|
|
if (a.isExplicit2D() && b.isExplicit2D() && c.isSSI()) return dotproductSign2D_EEI(a, b, c);
|
|
if (a.isSSI() && b.isSSI() && c.isExplicit2D()) return dotproductSign2D_IIE(a, b, c);
|
|
if (a.isExplicit2D() && b.isSSI() && c.isSSI()) return dotproductSign2D_IEI(b, a, c);
|
|
if (a.isSSI() && b.isExplicit2D() && c.isSSI()) return dotproductSign2D_IEI(a, b, c);
|
|
return dotproductSign2D_III(a, b, c);
|
|
}
|
|
|
|
inline int dotproductSign3D_EEE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return dotProductSign3D(a.toExplicit3D().X(),
|
|
a.toExplicit3D().Y(),
|
|
a.toExplicit3D().Z(),
|
|
b.toExplicit3D().X(),
|
|
b.toExplicit3D().Y(),
|
|
b.toExplicit3D().Z(),
|
|
c.toExplicit3D().X(),
|
|
c.toExplicit3D().Y(),
|
|
c.toExplicit3D().Z());
|
|
}
|
|
|
|
inline int dotproductSign3D_IEE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return dotProductSign3D_IEE(a,
|
|
b.toExplicit3D().X(),
|
|
b.toExplicit3D().Y(),
|
|
b.toExplicit3D().Z(),
|
|
c.toExplicit3D().X(),
|
|
c.toExplicit3D().Y(),
|
|
c.toExplicit3D().Z());
|
|
}
|
|
|
|
inline int dotproductSign3D_IIE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return dotProductSign3D_IIE(a, b, c.toExplicit3D().X(), c.toExplicit3D().Y(), c.toExplicit3D().Z());
|
|
}
|
|
|
|
inline int dotproductSign3D_III(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return dotProductSign3D_III(a, b, c);
|
|
}
|
|
|
|
inline int dotproductSign3D_EEI(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return dotProductSign3D_EEI(c,
|
|
a.toExplicit3D().X(),
|
|
a.toExplicit3D().Y(),
|
|
a.toExplicit3D().Z(),
|
|
b.toExplicit3D().X(),
|
|
b.toExplicit3D().Y(),
|
|
b.toExplicit3D().Z());
|
|
}
|
|
|
|
inline int dotproductSign3D_IEI(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return dotProductSign3D_IEI(a, c, b.toExplicit3D().X(), b.toExplicit3D().Y(), b.toExplicit3D().Z());
|
|
}
|
|
|
|
inline int genericPoint::dotProductSign3D(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
if (a.isExplicit3D() && b.isExplicit3D() && c.isExplicit3D()) return dotproductSign3D_EEE(a, b, c);
|
|
if (!a.isExplicit3D() && b.isExplicit3D() && c.isExplicit3D()) return dotproductSign3D_IEE(a, b, c);
|
|
if (a.isExplicit3D() && !b.isExplicit3D() && c.isExplicit3D()) return dotproductSign3D_IEE(b, a, c);
|
|
if (a.isExplicit3D() && b.isExplicit3D() && !c.isExplicit3D()) return dotproductSign3D_EEI(a, b, c);
|
|
if (!a.isExplicit3D() && !b.isExplicit3D() && c.isExplicit3D()) return dotproductSign3D_IIE(a, b, c);
|
|
if (a.isExplicit3D() && !b.isExplicit3D() && !c.isExplicit3D()) return dotproductSign3D_IEI(b, a, c);
|
|
if (!a.isExplicit3D() && b.isExplicit3D() && !c.isExplicit3D()) return dotproductSign3D_IEI(a, b, c);
|
|
return dotproductSign3D_III(a, b, c);
|
|
}
|
|
|
|
inline int orient2d_EEE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return orient2d(a.toExplicit2D().X(),
|
|
a.toExplicit2D().Y(),
|
|
b.toExplicit2D().X(),
|
|
b.toExplicit2D().Y(),
|
|
c.toExplicit2D().X(),
|
|
c.toExplicit2D().Y());
|
|
}
|
|
|
|
inline int orient2d_IEE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return orient2d_indirect_IEE(a, b.toExplicit2D().X(), b.toExplicit2D().Y(), c.toExplicit2D().X(), c.toExplicit2D().Y());
|
|
}
|
|
|
|
inline int orient2d_IIE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return orient2d_indirect_IIE(a, b, c.toExplicit2D().X(), c.toExplicit2D().Y());
|
|
}
|
|
|
|
inline int orient2d_III(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return orient2d_indirect_III(a, b, c);
|
|
}
|
|
|
|
inline int genericPoint::orient2D(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
// Here we implicitly assume that points are 2D. Do not check.
|
|
|
|
if (a.isExplicit2D() && b.isExplicit2D() && c.isExplicit2D()) return orient2d_EEE(a, b, c);
|
|
if (a.isSSI() && b.isExplicit2D() && c.isExplicit2D()) return orient2d_IEE(a, b, c);
|
|
if (a.isExplicit2D() && b.isSSI() && c.isExplicit2D()) return orient2d_IEE(b, c, a);
|
|
if (a.isExplicit2D() && b.isExplicit2D() && c.isSSI()) return orient2d_IEE(c, a, b);
|
|
if (a.isSSI() && b.isSSI() && c.isExplicit2D()) return orient2d_IIE(a, b, c);
|
|
if (a.isExplicit2D() && b.isSSI() && c.isSSI()) return orient2d_IIE(b, c, a);
|
|
if (a.isSSI() && b.isExplicit2D() && c.isSSI()) return orient2d_IIE(c, a, b);
|
|
return orient2d_III(a, b, c);
|
|
}
|
|
|
|
inline int orient2dxy_EEE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return orient2d(a.toExplicit3D().X(),
|
|
a.toExplicit3D().Y(),
|
|
b.toExplicit3D().X(),
|
|
b.toExplicit3D().Y(),
|
|
c.toExplicit3D().X(),
|
|
c.toExplicit3D().Y());
|
|
}
|
|
|
|
inline int orient2dxy_IEE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return orient2dxy_indirect_IEE(a, b.toExplicit3D().X(), b.toExplicit3D().Y(), c.toExplicit3D().X(), c.toExplicit3D().Y());
|
|
}
|
|
|
|
inline int orient2dxy_IIE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return orient2dxy_indirect_IIE(a, b, c.toExplicit3D().X(), c.toExplicit3D().Y());
|
|
}
|
|
|
|
inline int orient2dxy_III(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return orient2dxy_indirect_III(a, b, c);
|
|
}
|
|
|
|
inline int genericPoint::orient2Dxy(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
if (a.isExplicit3D() && b.isExplicit3D() && c.isExplicit3D()) return orient2dxy_EEE(a, b, c);
|
|
|
|
if (!a.isExplicit3D() && b.isExplicit3D() && c.isExplicit3D()) return orient2dxy_IEE(a, b, c);
|
|
if (a.isExplicit3D() && !b.isExplicit3D() && c.isExplicit3D()) return orient2dxy_IEE(b, c, a);
|
|
if (a.isExplicit3D() && b.isExplicit3D() && !c.isExplicit3D()) return orient2dxy_IEE(c, a, b);
|
|
|
|
if (!a.isExplicit3D() && !b.isExplicit3D() && c.isExplicit3D()) return orient2dxy_IIE(a, b, c);
|
|
if (!a.isExplicit3D() && b.isExplicit3D() && !c.isExplicit3D()) return orient2dxy_IIE(c, a, b);
|
|
if (a.isExplicit3D() && !b.isExplicit3D() && !c.isExplicit3D()) return orient2dxy_IIE(b, c, a);
|
|
|
|
return orient2dxy_III(a, b, c);
|
|
}
|
|
|
|
inline int orient2dyz_EEE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return orient2d(a.toExplicit3D().Y(),
|
|
a.toExplicit3D().Z(),
|
|
b.toExplicit3D().Y(),
|
|
b.toExplicit3D().Z(),
|
|
c.toExplicit3D().Y(),
|
|
c.toExplicit3D().Z());
|
|
}
|
|
|
|
inline int orient2dyz_IEE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return orient2dyz_indirect_IEE(a, b.toExplicit3D().Y(), b.toExplicit3D().Z(), c.toExplicit3D().Y(), c.toExplicit3D().Z());
|
|
}
|
|
|
|
inline int orient2dyz_IIE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return orient2dyz_indirect_IIE(a, b, c.toExplicit3D().Y(), c.toExplicit3D().Z());
|
|
}
|
|
|
|
inline int orient2dyz_III(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return orient2dyz_indirect_III(a, b, c);
|
|
}
|
|
|
|
inline int genericPoint::orient2Dyz(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
if (a.isExplicit3D() && b.isExplicit3D() && c.isExplicit3D()) return orient2dyz_EEE(a, b, c);
|
|
|
|
if (!a.isExplicit3D() && b.isExplicit3D() && c.isExplicit3D()) return orient2dyz_IEE(a, b, c);
|
|
if (a.isExplicit3D() && !b.isExplicit3D() && c.isExplicit3D()) return orient2dyz_IEE(b, c, a);
|
|
if (a.isExplicit3D() && b.isExplicit3D() && !c.isExplicit3D()) return orient2dyz_IEE(c, a, b);
|
|
|
|
if (!a.isExplicit3D() && !b.isExplicit3D() && c.isExplicit3D()) return orient2dyz_IIE(a, b, c);
|
|
if (!a.isExplicit3D() && b.isExplicit3D() && !c.isExplicit3D()) return orient2dyz_IIE(c, a, b);
|
|
if (a.isExplicit3D() && !b.isExplicit3D() && !c.isExplicit3D()) return orient2dyz_IIE(b, c, a);
|
|
|
|
return orient2dyz_III(a, b, c);
|
|
}
|
|
|
|
inline int orient2dzx_EEE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return orient2d(a.toExplicit3D().Z(),
|
|
a.toExplicit3D().X(),
|
|
b.toExplicit3D().Z(),
|
|
b.toExplicit3D().X(),
|
|
c.toExplicit3D().Z(),
|
|
c.toExplicit3D().X());
|
|
}
|
|
|
|
inline int orient2dzx_IEE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return orient2dzx_indirect_IEE(a, b.toExplicit3D().Z(), b.toExplicit3D().X(), c.toExplicit3D().Z(), c.toExplicit3D().X());
|
|
}
|
|
|
|
inline int orient2dzx_IIE(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return orient2dzx_indirect_IIE(a, b, c.toExplicit3D().Z(), c.toExplicit3D().X());
|
|
}
|
|
|
|
inline int orient2dzx_III(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
return orient2dzx_indirect_III(a, b, c);
|
|
}
|
|
|
|
inline int genericPoint::orient2Dzx(const genericPoint& a, const genericPoint& b, const genericPoint& c)
|
|
{
|
|
if (a.isExplicit3D() && b.isExplicit3D() && c.isExplicit3D()) return orient2dzx_EEE(a, b, c);
|
|
|
|
if (!a.isExplicit3D() && b.isExplicit3D() && c.isExplicit3D()) return orient2dzx_IEE(a, b, c);
|
|
if (a.isExplicit3D() && !b.isExplicit3D() && c.isExplicit3D()) return orient2dzx_IEE(b, c, a);
|
|
if (a.isExplicit3D() && b.isExplicit3D() && !c.isExplicit3D()) return orient2dzx_IEE(c, a, b);
|
|
|
|
if (!a.isExplicit3D() && !b.isExplicit3D() && c.isExplicit3D()) return orient2dzx_IIE(a, b, c);
|
|
if (!a.isExplicit3D() && b.isExplicit3D() && !c.isExplicit3D()) return orient2dzx_IIE(c, a, b);
|
|
if (a.isExplicit3D() && !b.isExplicit3D() && !c.isExplicit3D()) return orient2dzx_IIE(b, c, a);
|
|
|
|
return orient2dzx_III(a, b, c);
|
|
}
|
|
|
|
inline int orient3d_EEEE(const genericPoint& a, const genericPoint& b, const genericPoint& c, const genericPoint& d)
|
|
{
|
|
return orient3d(a.toExplicit3D().X(),
|
|
a.toExplicit3D().Y(),
|
|
a.toExplicit3D().Z(),
|
|
b.toExplicit3D().X(),
|
|
b.toExplicit3D().Y(),
|
|
b.toExplicit3D().Z(),
|
|
c.toExplicit3D().X(),
|
|
c.toExplicit3D().Y(),
|
|
c.toExplicit3D().Z(),
|
|
d.toExplicit3D().X(),
|
|
d.toExplicit3D().Y(),
|
|
d.toExplicit3D().Z());
|
|
}
|
|
|
|
inline int orient3d_IEEE(const genericPoint& a, const genericPoint& b, const genericPoint& c, const genericPoint& d)
|
|
{
|
|
return orient3d_indirect_IEEE(a,
|
|
b.toExplicit3D().X(),
|
|
b.toExplicit3D().Y(),
|
|
b.toExplicit3D().Z(),
|
|
c.toExplicit3D().X(),
|
|
c.toExplicit3D().Y(),
|
|
c.toExplicit3D().Z(),
|
|
d.toExplicit3D().X(),
|
|
d.toExplicit3D().Y(),
|
|
d.toExplicit3D().Z());
|
|
}
|
|
|
|
inline int orient3d_IIEE(const genericPoint& a, const genericPoint& b, const genericPoint& c, const genericPoint& d)
|
|
{
|
|
return orient3d_indirect_IIEE(a,
|
|
b,
|
|
c.toExplicit3D().X(),
|
|
c.toExplicit3D().Y(),
|
|
c.toExplicit3D().Z(),
|
|
d.toExplicit3D().X(),
|
|
d.toExplicit3D().Y(),
|
|
d.toExplicit3D().Z());
|
|
}
|
|
|
|
inline int orient3d_IIIE(const genericPoint& a, const genericPoint& b, const genericPoint& c, const genericPoint& d)
|
|
{
|
|
return orient3d_indirect_IIIE(a, b, c, d.toExplicit3D().X(), d.toExplicit3D().Y(), d.toExplicit3D().Z());
|
|
}
|
|
|
|
inline int genericPoint::orient3D(const genericPoint& a, const genericPoint& b, const genericPoint& c, const genericPoint& d)
|
|
{
|
|
// Here we implicitly assume that points are 3D. Do not check.
|
|
|
|
const int i = a.isExplicit3D() + b.isExplicit3D() + c.isExplicit3D() + d.isExplicit3D();
|
|
|
|
if (i == 4) return orient3d_EEEE(a, b, c, d);
|
|
|
|
if (i == 3) {
|
|
if (!a.isExplicit3D()) return orient3d_IEEE(a, b, c, d);
|
|
if (!b.isExplicit3D()) return orient3d_IEEE(b, c, a, d);
|
|
if (!c.isExplicit3D()) return orient3d_IEEE(c, d, a, b);
|
|
return orient3d_IEEE(d, a, c, b);
|
|
}
|
|
|
|
if (i == 2) {
|
|
if (c.isExplicit3D() && d.isExplicit3D()) return orient3d_IIEE(a, b, c, d);
|
|
if (b.isExplicit3D() && d.isExplicit3D()) return orient3d_IIEE(a, c, d, b);
|
|
if (a.isExplicit3D() && d.isExplicit3D()) return orient3d_IIEE(b, c, a, d);
|
|
if (b.isExplicit3D() && c.isExplicit3D()) return orient3d_IIEE(d, a, c, b);
|
|
if (a.isExplicit3D() && c.isExplicit3D()) return orient3d_IIEE(d, b, a, c);
|
|
return orient3d_IIEE(c, d, a, b);
|
|
}
|
|
|
|
if (i == 1) {
|
|
if (d.isExplicit3D()) return orient3d_IIIE(a, b, c, d);
|
|
if (c.isExplicit3D()) return orient3d_IIIE(d, b, a, c);
|
|
if (b.isExplicit3D()) return orient3d_IIIE(a, c, d, b);
|
|
return orient3d_IIIE(b, d, c, a);
|
|
}
|
|
|
|
return orient3d_indirect_IIII(a, b, c, d);
|
|
}
|
|
|
|
inline int inSphere_IEEEE(const genericPoint& a,
|
|
const genericPoint& b,
|
|
const genericPoint& c,
|
|
const genericPoint& d,
|
|
const genericPoint& e)
|
|
{
|
|
return inSphere_IEEEE(a,
|
|
b.toExplicit3D().X(),
|
|
b.toExplicit3D().Y(),
|
|
b.toExplicit3D().Z(),
|
|
c.toExplicit3D().X(),
|
|
c.toExplicit3D().Y(),
|
|
c.toExplicit3D().Z(),
|
|
d.toExplicit3D().X(),
|
|
d.toExplicit3D().Y(),
|
|
d.toExplicit3D().Z(),
|
|
e.toExplicit3D().X(),
|
|
e.toExplicit3D().Y(),
|
|
e.toExplicit3D().Z());
|
|
}
|
|
|
|
inline int inSphere_IIEEE(const genericPoint& a,
|
|
const genericPoint& b,
|
|
const genericPoint& c,
|
|
const genericPoint& d,
|
|
const genericPoint& e)
|
|
{
|
|
return inSphere_IIEEE(a,
|
|
b,
|
|
c.toExplicit3D().X(),
|
|
c.toExplicit3D().Y(),
|
|
c.toExplicit3D().Z(),
|
|
d.toExplicit3D().X(),
|
|
d.toExplicit3D().Y(),
|
|
d.toExplicit3D().Z(),
|
|
e.toExplicit3D().X(),
|
|
e.toExplicit3D().Y(),
|
|
e.toExplicit3D().Z());
|
|
}
|
|
|
|
inline int inSphere_IIIEE(const genericPoint& a,
|
|
const genericPoint& b,
|
|
const genericPoint& c,
|
|
const genericPoint& d,
|
|
const genericPoint& e)
|
|
{
|
|
return inSphere_IIIEE(a,
|
|
b,
|
|
c,
|
|
d.toExplicit3D().X(),
|
|
d.toExplicit3D().Y(),
|
|
d.toExplicit3D().Z(),
|
|
e.toExplicit3D().X(),
|
|
e.toExplicit3D().Y(),
|
|
e.toExplicit3D().Z());
|
|
}
|
|
|
|
inline int inSphere_IIIIE(const genericPoint& a,
|
|
const genericPoint& b,
|
|
const genericPoint& c,
|
|
const genericPoint& d,
|
|
const genericPoint& e)
|
|
{
|
|
return inSphere_IIIIE(a, b, c, d, e.toExplicit3D().X(), e.toExplicit3D().Y(), e.toExplicit3D().Z());
|
|
}
|
|
|
|
#define USE_LOOKUP
|
|
|
|
#ifndef USE_LOOKUP
|
|
|
|
inline int genericPoint::inSphere(const genericPoint& a,
|
|
const genericPoint& b,
|
|
const genericPoint& c,
|
|
const genericPoint& d,
|
|
const genericPoint& e)
|
|
{
|
|
const int num_explicit = a.isExplicit3D() + b.isExplicit3D() + c.isExplicit3D() + d.isExplicit3D() + e.isExplicit3D();
|
|
|
|
if (num_explicit == 5)
|
|
return ::inSphere(a.toExplicit3D().X(),
|
|
a.toExplicit3D().Y(),
|
|
a.toExplicit3D().Z(),
|
|
b.toExplicit3D().X(),
|
|
b.toExplicit3D().Y(),
|
|
b.toExplicit3D().Z(),
|
|
c.toExplicit3D().X(),
|
|
c.toExplicit3D().Y(),
|
|
c.toExplicit3D().Z(),
|
|
d.toExplicit3D().X(),
|
|
d.toExplicit3D().Y(),
|
|
d.toExplicit3D().Z(),
|
|
e.toExplicit3D().X(),
|
|
e.toExplicit3D().Y(),
|
|
e.toExplicit3D().Z());
|
|
|
|
const genericPoint* A[5] = {&a, &b, &c, &d, &e};
|
|
|
|
// Sort points so that I < E
|
|
bool swapped = true;
|
|
int sign_swap = 1;
|
|
|
|
while (swapped) {
|
|
swapped = false;
|
|
for (int i = 0; i < 4; i++) {
|
|
if (A[i]->isExplicit3D() && !A[i + 1]->isExplicit3D()) {
|
|
std::swap(A[i], A[i + 1]);
|
|
swapped = true;
|
|
sign_swap *= -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (num_explicit == 4) return sign_swap * inSphere_IEEEE(*A[0], *A[1], *A[2], *A[3], *A[4]);
|
|
if (num_explicit == 3) return sign_swap * inSphere_IIEEE(*A[0], *A[1], *A[2], *A[3], *A[4]);
|
|
if (num_explicit == 2) return sign_swap * inSphere_IIIEE(*A[0], *A[1], *A[2], *A[3], *A[4]);
|
|
if (num_explicit == 1) return sign_swap * inSphere_IIIIE(*A[0], *A[1], *A[2], *A[3], *A[4]);
|
|
return sign_swap * inSphere_IIIII(*A[0], *A[1], *A[2], *A[3], *A[4]);
|
|
}
|
|
#else
|
|
|
|
inline int genericPoint::inSphere(const genericPoint& a,
|
|
const genericPoint& b,
|
|
const genericPoint& c,
|
|
const genericPoint& d,
|
|
const genericPoint& e)
|
|
{
|
|
const int num_explicit = a.isExplicit3D() + b.isExplicit3D() + c.isExplicit3D() + d.isExplicit3D() + e.isExplicit3D();
|
|
|
|
if (num_explicit == 5)
|
|
return ::inSphere(a.toExplicit3D().X(),
|
|
a.toExplicit3D().Y(),
|
|
a.toExplicit3D().Z(),
|
|
b.toExplicit3D().X(),
|
|
b.toExplicit3D().Y(),
|
|
b.toExplicit3D().Z(),
|
|
c.toExplicit3D().X(),
|
|
c.toExplicit3D().Y(),
|
|
c.toExplicit3D().Z(),
|
|
d.toExplicit3D().X(),
|
|
d.toExplicit3D().Y(),
|
|
d.toExplicit3D().Z(),
|
|
e.toExplicit3D().X(),
|
|
e.toExplicit3D().Y(),
|
|
e.toExplicit3D().Z());
|
|
|
|
const genericPoint* A[5] = {&a, &b, &c, &d, &e};
|
|
|
|
static const int is_lookup[] = {
|
|
1, 0, 1, 2, 3, 4, // 00000
|
|
1, 0, 1, 2, 3, 4, // 00001
|
|
-1, 0, 1, 2, 4, 3, // 00010
|
|
1, 0, 1, 2, 3, 4, // 00011
|
|
1, 0, 1, 3, 4, 2, // 00100
|
|
-1, 0, 1, 3, 2, 4, // 00101
|
|
1, 0, 1, 4, 2, 3, // 00110
|
|
1, 0, 1, 2, 3, 4, // 00111
|
|
-1, 0, 2, 3, 4, 1, // 01000
|
|
1, 0, 2, 3, 1, 4, // 01001
|
|
-1, 0, 2, 4, 1, 3, // 01010
|
|
-1, 0, 2, 1, 3, 4, // 01011
|
|
1, 0, 3, 4, 1, 2, // 01100
|
|
1, 0, 3, 1, 2, 4, // 01101
|
|
-1, 0, 4, 1, 2, 3, // 01110
|
|
1, 0, 1, 2, 3, 4, // 01111
|
|
1, 1, 2, 3, 4, 0, // 10000
|
|
-1, 1, 2, 3, 0, 4, // 10001
|
|
1, 1, 2, 4, 0, 3, // 10010
|
|
1, 1, 2, 0, 3, 4, // 10011
|
|
-1, 1, 3, 4, 0, 2, // 10100
|
|
-1, 1, 3, 0, 2, 4, // 10101
|
|
1, 1, 4, 0, 2, 3, // 10110
|
|
-1, 1, 0, 2, 3, 4, // 10111
|
|
1, 2, 3, 4, 0, 1, // 11000
|
|
1, 2, 3, 0, 1, 4, // 11001
|
|
-1, 2, 4, 0, 1, 3, // 11010
|
|
1, 2, 0, 1, 3, 4, // 11011
|
|
1, 3, 4, 0, 1, 2, // 11100
|
|
-1, 3, 0, 1, 2, 4, // 11101
|
|
1, 4, 0, 1, 2, 3, // 11110
|
|
1, 0, 1, 2, 3, 4 // 11111
|
|
};
|
|
|
|
const int idx = (a.isExplicit3D() << 4) + (b.isExplicit3D() << 3) + (c.isExplicit3D() << 2) + (d.isExplicit3D() << 1)
|
|
+ e.isExplicit3D();
|
|
const int* cfg = is_lookup + idx * 6;
|
|
|
|
if (num_explicit == 4) return cfg[0] * inSphere_IEEEE(*A[cfg[1]], *A[cfg[2]], *A[cfg[3]], *A[cfg[4]], *A[cfg[5]]);
|
|
if (num_explicit == 3) return cfg[0] * inSphere_IIEEE(*A[cfg[1]], *A[cfg[2]], *A[cfg[3]], *A[cfg[4]], *A[cfg[5]]);
|
|
if (num_explicit == 2) return cfg[0] * inSphere_IIIEE(*A[cfg[1]], *A[cfg[2]], *A[cfg[3]], *A[cfg[4]], *A[cfg[5]]);
|
|
if (num_explicit == 1) return cfg[0] * inSphere_IIIIE(*A[cfg[1]], *A[cfg[2]], *A[cfg[3]], *A[cfg[4]], *A[cfg[5]]);
|
|
return cfg[0] * inSphere_IIIII(*A[cfg[1]], *A[cfg[2]], *A[cfg[3]], *A[cfg[4]], *A[cfg[5]]);
|
|
}
|
|
#endif
|
|
|
|
inline int incircle2d_EEEE(const genericPoint& a, const genericPoint& b, const genericPoint& c, const genericPoint& d)
|
|
{
|
|
return incircle(a.toExplicit2D().X(),
|
|
a.toExplicit2D().Y(),
|
|
b.toExplicit2D().X(),
|
|
b.toExplicit2D().Y(),
|
|
c.toExplicit2D().X(),
|
|
c.toExplicit2D().Y(),
|
|
d.toExplicit2D().X(),
|
|
d.toExplicit2D().Y());
|
|
}
|
|
|
|
inline int incircle2d_IEEE(const genericPoint& a, const genericPoint& b, const genericPoint& c, const genericPoint& d)
|
|
{
|
|
return incircle_indirect_IEEE(a,
|
|
b.toExplicit2D().X(),
|
|
b.toExplicit2D().Y(),
|
|
c.toExplicit2D().X(),
|
|
c.toExplicit2D().Y(),
|
|
d.toExplicit2D().X(),
|
|
d.toExplicit2D().Y());
|
|
}
|
|
|
|
inline int incircle2d_IIEE(const genericPoint& a, const genericPoint& b, const genericPoint& c, const genericPoint& d)
|
|
{
|
|
return incircle_indirect_IIEE(a, b, c.toExplicit2D().X(), c.toExplicit2D().Y(), d.toExplicit2D().X(), d.toExplicit2D().Y());
|
|
}
|
|
|
|
inline int incircle2d_IIIE(const genericPoint& a, const genericPoint& b, const genericPoint& c, const genericPoint& d)
|
|
{
|
|
return incircle_indirect_IIIE(a, b, c, d.toExplicit2D().X(), d.toExplicit2D().Y());
|
|
}
|
|
|
|
inline int genericPoint::incircle(const genericPoint& a, const genericPoint& b, const genericPoint& c, const genericPoint& d)
|
|
{
|
|
const int i = a.isExplicit2D() + b.isExplicit2D() + c.isExplicit2D() + d.isExplicit2D();
|
|
|
|
if (i == 4) return incircle2d_EEEE(a, b, c, d);
|
|
|
|
if (i == 3) {
|
|
if (!a.isExplicit2D()) return incircle2d_IEEE(a, b, c, d);
|
|
if (!b.isExplicit2D()) return incircle2d_IEEE(b, c, a, d);
|
|
if (!c.isExplicit2D()) return incircle2d_IEEE(c, d, a, b);
|
|
return incircle2d_IEEE(d, a, c, b);
|
|
}
|
|
|
|
if (i == 2) {
|
|
if (c.isExplicit2D() && d.isExplicit2D()) return incircle2d_IIEE(a, b, c, d);
|
|
if (b.isExplicit2D() && d.isExplicit2D()) return incircle2d_IIEE(a, c, d, b);
|
|
if (a.isExplicit2D() && d.isExplicit2D()) return incircle2d_IIEE(b, c, a, d);
|
|
if (b.isExplicit2D() && c.isExplicit2D()) return incircle2d_IIEE(d, a, c, b);
|
|
if (a.isExplicit2D() && c.isExplicit2D()) return incircle2d_IIEE(d, b, a, c);
|
|
return incircle2d_IIEE(c, d, a, b);
|
|
}
|
|
|
|
if (i == 1) {
|
|
if (d.isExplicit2D()) return incircle2d_IIIE(a, b, c, d);
|
|
if (c.isExplicit2D()) return incircle2d_IIIE(d, b, a, c);
|
|
if (b.isExplicit2D()) return incircle2d_IIIE(a, c, d, b);
|
|
return incircle2d_IIIE(b, d, c, a);
|
|
}
|
|
|
|
return incircle_indirect_IIII(a, b, c, d);
|
|
}
|
|
|
|
inline int incircle2dxy_EEEE(const genericPoint& a, const genericPoint& b, const genericPoint& c, const genericPoint& d)
|
|
{
|
|
return incircle(a.toExplicit3D().X(),
|
|
a.toExplicit3D().Y(),
|
|
b.toExplicit3D().X(),
|
|
b.toExplicit3D().Y(),
|
|
c.toExplicit3D().X(),
|
|
c.toExplicit3D().Y(),
|
|
d.toExplicit3D().X(),
|
|
d.toExplicit3D().Y());
|
|
}
|
|
|
|
inline int incircle2dxy_IEEE(const genericPoint& a, const genericPoint& b, const genericPoint& c, const genericPoint& d)
|
|
{
|
|
return incirclexy_indirect_IEEE(a,
|
|
b.toExplicit3D().X(),
|
|
b.toExplicit3D().Y(),
|
|
c.toExplicit3D().X(),
|
|
c.toExplicit3D().Y(),
|
|
d.toExplicit3D().X(),
|
|
d.toExplicit3D().Y());
|
|
}
|
|
|
|
inline int incircle2dxy_IIEE(const genericPoint& a, const genericPoint& b, const genericPoint& c, const genericPoint& d)
|
|
{
|
|
return incirclexy_indirect_IIEE(a,
|
|
b,
|
|
c.toExplicit3D().X(),
|
|
c.toExplicit3D().Y(),
|
|
d.toExplicit3D().X(),
|
|
d.toExplicit3D().Y());
|
|
}
|
|
|
|
inline int incircle2dxy_IIIE(const genericPoint& a, const genericPoint& b, const genericPoint& c, const genericPoint& d)
|
|
{
|
|
return incirclexy_indirect_IIIE(a, b, c, d.toExplicit3D().X(), d.toExplicit3D().Y());
|
|
}
|
|
|
|
inline int genericPoint::incirclexy(const genericPoint& a, const genericPoint& b, const genericPoint& c, const genericPoint& d)
|
|
{
|
|
int i = a.isExplicit3D() + b.isExplicit3D() + c.isExplicit3D() + d.isExplicit3D();
|
|
|
|
if (i == 4) return incircle2dxy_EEEE(a, b, c, d);
|
|
|
|
if (i == 3) {
|
|
if (!a.isExplicit3D()) return incircle2dxy_IEEE(a, b, c, d);
|
|
if (!b.isExplicit3D()) return incircle2dxy_IEEE(b, c, a, d);
|
|
if (!c.isExplicit3D()) return incircle2dxy_IEEE(c, d, a, b);
|
|
return incircle2dxy_IEEE(d, a, c, b);
|
|
}
|
|
|
|
if (i == 2) {
|
|
if (c.isExplicit3D() && d.isExplicit3D()) return incircle2dxy_IIEE(a, b, c, d);
|
|
if (b.isExplicit3D() && d.isExplicit3D()) return incircle2dxy_IIEE(a, c, d, b);
|
|
if (a.isExplicit3D() && d.isExplicit3D()) return incircle2dxy_IIEE(b, c, a, d);
|
|
if (b.isExplicit3D() && c.isExplicit3D()) return incircle2dxy_IIEE(d, a, c, b);
|
|
if (a.isExplicit3D() && c.isExplicit3D()) return incircle2dxy_IIEE(d, b, a, c);
|
|
return incircle2dxy_IIEE(c, d, a, b);
|
|
}
|
|
|
|
if (i == 1) {
|
|
if (d.isExplicit3D()) return incircle2dxy_IIIE(a, b, c, d);
|
|
if (c.isExplicit3D()) return incircle2dxy_IIIE(d, b, a, c);
|
|
if (b.isExplicit3D()) return incircle2dxy_IIIE(a, c, d, b);
|
|
return incircle2dxy_IIIE(b, d, c, a);
|
|
}
|
|
|
|
return incirclexy_indirect_IIII(a, b, c, d);
|
|
}
|
|
|
|
// These functions assume that point is an SSI
|
|
inline bool genericPoint::getIntervalLambda(interval_number& lx, interval_number& ly, interval_number& d) const
|
|
{
|
|
return toSSI().getIntervalLambda(lx, ly, d);
|
|
}
|
|
|
|
inline void genericPoint::getExactLambda(double** lx, int& lxl, double** ly, int& lyl, double** d, int& dl) const
|
|
{
|
|
toSSI().getExactLambda(lx, lxl, ly, lyl, d, dl);
|
|
}
|
|
|
|
inline void genericPoint::getBigfloatLambda(bigfloat& lx, bigfloat& ly, bigfloat& d) const
|
|
{
|
|
toSSI().getBigfloatLambda(lx, ly, d);
|
|
}
|
|
|
|
// These functions assume that point is an implicit 3D
|
|
inline bool genericPoint::getIntervalLambda(interval_number& lx,
|
|
interval_number& ly,
|
|
interval_number& lz,
|
|
interval_number& d) const
|
|
{
|
|
if (isLPI())
|
|
return toLPI().getIntervalLambda(lx, ly, lz, d);
|
|
else if (isTPI())
|
|
return toTPI().getIntervalLambda(lx, ly, lz, d);
|
|
else
|
|
return toLNC().getIntervalLambda(lx, ly, lz, d);
|
|
}
|
|
|
|
inline void
|
|
genericPoint::getExactLambda(double** lx, int& lxl, double** ly, int& lyl, double** lz, int& lzl, double** d, int& dl) const
|
|
{
|
|
if (isLPI())
|
|
toLPI().getExactLambda(lx, lxl, ly, lyl, lz, lzl, d, dl);
|
|
else if (isTPI())
|
|
toTPI().getExactLambda(lx, lxl, ly, lyl, lz, lzl, d, dl);
|
|
else
|
|
toLNC().getExactLambda(lx, lxl, ly, lyl, lz, lzl, d, dl);
|
|
}
|
|
|
|
inline void genericPoint::getBigfloatLambda(bigfloat& lx, bigfloat& ly, bigfloat& lz, bigfloat& d) const
|
|
{
|
|
if (isLPI())
|
|
toLPI().getBigfloatLambda(lx, ly, lz, d);
|
|
else if (isTPI())
|
|
toTPI().getBigfloatLambda(lx, ly, lz, d);
|
|
else
|
|
toLNC().getBigfloatLambda(lx, ly, lz, d);
|
|
}
|
|
|
|
// Type-specific lambdas
|
|
|
|
inline bool implicitPoint2D_SSI::getIntervalLambda(interval_number& lx, interval_number& ly, interval_number& d) const
|
|
{
|
|
lx = dfilter_lambda_x;
|
|
ly = dfilter_lambda_y;
|
|
d = dfilter_denominator;
|
|
return (dfilter_denominator.signIsReliable());
|
|
}
|
|
|
|
inline implicitPoint2D_SSI::implicitPoint2D_SSI(const explicitPoint2D& l11,
|
|
const explicitPoint2D& l12,
|
|
const explicitPoint2D& l21,
|
|
const explicitPoint2D& l22)
|
|
: genericPoint(Point_Type::SSI), l1_1(l11), l1_2(l12), l2_1(l21), l2_2(l22)
|
|
{
|
|
lambda2d_SSI_interval(l1_1.X(),
|
|
l1_1.Y(),
|
|
l1_2.X(),
|
|
l1_2.Y(),
|
|
l2_1.X(),
|
|
l2_1.Y(),
|
|
l2_2.X(),
|
|
l2_2.Y(),
|
|
dfilter_lambda_x,
|
|
dfilter_lambda_y,
|
|
dfilter_denominator);
|
|
if (dfilter_denominator.isNegative()) {
|
|
dfilter_lambda_x.negate();
|
|
dfilter_lambda_y.negate();
|
|
dfilter_denominator.negate();
|
|
}
|
|
}
|
|
|
|
inline bool implicitPoint3D_LPI::getIntervalLambda(interval_number& lx,
|
|
interval_number& ly,
|
|
interval_number& lz,
|
|
interval_number& d) const
|
|
{
|
|
lx = dfilter_lambda_x;
|
|
ly = dfilter_lambda_y;
|
|
lz = dfilter_lambda_z;
|
|
d = dfilter_denominator;
|
|
return (dfilter_denominator.signIsReliable());
|
|
}
|
|
|
|
inline implicitPoint3D_LPI::implicitPoint3D_LPI(const explicitPoint3D& _p,
|
|
const explicitPoint3D& _q,
|
|
const explicitPoint3D& _r,
|
|
const explicitPoint3D& _s,
|
|
const explicitPoint3D& _t)
|
|
: genericPoint(Point_Type::LPI), ip(_p), iq(_q), ir(_r), is(_s), it(_t)
|
|
{
|
|
lambda3d_LPI_interval(P().X(),
|
|
P().Y(),
|
|
P().Z(),
|
|
Q().X(),
|
|
Q().Y(),
|
|
Q().Z(),
|
|
R().X(),
|
|
R().Y(),
|
|
R().Z(),
|
|
S().X(),
|
|
S().Y(),
|
|
S().Z(),
|
|
T().X(),
|
|
T().Y(),
|
|
T().Z(),
|
|
dfilter_lambda_x,
|
|
dfilter_lambda_y,
|
|
dfilter_lambda_z,
|
|
dfilter_denominator);
|
|
if (dfilter_denominator.isNegative()) {
|
|
dfilter_lambda_x.negate();
|
|
dfilter_lambda_y.negate();
|
|
dfilter_lambda_z.negate();
|
|
dfilter_denominator.negate();
|
|
}
|
|
}
|
|
|
|
inline bool implicitPoint3D_TPI::getIntervalLambda(interval_number& lx,
|
|
interval_number& ly,
|
|
interval_number& lz,
|
|
interval_number& d) const
|
|
{
|
|
lx = dfilter_lambda_x;
|
|
ly = dfilter_lambda_y;
|
|
lz = dfilter_lambda_z;
|
|
d = dfilter_denominator;
|
|
return (dfilter_denominator.signIsReliable());
|
|
}
|
|
|
|
inline implicitPoint3D_TPI::implicitPoint3D_TPI(const explicitPoint3D& _v1,
|
|
const explicitPoint3D& _v2,
|
|
const explicitPoint3D& _v3,
|
|
const explicitPoint3D& _w1,
|
|
const explicitPoint3D& _w2,
|
|
const explicitPoint3D& _w3,
|
|
const explicitPoint3D& _u1,
|
|
const explicitPoint3D& _u2,
|
|
const explicitPoint3D& _u3)
|
|
: genericPoint(Point_Type::TPI), iv1(_v1), iv2(_v2), iv3(_v3), iw1(_w1), iw2(_w2), iw3(_w3), iu1(_u1), iu2(_u2), iu3(_u3)
|
|
{
|
|
lambda3d_TPI_interval(V1().X(),
|
|
V1().Y(),
|
|
V1().Z(),
|
|
V2().X(),
|
|
V2().Y(),
|
|
V2().Z(),
|
|
V3().X(),
|
|
V3().Y(),
|
|
V3().Z(),
|
|
W1().X(),
|
|
W1().Y(),
|
|
W1().Z(),
|
|
W2().X(),
|
|
W2().Y(),
|
|
W2().Z(),
|
|
W3().X(),
|
|
W3().Y(),
|
|
W3().Z(),
|
|
U1().X(),
|
|
U1().Y(),
|
|
U1().Z(),
|
|
U2().X(),
|
|
U2().Y(),
|
|
U2().Z(),
|
|
U3().X(),
|
|
U3().Y(),
|
|
U3().Z(),
|
|
dfilter_lambda_x,
|
|
dfilter_lambda_y,
|
|
dfilter_lambda_z,
|
|
dfilter_denominator);
|
|
if (dfilter_denominator.isNegative()) {
|
|
dfilter_lambda_x.negate();
|
|
dfilter_lambda_y.negate();
|
|
dfilter_lambda_z.negate();
|
|
dfilter_denominator.negate();
|
|
}
|
|
}
|
|
|
|
inline bool implicitPoint3D_LNC::getIntervalLambda(interval_number& lx,
|
|
interval_number& ly,
|
|
interval_number& lz,
|
|
interval_number& d) const
|
|
{
|
|
lx = dfilter_lambda_x;
|
|
ly = dfilter_lambda_y;
|
|
lz = dfilter_lambda_z;
|
|
d = dfilter_denominator;
|
|
return true;
|
|
}
|
|
|
|
inline implicitPoint3D_LNC::implicitPoint3D_LNC(const explicitPoint3D& _p, const explicitPoint3D& _q, const double _t)
|
|
: genericPoint(Point_Type::LNC), ip(_p), iq(_q), t(_t)
|
|
{
|
|
lambda3d_LNC_interval(P().X(),
|
|
P().Y(),
|
|
P().Z(),
|
|
Q().X(),
|
|
Q().Y(),
|
|
Q().Z(),
|
|
T(),
|
|
dfilter_lambda_x,
|
|
dfilter_lambda_y,
|
|
dfilter_lambda_z,
|
|
dfilter_denominator);
|
|
}
|
|
|
|
inline void implicitPoint2D_SSI::getExactLambda(double** lx, int& lxl, double** ly, int& lyl, double** d, int& dl) const
|
|
{
|
|
lambda2d_SSI_exact(l1_1.X(), l1_1.Y(), l1_2.X(), l1_2.Y(), l2_1.X(), l2_1.Y(), l2_2.X(), l2_2.Y(), lx, lxl, ly, lyl, d, dl);
|
|
if ((*d)[dl - 1] < 0) {
|
|
expansionObject::Gen_Invert(lxl, *lx);
|
|
expansionObject::Gen_Invert(lyl, *ly);
|
|
expansionObject::Gen_Invert(dl, *d);
|
|
}
|
|
}
|
|
|
|
// Keeps lambda/d pairs as close to one as possible to avoid under/overflows
|
|
inline void normalizeLambda3D(double* lx, int& lxl, double* ly, int& lyl, double* lz, int& lzl, double* d, int& dl)
|
|
{
|
|
double maxd, maxsd, ad, aad;
|
|
maxsd = expansionObject::To_Double(lxl, lx);
|
|
maxd = fabs(maxsd);
|
|
if ((aad = fabs((ad = expansionObject::To_Double(lyl, ly)))) > maxd) {
|
|
maxd = aad;
|
|
maxsd = ad;
|
|
}
|
|
if ((aad = fabs((ad = expansionObject::To_Double(lzl, lz)))) > maxd) {
|
|
maxd = aad;
|
|
maxsd = ad;
|
|
}
|
|
if ((aad = fabs((ad = expansionObject::To_Double(dl, d)))) > maxd) {
|
|
maxd = aad;
|
|
maxsd = ad;
|
|
}
|
|
|
|
int e;
|
|
frexp(maxsd, &e);
|
|
const double m = ldexp(2, -e);
|
|
|
|
expansionObject::ExactScale(lxl, lx, m);
|
|
expansionObject::ExactScale(lyl, ly, m);
|
|
expansionObject::ExactScale(lzl, lz, m);
|
|
expansionObject::ExactScale(dl, d, m);
|
|
}
|
|
|
|
inline void implicitPoint3D_LPI::getExactLambda(double** lx,
|
|
int& lxl,
|
|
double** ly,
|
|
int& lyl,
|
|
double** lz,
|
|
int& lzl,
|
|
double** d,
|
|
int& dl) const
|
|
{
|
|
lambda3d_LPI_exact(P().X(),
|
|
P().Y(),
|
|
P().Z(),
|
|
Q().X(),
|
|
Q().Y(),
|
|
Q().Z(),
|
|
R().X(),
|
|
R().Y(),
|
|
R().Z(),
|
|
S().X(),
|
|
S().Y(),
|
|
S().Z(),
|
|
T().X(),
|
|
T().Y(),
|
|
T().Z(),
|
|
lx,
|
|
lxl,
|
|
ly,
|
|
lyl,
|
|
lz,
|
|
lzl,
|
|
d,
|
|
dl);
|
|
if ((*d)[dl - 1] < 0) {
|
|
expansionObject::Gen_Invert(lxl, *lx);
|
|
expansionObject::Gen_Invert(lyl, *ly);
|
|
expansionObject::Gen_Invert(lzl, *lz);
|
|
expansionObject::Gen_Invert(dl, *d);
|
|
}
|
|
normalizeLambda3D(*lx, lxl, *ly, lyl, *lz, lzl, *d, dl);
|
|
}
|
|
|
|
inline void implicitPoint3D_TPI::getExactLambda(double** lx,
|
|
int& lxl,
|
|
double** ly,
|
|
int& lyl,
|
|
double** lz,
|
|
int& lzl,
|
|
double** d,
|
|
int& dl) const
|
|
{
|
|
lambda3d_TPI_exact(V1().X(),
|
|
V1().Y(),
|
|
V1().Z(),
|
|
V2().X(),
|
|
V2().Y(),
|
|
V2().Z(),
|
|
V3().X(),
|
|
V3().Y(),
|
|
V3().Z(),
|
|
W1().X(),
|
|
W1().Y(),
|
|
W1().Z(),
|
|
W2().X(),
|
|
W2().Y(),
|
|
W2().Z(),
|
|
W3().X(),
|
|
W3().Y(),
|
|
W3().Z(),
|
|
U1().X(),
|
|
U1().Y(),
|
|
U1().Z(),
|
|
U2().X(),
|
|
U2().Y(),
|
|
U2().Z(),
|
|
U3().X(),
|
|
U3().Y(),
|
|
U3().Z(),
|
|
lx,
|
|
lxl,
|
|
ly,
|
|
lyl,
|
|
lz,
|
|
lzl,
|
|
d,
|
|
dl);
|
|
if ((*d)[dl - 1] < 0) {
|
|
expansionObject::Gen_Invert(lxl, *lx);
|
|
expansionObject::Gen_Invert(lyl, *ly);
|
|
expansionObject::Gen_Invert(lzl, *lz);
|
|
expansionObject::Gen_Invert(dl, *d);
|
|
}
|
|
normalizeLambda3D(*lx, lxl, *ly, lyl, *lz, lzl, *d, dl);
|
|
}
|
|
|
|
inline void implicitPoint3D_LNC::getExactLambda(double** lx,
|
|
int& lxl,
|
|
double** ly,
|
|
int& lyl,
|
|
double** lz,
|
|
int& lzl,
|
|
double** d,
|
|
int& dl) const
|
|
{
|
|
lambda3d_LNC_exact(P().X(), P().Y(), P().Z(), Q().X(), Q().Y(), Q().Z(), T(), lx, lxl, ly, lyl, lz, lzl, d, dl);
|
|
normalizeLambda3D(*lx, lxl, *ly, lyl, *lz, lzl, *d, dl);
|
|
}
|
|
|
|
inline void implicitPoint2D_SSI::getBigfloatLambda(bigfloat& lx, bigfloat& ly, bigfloat& d) const
|
|
{
|
|
lambda2d_SSI_bigfloat(l1_1.X(), l1_1.Y(), l1_2.X(), l1_2.Y(), l2_1.X(), l2_1.Y(), l2_2.X(), l2_2.Y(), lx, ly, d);
|
|
if (sgn(d) < 0) {
|
|
lx = -lx;
|
|
ly = -ly;
|
|
d = -d;
|
|
}
|
|
}
|
|
|
|
inline void implicitPoint3D_LPI::getBigfloatLambda(bigfloat& lx, bigfloat& ly, bigfloat& lz, bigfloat& d) const
|
|
{
|
|
lambda3d_LPI_bigfloat(P().X(),
|
|
P().Y(),
|
|
P().Z(),
|
|
Q().X(),
|
|
Q().Y(),
|
|
Q().Z(),
|
|
R().X(),
|
|
R().Y(),
|
|
R().Z(),
|
|
S().X(),
|
|
S().Y(),
|
|
S().Z(),
|
|
T().X(),
|
|
T().Y(),
|
|
T().Z(),
|
|
lx,
|
|
ly,
|
|
lz,
|
|
d);
|
|
if (sgn(d) < 0) {
|
|
lx = -lx;
|
|
ly = -ly;
|
|
lz = -lz;
|
|
d = -d;
|
|
}
|
|
}
|
|
|
|
inline void implicitPoint3D_TPI::getBigfloatLambda(bigfloat& lx, bigfloat& ly, bigfloat& lz, bigfloat& d) const
|
|
{
|
|
lambda3d_TPI_bigfloat(V1().X(),
|
|
V1().Y(),
|
|
V1().Z(),
|
|
V2().X(),
|
|
V2().Y(),
|
|
V2().Z(),
|
|
V3().X(),
|
|
V3().Y(),
|
|
V3().Z(),
|
|
W1().X(),
|
|
W1().Y(),
|
|
W1().Z(),
|
|
W2().X(),
|
|
W2().Y(),
|
|
W2().Z(),
|
|
W3().X(),
|
|
W3().Y(),
|
|
W3().Z(),
|
|
U1().X(),
|
|
U1().Y(),
|
|
U1().Z(),
|
|
U2().X(),
|
|
U2().Y(),
|
|
U2().Z(),
|
|
U3().X(),
|
|
U3().Y(),
|
|
U3().Z(),
|
|
lx,
|
|
ly,
|
|
lz,
|
|
d);
|
|
if (sgn(d) < 0) {
|
|
lx = -lx;
|
|
ly = -ly;
|
|
lz = -lz;
|
|
d = -d;
|
|
}
|
|
}
|
|
|
|
inline void implicitPoint3D_LNC::getBigfloatLambda(bigfloat& lx, bigfloat& ly, bigfloat& lz, bigfloat& d) const
|
|
{
|
|
lambda3d_LNC_bigfloat(P().X(), P().Y(), P().Z(), Q().X(), Q().Y(), Q().Z(), T(), lx, ly, lz, d);
|
|
}
|
|
|
|
inline bool genericPoint::apapExplicit(explicitPoint2D& e) const
|
|
{
|
|
if (isExplicit2D())
|
|
e = toExplicit2D();
|
|
else {
|
|
double l1x_p[128], *l1x = l1x_p, l1y_p[128], *l1y = l1y_p, d1_p[128], *d1 = d1_p;
|
|
int l1x_len, l1y_len, d1_len;
|
|
getExactLambda(&l1x, l1x_len, &l1y, l1y_len, &d1, d1_len);
|
|
const double lambda_x = expansionObject::To_Double(l1x_len, l1x);
|
|
const double lambda_y = expansionObject::To_Double(l1y_len, l1y);
|
|
const double lambda_d = expansionObject::To_Double(d1_len, d1);
|
|
if (l1x_p != l1x) FreeDoubles(l1x);
|
|
if (l1y_p != l1y) FreeDoubles(l1y);
|
|
if (d1_p != d1) FreeDoubles(d1);
|
|
if (lambda_d == 0) return false;
|
|
|
|
e = explicitPoint2D(lambda_x / lambda_d, lambda_y / lambda_d);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
inline bool genericPoint::approxExplicit(explicitPoint2D& e) const
|
|
{
|
|
if (isExplicit2D())
|
|
e = toExplicit2D();
|
|
else {
|
|
double lambda_x, lambda_y, lambda_d;
|
|
interval_number ilx, ily, id;
|
|
if (!getIntervalLambda(ilx, ily, id))
|
|
return apapExplicit(e);
|
|
else {
|
|
lambda_x = ilx.sup() + ilx.inf();
|
|
lambda_y = ily.sup() + ily.inf();
|
|
lambda_d = id.sup() + id.inf();
|
|
}
|
|
e = explicitPoint2D(lambda_x / lambda_d, lambda_y / lambda_d);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
inline bool genericPoint::apapExplicit(explicitPoint3D& e) const
|
|
{
|
|
if (isExplicit3D())
|
|
e = toExplicit3D();
|
|
else {
|
|
double l1z_p[128], *l1z = l1z_p, l1x_p[128], *l1x = l1x_p, l1y_p[128], *l1y = l1y_p, d1_p[128], *d1 = d1_p;
|
|
int l1z_len, l1x_len, l1y_len, d1_len;
|
|
getExactLambda(&l1x, l1x_len, &l1y, l1y_len, &l1z, l1z_len, &d1, d1_len);
|
|
const double lambda_x = expansionObject::To_Double(l1x_len, l1x);
|
|
const double lambda_y = expansionObject::To_Double(l1y_len, l1y);
|
|
const double lambda_z = expansionObject::To_Double(l1z_len, l1z);
|
|
const double lambda_d = expansionObject::To_Double(d1_len, d1);
|
|
if (l1z_p != l1z) FreeDoubles(l1z);
|
|
if (l1x_p != l1x) FreeDoubles(l1x);
|
|
if (l1y_p != l1y) FreeDoubles(l1y);
|
|
if (d1_p != d1) FreeDoubles(d1);
|
|
if (lambda_d == 0) return false;
|
|
e = explicitPoint3D(lambda_x / lambda_d, lambda_y / lambda_d, lambda_z / lambda_d);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
inline bool genericPoint::approxExplicit(explicitPoint3D& e) const
|
|
{
|
|
if (isExplicit3D())
|
|
e = toExplicit3D();
|
|
else {
|
|
double lambda_x, lambda_y, lambda_z, lambda_d;
|
|
interval_number ilx, ily, ilz, id;
|
|
if (!getIntervalLambda(ilx, ily, ilz, id))
|
|
return apapExplicit(e);
|
|
else {
|
|
lambda_x = ilx.sup() + ilx.inf();
|
|
lambda_y = ily.sup() + ily.inf();
|
|
lambda_z = ilz.sup() + ilz.inf();
|
|
lambda_d = id.sup() + id.inf();
|
|
}
|
|
e = explicitPoint3D(lambda_x / lambda_d, lambda_y / lambda_d, lambda_z / lambda_d);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
inline bool genericPoint::getApproxXYCoordinates(double& x, double& y, bool apap) const
|
|
{
|
|
if (is2D()) {
|
|
explicitPoint2D op;
|
|
if (apap && !apapExplicit(op)) return false;
|
|
if (!apap && !approxExplicit(op)) return false;
|
|
x = op.X();
|
|
y = op.Y();
|
|
return true;
|
|
}
|
|
if (is3D()) {
|
|
explicitPoint3D op;
|
|
if (apap && !apapExplicit(op)) return false;
|
|
if (!apap && !approxExplicit(op)) return false;
|
|
x = op.X();
|
|
y = op.Y();
|
|
return true;
|
|
}
|
|
ip_error("genericPoint::getApproxXYCoordinates - should not happen\n");
|
|
return false;
|
|
}
|
|
|
|
inline bool genericPoint::getApproxXYZCoordinates(double& x, double& y, double& z, bool apap) const
|
|
{
|
|
if (is3D()) {
|
|
explicitPoint3D op;
|
|
if (apap && !apapExplicit(op)) return false;
|
|
if (!apap && !approxExplicit(op)) return false;
|
|
x = op.X();
|
|
y = op.Y();
|
|
z = op.Z();
|
|
return true;
|
|
}
|
|
ip_error("genericPoint::getApproxXYZCoordinates - should not happen\n");
|
|
return false;
|
|
}
|
|
|
|
inline bool genericPoint::getExactXYCoordinates(bigrational& x, bigrational& y) const
|
|
{
|
|
if (isExplicit2D())
|
|
return toExplicit2D().getExactXYCoordinates(x, y);
|
|
else if (isSSI())
|
|
return toSSI().getExactXYCoordinates(x, y);
|
|
else
|
|
ip_error("genericPoint::getExactXYCoordinates - should not happen\n");
|
|
return false;
|
|
}
|
|
|
|
inline bool genericPoint::getExactXYZCoordinates(bigrational& x, bigrational& y, bigrational& z) const
|
|
{
|
|
if (isExplicit3D())
|
|
return toExplicit3D().getExactXYZCoordinates(x, y, z);
|
|
else if (isLPI())
|
|
return toLPI().getExactXYZCoordinates(x, y, z);
|
|
else if (isTPI())
|
|
return toTPI().getExactXYZCoordinates(x, y, z);
|
|
else if (isLNC())
|
|
return toLNC().getExactXYZCoordinates(x, y, z);
|
|
else if (isExplicit2D()) {
|
|
z = bigfloat(0);
|
|
return toExplicit2D().getExactXYCoordinates(x, y);
|
|
} else if (isSSI()) {
|
|
z = bigfloat(0);
|
|
return toSSI().getExactXYCoordinates(x, y);
|
|
} else
|
|
ip_error("genericPoint::getExactXYZCoordinates - should not happen\n");
|
|
return false;
|
|
}
|
|
|
|
inline bool implicitPoint2D_SSI::getExactXYCoordinates(bigrational& x, bigrational& y) const
|
|
{
|
|
bigfloat lx, ly, d;
|
|
getBigfloatLambda(lx, ly, d);
|
|
if (sgn(d) == 0) return false;
|
|
const bigrational rd(d);
|
|
x = bigrational(lx) / rd;
|
|
y = bigrational(ly) / rd;
|
|
return true;
|
|
}
|
|
|
|
inline bool implicitPoint3D_LPI::getExactXYZCoordinates(bigrational& x, bigrational& y, bigrational& z) const
|
|
{
|
|
bigfloat lx, ly, lz, d;
|
|
getBigfloatLambda(lx, ly, lz, d);
|
|
if (sgn(d) == 0) return false;
|
|
const bigrational rd(d);
|
|
x = bigrational(lx) / rd;
|
|
y = bigrational(ly) / rd;
|
|
z = bigrational(lz) / rd;
|
|
return true;
|
|
}
|
|
|
|
inline bool implicitPoint3D_TPI::getExactXYZCoordinates(bigrational& x, bigrational& y, bigrational& z) const
|
|
{
|
|
bigfloat lx, ly, lz, d;
|
|
getBigfloatLambda(lx, ly, lz, d);
|
|
if (sgn(d) == 0) return false;
|
|
const bigrational rd(d);
|
|
x = bigrational(lx) / rd;
|
|
y = bigrational(ly) / rd;
|
|
z = bigrational(lz) / rd;
|
|
return true;
|
|
}
|
|
|
|
inline bool implicitPoint3D_LNC::getExactXYZCoordinates(bigrational& x, bigrational& y, bigrational& z) const
|
|
{
|
|
bigfloat lx, ly, lz, d;
|
|
getBigfloatLambda(lx, ly, lz, d);
|
|
x = bigrational(lx);
|
|
y = bigrational(ly);
|
|
z = bigrational(lz);
|
|
return true;
|
|
}
|
|
|
|
inline ostream& operator<<(ostream& os, const genericPoint& p)
|
|
{
|
|
if (p.isExplicit2D())
|
|
return os << p.toExplicit2D();
|
|
else if (p.isExplicit3D())
|
|
return os << p.toExplicit3D();
|
|
else if (p.isSSI())
|
|
return os << p.toSSI();
|
|
else if (p.isLPI())
|
|
return os << p.toLPI();
|
|
else if (p.isTPI())
|
|
return os << p.toTPI();
|
|
else if (p.isLNC())
|
|
return os << p.toLNC();
|
|
else
|
|
ip_error("genericPoint::operator<< - should not happen\n");
|
|
return os;
|
|
}
|
|
|
|
inline int maxComponentInTriangleNormal_filtered(double ov1x,
|
|
double ov1y,
|
|
double ov1z,
|
|
double ov2x,
|
|
double ov2y,
|
|
double ov2z,
|
|
double ov3x,
|
|
double ov3y,
|
|
double ov3z)
|
|
{
|
|
double v3x = ov3x - ov2x;
|
|
double v3y = ov3y - ov2y;
|
|
double v3z = ov3z - ov2z;
|
|
double v2x = ov2x - ov1x;
|
|
double v2y = ov2y - ov1y;
|
|
double v2z = ov2z - ov1z;
|
|
double nvx1 = v2y * v3z;
|
|
double nvx2 = v2z * v3y;
|
|
double nvx = nvx1 - nvx2;
|
|
double nvy1 = v3x * v2z;
|
|
double nvy2 = v3z * v2x;
|
|
double nvy = nvy1 - nvy2;
|
|
double nvz1 = v2x * v3y;
|
|
double nvz2 = v2y * v3x;
|
|
double nvz = nvz1 - nvz2;
|
|
|
|
double _tmp_fabs, max_var = 0;
|
|
if ((_tmp_fabs = fabs(v3x)) > max_var) max_var = _tmp_fabs;
|
|
if ((_tmp_fabs = fabs(v3y)) > max_var) max_var = _tmp_fabs;
|
|
if ((_tmp_fabs = fabs(v3z)) > max_var) max_var = _tmp_fabs;
|
|
if ((_tmp_fabs = fabs(v2x)) > max_var) max_var = _tmp_fabs;
|
|
if ((_tmp_fabs = fabs(v2y)) > max_var) max_var = _tmp_fabs;
|
|
if ((_tmp_fabs = fabs(v2z)) > max_var) max_var = _tmp_fabs;
|
|
double epsilon = 8.88395e-016 * max_var * max_var;
|
|
|
|
double nvxc = fabs(nvx);
|
|
double nvyc = fabs(nvy);
|
|
double nvzc = fabs(nvz);
|
|
double nv = nvxc;
|
|
if (nvyc > nv) nv = nvyc;
|
|
if (nvzc > nv) nv = nvzc;
|
|
|
|
if (nv > epsilon) {
|
|
if (nv == nvxc) return 0;
|
|
if (nv == nvyc) return 1;
|
|
if (nv == nvzc) return 2;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
inline int maxComponentInTriangleNormal_exact(double ov1x,
|
|
double ov1y,
|
|
double ov1z,
|
|
double ov2x,
|
|
double ov2y,
|
|
double ov2z,
|
|
double ov3x,
|
|
double ov3y,
|
|
double ov3z)
|
|
{
|
|
expansionObject o;
|
|
double v3x[2];
|
|
o.two_Diff(ov3x, ov2x, v3x);
|
|
double v3y[2];
|
|
o.two_Diff(ov3y, ov2y, v3y);
|
|
double v3z[2];
|
|
o.two_Diff(ov3z, ov2z, v3z);
|
|
double v2x[2];
|
|
o.two_Diff(ov2x, ov1x, v2x);
|
|
double v2y[2];
|
|
o.two_Diff(ov2y, ov1y, v2y);
|
|
double v2z[2];
|
|
o.two_Diff(ov2z, ov1z, v2z);
|
|
double nvx1[8];
|
|
o.Two_Two_Prod(v2y, v3z, nvx1);
|
|
double nvx2[8];
|
|
o.Two_Two_Prod(v2z, v3y, nvx2);
|
|
double nvx[16];
|
|
int nvx_len = o.Gen_Diff(8, nvx1, 8, nvx2, nvx);
|
|
double nvy1[8];
|
|
o.Two_Two_Prod(v3x, v2z, nvy1);
|
|
double nvy2[8];
|
|
o.Two_Two_Prod(v3z, v2x, nvy2);
|
|
double nvy[16];
|
|
int nvy_len = o.Gen_Diff(8, nvy1, 8, nvy2, nvy);
|
|
double nvz1[8];
|
|
o.Two_Two_Prod(v2x, v3y, nvz1);
|
|
double nvz2[8];
|
|
o.Two_Two_Prod(v2y, v3x, nvz2);
|
|
double nvz[16];
|
|
int nvz_len = o.Gen_Diff(8, nvz1, 8, nvz2, nvz);
|
|
|
|
double nvxc = fabs(nvx[nvx_len - 1]);
|
|
double nvyc = fabs(nvy[nvy_len - 1]);
|
|
double nvzc = fabs(nvz[nvz_len - 1]);
|
|
double nv = nvxc;
|
|
if (nvyc > nv) nv = nvyc;
|
|
if (nvzc > nv) return 2;
|
|
if (nv == nvxc) return 0;
|
|
return 1;
|
|
}
|
|
|
|
inline int genericPoint::maxComponentInTriangleNormal(double ov1x,
|
|
double ov1y,
|
|
double ov1z,
|
|
double ov2x,
|
|
double ov2y,
|
|
double ov2z,
|
|
double ov3x,
|
|
double ov3y,
|
|
double ov3z)
|
|
{
|
|
int ret;
|
|
if ((ret = maxComponentInTriangleNormal_filtered(ov1x, ov1y, ov1z, ov2x, ov2y, ov2z, ov3x, ov3y, ov3z)) >= 0) return ret;
|
|
return maxComponentInTriangleNormal_exact(ov1x, ov1y, ov1z, ov2x, ov2y, ov2z, ov3x, ov3y, ov3z);
|
|
}
|
|
|
|
/////////////////////////////////////////////
|
|
//
|
|
// Derived predicates
|
|
//
|
|
/////////////////////////////////////////////
|
|
|
|
inline bool genericPoint::innerSegmentsCross(const genericPoint& A,
|
|
const genericPoint& B,
|
|
const genericPoint& P,
|
|
const genericPoint& Q)
|
|
{
|
|
int o11, o12, o21, o22;
|
|
|
|
o11 = orient2Dxy(P, A, B);
|
|
o12 = orient2Dxy(Q, B, A);
|
|
o21 = orient2Dxy(A, P, Q);
|
|
o22 = orient2Dxy(B, Q, P);
|
|
if (o11 || o21 || o12 || o22) return (o11 == o12 && o21 == o22);
|
|
|
|
o11 = orient2Dyz(P, A, B);
|
|
o12 = orient2Dyz(Q, B, A);
|
|
o21 = orient2Dyz(A, P, Q);
|
|
o22 = orient2Dyz(B, Q, P);
|
|
if (o11 || o21 || o12 || o22) return (o11 == o12 && o21 == o22);
|
|
|
|
o11 = orient2Dzx(P, A, B);
|
|
o12 = orient2Dzx(Q, B, A);
|
|
o21 = orient2Dzx(A, P, Q);
|
|
o22 = orient2Dzx(B, Q, P);
|
|
if (o11 || o21 || o12 || o22) return (o11 == o12 && o21 == o22);
|
|
|
|
return false;
|
|
}
|
|
|
|
inline bool genericPoint::segmentsCross(const genericPoint& A,
|
|
const genericPoint& B,
|
|
const genericPoint& P,
|
|
const genericPoint& Q)
|
|
{
|
|
int o11, o12, o21, o22;
|
|
|
|
o11 = orient2Dxy(P, A, B);
|
|
o12 = orient2Dxy(Q, B, A);
|
|
o21 = orient2Dxy(A, P, Q);
|
|
o22 = orient2Dxy(B, Q, P);
|
|
if ((o11 || o12) && (o11 * o12 >= 0) && (o21 || o22) && (o21 * o22 >= 0)) return true;
|
|
|
|
o11 = orient2Dyz(P, A, B);
|
|
o12 = orient2Dyz(Q, B, A);
|
|
o21 = orient2Dyz(A, P, Q);
|
|
o22 = orient2Dyz(B, Q, P);
|
|
if ((o11 || o12) && (o11 * o12 >= 0) && (o21 || o22) && (o21 * o22 >= 0)) return true;
|
|
|
|
o11 = orient2Dzx(P, A, B);
|
|
o12 = orient2Dzx(Q, B, A);
|
|
o21 = orient2Dzx(A, P, Q);
|
|
o22 = orient2Dzx(B, Q, P);
|
|
if ((o11 || o12) && (o11 * o12 >= 0) && (o21 || o22) && (o21 * o22 >= 0)) return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
inline bool genericPoint::innerSegmentCrossesInnerTriangle(const genericPoint& s1,
|
|
const genericPoint& s2,
|
|
const genericPoint& v1,
|
|
const genericPoint& v2,
|
|
const genericPoint& v3)
|
|
{
|
|
int o1 = orient3D(s1, v1, v2, v3);
|
|
if (o1 == 0) return false;
|
|
int o2 = orient3D(s2, v1, v2, v3);
|
|
if (o2 == 0) return false;
|
|
|
|
if ((o1 > 0 && o2 > 0) || (o1 < 0 && o2 < 0)) return false;
|
|
o1 = orient3D(s1, s2, v1, v2);
|
|
o2 = orient3D(s1, s2, v2, v3);
|
|
if ((o1 >= 0 && o2 <= 0) || (o1 <= 0 && o2 >= 0)) return false;
|
|
int o3 = orient3D(s1, s2, v3, v1);
|
|
if ((o1 >= 0 && o3 <= 0) || (o1 <= 0 && o3 >= 0)) return false;
|
|
if ((o2 >= 0 && o3 <= 0) || (o2 <= 0 && o3 >= 0)) return false;
|
|
return true;
|
|
}
|
|
|
|
inline bool genericPoint::pointInInnerSegment(const genericPoint& p, const genericPoint& v1, const genericPoint& v2)
|
|
{
|
|
if (misaligned(p, v1, v2)) return false;
|
|
|
|
int lt2, lt3;
|
|
lt2 = lessThanOnX(v1, p);
|
|
lt3 = lessThanOnX(p, v2);
|
|
if (lt2) return (lt2 == lt3);
|
|
lt2 = lessThanOnY(v1, p);
|
|
lt3 = lessThanOnY(p, v2);
|
|
if (lt2) return (lt2 == lt3);
|
|
lt2 = lessThanOnZ(v1, p);
|
|
lt3 = lessThanOnZ(p, v2);
|
|
if (lt2) return (lt2 == lt3);
|
|
return false;
|
|
}
|
|
|
|
inline bool genericPoint::pointInSegment(const genericPoint& p, const genericPoint& v1, const genericPoint& v2)
|
|
{
|
|
if (misaligned(p, v1, v2)) return false;
|
|
|
|
int lt2x = lessThanOnX(v1, p);
|
|
int lt3x = lessThanOnX(p, v2);
|
|
if (lt2x && lt3x) return (lt2x == lt3x);
|
|
int lt2y = lessThanOnY(v1, p);
|
|
int lt3y = lessThanOnY(p, v2);
|
|
if (lt2y && lt3y) return (lt2y == lt3y);
|
|
int lt2z = lessThanOnZ(v1, p);
|
|
int lt3z = lessThanOnZ(p, v2);
|
|
if (lt2z && lt3z) return (lt2z == lt3z);
|
|
|
|
return ((lt2x == 0 && lt2y == 0 && lt2z == 0) || (lt3x == 0 && lt3y == 0 && lt3z == 0));
|
|
}
|
|
|
|
inline bool genericPoint::pointInTriangle(const genericPoint& P,
|
|
const genericPoint& A,
|
|
const genericPoint& B,
|
|
const genericPoint& C)
|
|
{
|
|
int o1, o2, o3;
|
|
o1 = orient2Dxy(P, A, B);
|
|
o2 = orient2Dxy(P, B, C);
|
|
o3 = orient2Dxy(P, C, A);
|
|
if (o1 || o2 || o3) return ((o1 >= 0 && o2 >= 0 && o3 >= 0) || (o1 <= 0 && o2 <= 0 && o3 <= 0));
|
|
o1 = orient2Dyz(P, A, B);
|
|
o2 = orient2Dyz(P, B, C);
|
|
o3 = orient2Dyz(P, C, A);
|
|
if (o1 || o2 || o3) return ((o1 >= 0 && o2 >= 0 && o3 >= 0) || (o1 <= 0 && o2 <= 0 && o3 <= 0));
|
|
o1 = orient2Dzx(P, A, B);
|
|
o2 = orient2Dzx(P, B, C);
|
|
o3 = orient2Dzx(P, C, A);
|
|
return ((o1 >= 0 && o2 >= 0 && o3 >= 0) || (o1 <= 0 && o2 <= 0 && o3 <= 0));
|
|
}
|
|
|
|
inline bool genericPoint::pointInTriangle(const genericPoint& P,
|
|
const genericPoint& A,
|
|
const genericPoint& B,
|
|
const genericPoint& C,
|
|
int& o1,
|
|
int& o2,
|
|
int& o3)
|
|
{
|
|
o1 = orient2Dxy(P, A, B);
|
|
o2 = orient2Dxy(P, B, C);
|
|
o3 = orient2Dxy(P, C, A);
|
|
if (o1 || o2 || o3) return ((o1 >= 0 && o2 >= 0 && o3 >= 0) || (o1 <= 0 && o2 <= 0 && o3 <= 0));
|
|
o1 = orient2Dyz(P, A, B);
|
|
o2 = orient2Dyz(P, B, C);
|
|
o3 = orient2Dyz(P, C, A);
|
|
if (o1 || o2 || o3) return ((o1 >= 0 && o2 >= 0 && o3 >= 0) || (o1 <= 0 && o2 <= 0 && o3 <= 0));
|
|
o1 = orient2Dzx(P, A, B);
|
|
o2 = orient2Dzx(P, B, C);
|
|
o3 = orient2Dzx(P, C, A);
|
|
return ((o1 >= 0 && o2 >= 0 && o3 >= 0) || (o1 <= 0 && o2 <= 0 && o3 <= 0));
|
|
}
|
|
|
|
inline bool genericPoint::pointInInnerTriangle(const genericPoint& P,
|
|
const genericPoint& A,
|
|
const genericPoint& B,
|
|
const genericPoint& C)
|
|
{
|
|
int o1, o2, o3;
|
|
o1 = orient2Dxy(P, A, B);
|
|
o2 = orient2Dxy(P, B, C);
|
|
o3 = orient2Dxy(P, C, A);
|
|
if (o1 || o2 || o3) return ((o1 > 0 && o2 > 0 && o3 > 0) || (o1 < 0 && o2 < 0 && o3 < 0));
|
|
o1 = orient2Dyz(P, A, B);
|
|
o2 = orient2Dyz(P, B, C);
|
|
o3 = orient2Dyz(P, C, A);
|
|
if (o1 || o2 || o3) return ((o1 > 0 && o2 > 0 && o3 > 0) || (o1 < 0 && o2 < 0 && o3 < 0));
|
|
o1 = orient2Dzx(P, A, B);
|
|
o2 = orient2Dzx(P, B, C);
|
|
o3 = orient2Dzx(P, C, A);
|
|
return ((o1 > 0 && o2 > 0 && o3 > 0) || (o1 < 0 && o2 < 0 && o3 < 0));
|
|
}
|
|
|
|
inline bool genericPoint::lineCrossesInnerTriangle(const genericPoint& s1,
|
|
const genericPoint& s2,
|
|
const genericPoint& v1,
|
|
const genericPoint& v2,
|
|
const genericPoint& v3)
|
|
{
|
|
const int o1 = genericPoint::orient3D(s1, s2, v1, v2);
|
|
const int o2 = genericPoint::orient3D(s1, s2, v2, v3);
|
|
if ((o1 >= 0 && o2 <= 0) || (o1 <= 0 && o2 >= 0)) return false;
|
|
const int o3 = genericPoint::orient3D(s1, s2, v3, v1);
|
|
if ((o1 >= 0 && o3 <= 0) || (o1 <= 0 && o3 >= 0)) return false;
|
|
if ((o2 >= 0 && o3 <= 0) || (o2 <= 0 && o3 >= 0)) return false;
|
|
return true;
|
|
}
|
|
|
|
inline bool genericPoint::lineCrossesTriangle(const genericPoint& s1,
|
|
const genericPoint& s2,
|
|
const genericPoint& v1,
|
|
const genericPoint& v2,
|
|
const genericPoint& v3)
|
|
{
|
|
const int o1 = genericPoint::orient3D(s1, s2, v1, v2);
|
|
const int o2 = genericPoint::orient3D(s1, s2, v2, v3);
|
|
if ((o1 > 0 && o2 < 0) || (o1 < 0 && o2 > 0)) return false;
|
|
const int o3 = genericPoint::orient3D(s1, s2, v3, v1);
|
|
if ((o1 > 0 && o3 < 0) || (o1 < 0 && o3 > 0)) return false;
|
|
if ((o2 > 0 && o3 < 0) || (o2 < 0 && o3 > 0)) return false;
|
|
return true;
|
|
}
|
|
|
|
inline bool genericPoint::innerSegmentCrossesTriangle(const genericPoint& s1,
|
|
const genericPoint& s2,
|
|
const genericPoint& v1,
|
|
const genericPoint& v2,
|
|
const genericPoint& v3)
|
|
{
|
|
const int o1 = genericPoint::orient3D(s1, v1, v2, v3);
|
|
if (o1 == 0) return false;
|
|
const int o2 = genericPoint::orient3D(s2, v1, v2, v3);
|
|
if (o2 == 0) return false;
|
|
|
|
if ((o1 > 0 && o2 > 0) || (o1 < 0 && o2 < 0)) return false;
|
|
return lineCrossesTriangle(s1, s2, v1, v2, v3);
|
|
}
|
|
|
|
inline bool genericPoint::pointInInnerSegment(const genericPoint& p, const genericPoint& v1, const genericPoint& v2, int xyz)
|
|
{
|
|
int lt2, lt3;
|
|
if (xyz == 0) {
|
|
if (orient2Dyz(p, v1, v2)) return false;
|
|
lt2 = lessThanOnY(v1, p);
|
|
lt3 = lessThanOnY(p, v2);
|
|
if (lt2) return (lt2 == lt3);
|
|
lt2 = lessThanOnZ(v1, p);
|
|
lt3 = lessThanOnZ(p, v2);
|
|
} else if (xyz == 1) {
|
|
if (orient2Dzx(p, v1, v2)) return false;
|
|
lt2 = lessThanOnX(v1, p);
|
|
lt3 = lessThanOnX(p, v2);
|
|
if (lt2) return (lt2 == lt3);
|
|
lt2 = lessThanOnZ(v1, p);
|
|
lt3 = lessThanOnZ(p, v2);
|
|
} else {
|
|
if (orient2Dxy(p, v1, v2)) return false;
|
|
lt2 = lessThanOnX(v1, p);
|
|
lt3 = lessThanOnX(p, v2);
|
|
if (lt2) return (lt2 == lt3);
|
|
lt2 = lessThanOnY(v1, p);
|
|
lt3 = lessThanOnY(p, v2);
|
|
}
|
|
return (lt2 && (lt2 == lt3));
|
|
}
|
|
|
|
inline bool genericPoint::pointInSegment(const genericPoint& p, const genericPoint& v1, const genericPoint& v2, int xyz)
|
|
{
|
|
int lt2, lt3, lt4, lt5;
|
|
if (xyz == 0) {
|
|
if (orient2Dyz(p, v1, v2)) return false;
|
|
lt2 = lessThanOnY(v1, p);
|
|
lt3 = lessThanOnY(p, v2);
|
|
if (lt2 && lt3) return (lt2 == lt3);
|
|
lt4 = lessThanOnZ(v1, p);
|
|
lt5 = lessThanOnZ(p, v2);
|
|
} else if (xyz == 1) {
|
|
if (orient2Dzx(p, v1, v2)) return false;
|
|
lt2 = lessThanOnX(v1, p);
|
|
lt3 = lessThanOnX(p, v2);
|
|
if (lt2 && lt3) return (lt2 == lt3);
|
|
lt4 = lessThanOnZ(v1, p);
|
|
lt5 = lessThanOnZ(p, v2);
|
|
} else {
|
|
if (orient2Dxy(p, v1, v2)) return false;
|
|
lt2 = lessThanOnX(v1, p);
|
|
lt3 = lessThanOnX(p, v2);
|
|
if (lt2 && lt3) return (lt2 == lt3);
|
|
lt4 = lessThanOnY(v1, p);
|
|
lt5 = lessThanOnY(p, v2);
|
|
}
|
|
return ((lt2 == 0 && lt4 == 0) || (lt3 == 0 && lt5 == 0));
|
|
}
|
|
|
|
inline bool genericPoint::pointInInnerTriangle(const genericPoint& P,
|
|
const genericPoint& A,
|
|
const genericPoint& B,
|
|
const genericPoint& C,
|
|
int xyz)
|
|
{
|
|
int o1, o2, o3;
|
|
if (xyz == 2) {
|
|
o1 = genericPoint::orient2Dxy(P, A, B);
|
|
o2 = genericPoint::orient2Dxy(P, B, C);
|
|
o3 = genericPoint::orient2Dxy(P, C, A);
|
|
} else if (xyz == 0) {
|
|
o1 = genericPoint::orient2Dyz(P, A, B);
|
|
o2 = genericPoint::orient2Dyz(P, B, C);
|
|
o3 = genericPoint::orient2Dyz(P, C, A);
|
|
} else {
|
|
o1 = genericPoint::orient2Dzx(P, A, B);
|
|
o2 = genericPoint::orient2Dzx(P, B, C);
|
|
o3 = genericPoint::orient2Dzx(P, C, A);
|
|
}
|
|
return ((o1 > 0 && o2 > 0 && o3 > 0) || (o1 < 0 && o2 < 0 && o3 < 0));
|
|
}
|
|
|
|
inline bool genericPoint::pointInTriangle(const genericPoint& P,
|
|
const genericPoint& A,
|
|
const genericPoint& B,
|
|
const genericPoint& C,
|
|
int xyz)
|
|
{
|
|
int o1, o2, o3;
|
|
if (xyz == 2) {
|
|
o1 = genericPoint::orient2Dxy(P, A, B);
|
|
o2 = genericPoint::orient2Dxy(P, B, C);
|
|
o3 = genericPoint::orient2Dxy(P, C, A);
|
|
} else if (xyz == 0) {
|
|
o1 = genericPoint::orient2Dyz(P, A, B);
|
|
o2 = genericPoint::orient2Dyz(P, B, C);
|
|
o3 = genericPoint::orient2Dyz(P, C, A);
|
|
} else {
|
|
o1 = genericPoint::orient2Dzx(P, A, B);
|
|
o2 = genericPoint::orient2Dzx(P, B, C);
|
|
o3 = genericPoint::orient2Dzx(P, C, A);
|
|
}
|
|
return ((o1 >= 0 && o2 >= 0 && o3 >= 0) || (o1 <= 0 && o2 <= 0 && o3 <= 0));
|
|
}
|
|
|
|
inline bool genericPoint::innerSegmentsCross(const genericPoint& A,
|
|
const genericPoint& B,
|
|
const genericPoint& P,
|
|
const genericPoint& Q,
|
|
int xyz)
|
|
{
|
|
int o11, o12, o21, o22;
|
|
|
|
if (xyz == 2) {
|
|
o11 = orient2Dxy(P, A, B);
|
|
o12 = orient2Dxy(Q, B, A);
|
|
o21 = orient2Dxy(A, P, Q);
|
|
o22 = orient2Dxy(B, Q, P);
|
|
} else if (xyz == 0) {
|
|
o11 = orient2Dyz(P, A, B);
|
|
o12 = orient2Dyz(Q, B, A);
|
|
o21 = orient2Dyz(A, P, Q);
|
|
o22 = orient2Dyz(B, Q, P);
|
|
} else {
|
|
o11 = orient2Dzx(P, A, B);
|
|
o12 = orient2Dzx(Q, B, A);
|
|
o21 = orient2Dzx(A, P, Q);
|
|
o22 = orient2Dzx(B, Q, P);
|
|
}
|
|
|
|
return (o11 && o21 && o11 == o12 && o21 == o22);
|
|
}
|
|
|
|
inline bool genericPoint::segmentsCross(const genericPoint& A,
|
|
const genericPoint& B,
|
|
const genericPoint& P,
|
|
const genericPoint& Q,
|
|
int xyz)
|
|
{
|
|
int o11, o12, o21, o22;
|
|
|
|
if (xyz == 2) {
|
|
o11 = orient2Dxy(P, A, B);
|
|
o12 = orient2Dxy(Q, B, A);
|
|
o21 = orient2Dxy(A, P, Q);
|
|
o22 = orient2Dxy(B, Q, P);
|
|
} else if (xyz == 0) {
|
|
o11 = orient2Dyz(P, A, B);
|
|
o12 = orient2Dyz(Q, B, A);
|
|
o21 = orient2Dyz(A, P, Q);
|
|
o22 = orient2Dyz(B, Q, P);
|
|
} else {
|
|
o11 = orient2Dzx(P, A, B);
|
|
o12 = orient2Dzx(Q, B, A);
|
|
o21 = orient2Dzx(A, P, Q);
|
|
o22 = orient2Dzx(B, Q, P);
|
|
}
|
|
|
|
return ((o11 || o12) && (o11 * o12 >= 0) && (o21 || o22) && (o21 * o22 >= 0));
|
|
}
|
|
|