示例#1
0
int 
split_tris(Tri *tris, int num_tris, PQP_REAL a[3], PQP_REAL c)
{
  int i;
  int c1 = 0;
  PQP_REAL p[3];
  PQP_REAL x;
  Tri temp;

  for(i = 0; i < num_tris; i++)
  {
    // loop invariant: up to (but not including) index c1 in group 1,
    // then up to (but not including) index i in group 2
    //
    //  [1] [1] [1] [1] [2] [2] [2] [x] [x] ... [x]
    //                   c1          i
    //
    VcV(p, tris[i].p1);
    VpV(p, p, tris[i].p2);
    VpV(p, p, tris[i].p3);      
    x = VdotV(p, a);
    x /= 3.0;
    if (x <= c)
    {
	    // group 1
	    temp = tris[i];
	    tris[i] = tris[c1];
	    tris[c1] = temp;
	    c1++;
    }
    else
    {
	    // group 2 -- do nothing
    }
  }

  // split arbitrarily if one group empty

  if ((c1 == 0) || (c1 == num_tris)) c1 = num_tris/2;

  return c1;
}
示例#2
0
void
SegPoints(PQP_REAL VEC[3],
          PQP_REAL X[3], PQP_REAL Y[3],             // closest points
          const PQP_REAL P[3], const PQP_REAL A[3], // seg 1 origin, vector
          const PQP_REAL Q[3], const PQP_REAL B[3]) // seg 2 origin, vector
{
    PQP_REAL T[3], A_dot_A, B_dot_B, A_dot_B, A_dot_T, B_dot_T;
    PQP_REAL TMP[3];

    VmV(T,Q,P);
    A_dot_A = VdotV(A,A);
    B_dot_B = VdotV(B,B);
    A_dot_B = VdotV(A,B);
    A_dot_T = VdotV(A,T);
    B_dot_T = VdotV(B,T);

    // t parameterizes ray P,A
    // u parameterizes ray Q,B

    PQP_REAL t,u;

    // compute t for the closest point on ray P,A to
    // ray Q,B

    PQP_REAL denom = A_dot_A*B_dot_B - A_dot_B*A_dot_B;

    t = (A_dot_T*B_dot_B - B_dot_T*A_dot_B) / denom;

    // clamp result so t is on the segment P,A

    if ((t < 0) || isnan(t)) t = 0; else if (t > 1) t = 1;

    // find u for point on ray Q,B closest to point at t

    u = (t*A_dot_B - B_dot_T) / B_dot_B;

    // if u is on segment Q,B, t and u correspond to
    // closest points, otherwise, clamp u, recompute and
    // clamp t

    if ((u <= 0) || isnan(u)) {

        VcV(Y, Q);

        t = A_dot_T / A_dot_A;

        if ((t <= 0) || isnan(t)) {
            VcV(X, P);
            VmV(VEC, Q, P);
        }
        else if (t >= 1) {
            VpV(X, P, A);
            VmV(VEC, Q, X);
        }
        else {
            VpVxS(X, P, A, t);
            VcrossV(TMP, T, A);
            VcrossV(VEC, A, TMP);
        }
    }
    else if (u >= 1) {

        VpV(Y, Q, B);

        t = (A_dot_B + A_dot_T) / A_dot_A;

        if ((t <= 0) || isnan(t)) {
            VcV(X, P);
            VmV(VEC, Y, P);
        }
        else if (t >= 1) {
            VpV(X, P, A);
            VmV(VEC, Y, X);
        }
        else {
            VpVxS(X, P, A, t);
            VmV(T, Y, P);
            VcrossV(TMP, T, A);
            VcrossV(VEC, A, TMP);
        }
    }
    else {

        VpVxS(Y, Q, B, u);

        if ((t <= 0) || isnan(t)) {
            VcV(X, P);
            VcrossV(TMP, T, B);
            VcrossV(VEC, B, TMP);
        }
        else if (t >= 1) {
            VpV(X, P, A);
            VmV(T, Q, X);
            VcrossV(TMP, T, B);
            VcrossV(VEC, B, TMP);
        }
        else {
            VpVxS(X, P, A, t);
            VcrossV(VEC, A, B);
            if (VdotV(VEC, T) < 0) {
                VxS(VEC, VEC, -1);
            }
        }
    }
}