⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 geometricpredicates.cpp

📁 利用C
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*  Sets h = e + f.  See the long version of my 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.                                                              *//*                                                                           *//*****************************************************************************/static int fast_expansion_sum_zeroelim(int elen, REAL *e, 				       int flen, REAL *f, REAL *h)     /* h cannot be e or f. */{  REAL Q;  INEXACT REAL Qnew;  INEXACT REAL hh;  INEXACT REAL bvirt;  REAL avirt, bround, around;  int eindex, findex, hindex;  REAL 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)) {      Fast_Two_Sum(enow, Q, Qnew, hh);      enow = e[++eindex];    } else {      Fast_Two_Sum(fnow, Q, Qnew, hh);      fnow = f[++findex];    }    Q = Qnew;    if (hh != 0.0) {      h[hindex++] = hh;    }    while ((eindex < elen) && (findex < flen)) {      if ((fnow > enow) == (fnow > -enow)) {        Two_Sum(Q, enow, Qnew, hh);        enow = e[++eindex];      } else {        Two_Sum(Q, fnow, Qnew, hh);        fnow = f[++findex];      }      Q = Qnew;      if (hh != 0.0) {        h[hindex++] = hh;      }    }  }  while (eindex < elen) {    Two_Sum(Q, enow, Qnew, hh);    enow = e[++eindex];    Q = Qnew;    if (hh != 0.0) {      h[hindex++] = hh;    }  }  while (findex < flen) {    Two_Sum(Q, fnow, Qnew, hh);    fnow = f[++findex];    Q = Qnew;    if (hh != 0.0) {      h[hindex++] = hh;    }  }  if ((Q != 0.0) || (hindex == 0)) {    h[hindex++] = Q;  }  return hindex;}/*****************************************************************************//*                                                                           *//*  scale_expansion_zeroelim()   Multiply an expansion by a scalar,          *//*                               eliminating zero components from the        *//*                               output expansion.                           *//*                                                                           *//*  Sets h = be.  See either version of my 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.)                                                                 *//*                                                                           *//*****************************************************************************/static int scale_expansion_zeroelim(int elen, REAL *e, REAL b, REAL *h)     /* e and h cannot be the same. */{  INEXACT REAL Q, sum;  REAL hh;  INEXACT REAL product1;  REAL product0;  int eindex, hindex;  REAL enow;  INEXACT REAL bvirt;  REAL avirt, bround, around;  INEXACT REAL c;  INEXACT REAL abig;  REAL ahi, alo, bhi, blo;  REAL err1, err2, err3;  Split(b, bhi, blo);  Two_Product_Presplit(e[0], b, bhi, blo, Q, hh);  hindex = 0;  if (hh != 0) {    h[hindex++] = hh;  }  for (eindex = 1; eindex < elen; eindex++) {    enow = e[eindex];    Two_Product_Presplit(enow, b, bhi, blo, product1, product0);    Two_Sum(Q, product0, sum, hh);    if (hh != 0) {      h[hindex++] = hh;    }    Fast_Two_Sum(product1, sum, Q, hh);    if (hh != 0) {      h[hindex++] = hh;    }  }  if ((Q != 0.0) || (hindex == 0)) {    h[hindex++] = Q;  }  return hindex;}/*****************************************************************************//*                                                                           *//*  estimate()   Produce a one-word estimate of an expansion's value.        *//*                                                                           *//*  See either version of my paper for details.                              *//*                                                                           *//*****************************************************************************/static REAL estimate(int elen, REAL *e){  REAL Q;  int eindex;  Q = e[0];  for (eindex = 1; eindex < elen; eindex++) {    Q += e[eindex];  }  return Q;}/*****************************************************************************//*                                                                           *//*  orient2dfast()   Approximate 2D orientation test.  Nonrobust.            *//*  orient2dexact()   Exact 2D orientation test.  Robust.                    *//*  orient2dslow()   Another exact 2D orientation test.  Robust.             *//*  orient2d()   Adaptive exact 2D orientation test.  Robust.                *//*                                                                           *//*               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.           *//*                                                                           *//*  Only the first and last routine should be used; the middle two are for   *//*  timings.                                                                 *//*                                                                           *//*  The last three use exact arithmetic to ensure a correct answer.  The     *//*  result returned is the determinant of a matrix.  In orient2d() only,     *//*  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, orient2d() is usually quite *//*  fast, but will run more slowly when the input points are collinear or    *//*  nearly so.                                                               *//*                                                                           *//*****************************************************************************/static REAL orient2dadapt(REAL *pa, REAL *pb, REAL *pc, REAL detsum){  INEXACT REAL acx, acy, bcx, bcy;  REAL acxtail, acytail, bcxtail, bcytail;  INEXACT REAL detleft, detright;  REAL detlefttail, detrighttail;  REAL det, errbound;  REAL B[4], C1[8], C2[12], D[16];  INEXACT REAL B3;  int C1length, C2length, Dlength;  REAL u[4];  INEXACT REAL u3;  INEXACT REAL s1, t1;  REAL s0, t0;  INEXACT REAL bvirt;  REAL avirt, bround, around;  INEXACT REAL c;  INEXACT REAL abig;  REAL ahi, alo, bhi, blo;  REAL err1, err2, err3;  INEXACT REAL _i, _j;  REAL _0;  acx = (REAL) (pa[0] - pc[0]);  bcx = (REAL) (pb[0] - pc[0]);  acy = (REAL) (pa[1] - pc[1]);  bcy = (REAL) (pb[1] - pc[1]);  Two_Product(acx, bcy, detleft, detlefttail);  Two_Product(acy, bcx, detright, detrighttail);  Two_Two_Diff(detleft, detlefttail, detright, detrighttail,               B3, B[2], B[1], B[0]);  B[3] = B3;  det = estimate(4, B);  errbound = ccwerrboundB * detsum;  if ((det >= errbound) || (-det >= errbound)) {    return det;  }  Two_Diff_Tail(pa[0], pc[0], acx, acxtail);  Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail);  Two_Diff_Tail(pa[1], pc[1], acy, acytail);  Two_Diff_Tail(pb[1], pc[1], bcy, bcytail);  if ((acxtail == 0.0) && (acytail == 0.0)      && (bcxtail == 0.0) && (bcytail == 0.0)) {    return det;  }  errbound = ccwerrboundC * detsum + resulterrbound * Absolute(det);  det += (acx * bcytail + bcy * acxtail)       - (acy * bcxtail + bcx * acytail);  if ((det >= errbound) || (-det >= errbound)) {    return det;  }  Two_Product(acxtail, bcy, s1, s0);  Two_Product(acytail, bcx, t1, t0);  Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);  u[3] = u3;  C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1);  Two_Product(acx, bcytail, s1, s0);  Two_Product(acy, bcxtail, t1, t0);  Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);  u[3] = u3;  C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2);  Two_Product(acxtail, bcytail, s1, s0);  Two_Product(acytail, bcxtail, t1, t0);  Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);  u[3] = u3;  Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D);  return(D[Dlength - 1]);}REAL orient2d(REAL *pa, REAL *pb, REAL *pc){  REAL detleft, detright, det;  REAL detsum, errbound;  REAL orient;  FPU_ROUND_DOUBLE;  detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]);  detright = (pa[1] - pc[1]) * (pb[0] - pc[0]);  det = detleft - detright;  if (detleft > 0.0) {    if (detright <= 0.0) {      FPU_RESTORE;      return det;    } else {      detsum = detleft + detright;    }  } else if (detleft < 0.0) {    if (detright >= 0.0) {      FPU_RESTORE;      return det;    } else {      detsum = -detleft - detright;    }  } else {    FPU_RESTORE;    return det;  }  errbound = ccwerrboundA * detsum;  if ((det >= errbound) || (-det >= errbound)) {    FPU_RESTORE;    return det;  }  orient = orient2dadapt(pa, pb, pc, detsum);  FPU_RESTORE;  return orient;}/*****************************************************************************//*                                                                           *//*  orient3dfast()   Approximate 3D orientation test.  Nonrobust.            *//*  orient3dexact()   Exact 3D orientation test.  Robust.                    *//*  orient3dslow()   Another exact 3D orientation test.  Robust.             *//*  orient3d()   Adaptive exact 3D orientation test.  Robust.                *//*                                                                           *//*               Return a positive value if the point pd lies below the      *//*               plane passing through pa, pb, and pc; "below" is defined so *//*               that pa, pb, and pc appear in counterclockwise order when   *//*               viewed from above the plane.  Returns a negative value if   *//*               pd lies above the plane.  Returns zero if the points are    *//*               coplanar.  The result is also a rough approximation of six  *//*               times the signed volume of the tetrahedron defined by the   *//*               four points.                                                *//*                                                                           *//*  Only the first and last routine should be used; the middle two are for   *//*  timings.                                                                 *//*                                                                           *//*  The last three use exact arithmetic to ensure a correct answer.  The     *//*  result returned is the determinant of a matrix.  In orient3d() only,     *//*  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, orient3d() is usually quite *//*  fast, but will run more slowly when the input points are coplanar or     *//*  nearly so.                                                               *//*                                                                           *//*****************************************************************************/static REAL orient3dadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd, 			  REAL permanent)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -