コード例 #1
0
ファイル: tri_coll_test.c プロジェクト: boyisgood86/japp
// Compute intervals
static int COMPUTE_INTERVALS( float VV0, float VV1, float VV2, float D0, float D1, float D2, float D0D1, float D0D2, float *isect0, float *isect1,
	vector3 *N1, vector3 *V0, vector3 *V1, vector3 *V2, vector3 *U0, vector3 *U1, vector3 *U2 ) {
	if ( D0D1 > 0.0f )
		ISECT( VV2, VV0, VV1, D2, D0, D1, isect0, isect1 );
	else if ( D0D2 > 0.0f )
		ISECT( VV1, VV0, VV2, D1, D0, D2, isect0, isect1 );
	else if ( D1*D2 > 0.0f || D0 != 0.0f )
		ISECT( VV0, VV1, VV2, D0, D1, D2, isect0, isect1 );
	else if ( D1 != 0.0f )
		ISECT( VV1, VV0, VV2, D1, D0, D2, isect0, isect1 );
	else if ( D2 != 0.0f )
		ISECT( VV2, VV0, VV1, D2, D0, D1, isect0, isect1 );
	else
		return coplanar_tri_tri( N1, V0, V1, V2, U0, U1, U2 );
	return -1;
}
コード例 #2
0
ファイル: tri_tri.c プロジェクト: Sophiealex/jgt-code
int tri_tri_intersect(float V0[3],float V1[3],float V2[3],
                      float U0[3],float U1[3],float U2[3])
{

  float E1[3],E2[3];
  float N1[3],N2[3],d1,d2;
  float tmp[3];
  float du0,du1,du2,dv0,dv1,dv2;
  float N[3];
  float tdu0,tdu1,tdv0,tdv1;
  float du01,du02;
  /* flags of which vertex is single on one side of plane(U0,U1,U2), and plane(V0,V1,V2) */
  /* VV0 is the pointer to the single vertex in (V0,V1,V2) of the plane(U0,U1,U2) */
  /* UU0 is the pointer to the single vertex in (U0,U1,U2) of the plane(V0,V1,V2) */
  float *UU0,*UU1,*UU2,*VV0,*VV1,*VV2;

  /* compute plane equation of triangle(U0,U1,U2) */
  SUB(E1,U1,U0);
  SUB(E2,U2,U0);
  CROSS(N1,E1,E2);
  d1=-DOT(N1,U0);
  /* plane equation 1: N1.X+d1=0 */
  /* put V0,V1,V2 into plane equation 1 to compute signed distances to the plane*/
  dv0=DOT(N1,V0)+d1;
  dv1=DOT(N1,V1)+d1;
  dv2=DOT(N1,V2)+d1;

  /* coplanarity robustness check */
#if USE_EPSILON_TEST==TRUE
  if(FABS(dv0)<EPSILON) dv0=0.0;
  if(FABS(dv1)<EPSILON) dv1=0.0;
  if(FABS(dv2)<EPSILON) dv2=0.0;
#endif

  if(SAMESIGN012(dv0,dv1,dv2)) /* same sign on all of them + not equal 0 ? */
    return 0;               /* no intersection occurs */


  /* compute plane equation of triangle(V0,V1,V2) */
  SUB(E1,V1,V0);
  SUB(E2,V2,V0);
  CROSS(N2,E1,E2);
  d2=-DOT(N2,V0);
  /* plane equation 2: N2.X+d2=0 */

  /* put U0,U1,U2 into plane equation 1 to compute signed distances to the plane*/
  du0=DOT(N2,U0)+d2;
  du1=DOT(N2,U1)+d2;
  du2=DOT(N2,U2)+d2;

  /* coplanarity robustness check */
#if USE_EPSILON_TEST==TRUE
  if(FABS(du0)<EPSILON) du0=0.0;
  if(FABS(du1)<EPSILON) du1=0.0;
  if(FABS(du2)<EPSILON) du2=0.0;
#endif

  if(SAMESIGN012(du0,du1,du2)) /* same sign on all of them + not equal 0 ? */
    return 0;               /* no intersection occurs */

  /* V0,V1,V2,U0,U1,U2 are all in the same plane */
  if ((dv0==0)&&(dv1==0)&&(dv2==0))
  return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2);



  /* replace V0,V1,V2 with VV0,VV1,VV2 */
  if      (SIGN01_DIF_SIGN2(dv1,dv2,dv0))
  {
    VV0=V0;VV1=V1;VV2=V2;tdv0=dv0;tdv1=dv1;    /* V0 is single vertex of the plane of triangle (U0,U1,U2) */
  }
  else if (SIGN01_DIF_SIGN2(dv2,dv0,dv1))
  {
    VV0=V1;VV1=V2;VV2=V0;tdv0=dv1;tdv1=dv2;    /* V1 is single vertex of the plane of triangle (U0,U1,U2) */
  }
  else if (SIGN01_DIF_SIGN2(dv0,dv1,dv2))
  {
    VV0=V2;VV1=V0;VV2=V1;tdv0=dv2;tdv1=dv0;    /* V2 is single vertex of the plane of triangle (U0,U1,U2) */
  }


  /* replace U0,U1,U2 with UU0,UU1,UU2 */
  if      (SIGN01_DIF_SIGN2(du1,du2,du0))
  {
    UU0=U0;UU1=U1;UU2=U2;tdu0=du0;tdu1=du1;  /* U0 is single vertex of the plane of triangle (V0,V1,V2) */
  }
  else if (SIGN01_DIF_SIGN2(du2,du0,du1))
  {
    UU0=U1;UU1=U2;UU2=U0;tdu0=du1;tdu1=du2;  /* U1 is single vertex of the plane of triangle (V0,V1,V2) */
  }
  else if (SIGN01_DIF_SIGN2(du0,du1,du2))
  {
    UU0=U2;UU1=U0;UU2=U1;tdu0=du2;tdu1=du0;  /* U2 is single vertex of the plane of triangle (V0,V1,V2) */
  }


  /* compute distance between lines of triangle (V0,V1,V2) and triangle (U0,U1,U2) */
  if ((tdu0>=0) && (tdu1<=0))
  {
    if ((tdv0>=0) && (tdv1<=0))
    {
      SUB(E1,VV0,VV2);
      SUB(E2,UU0,UU2);
      CROSS(N,E1,E2);
      SUB(tmp,UU0,VV0);
      du02=DOT(N,tmp);
#if USE_EPSILON_TEST==TRUE
      if (du02>EPSILON)
#else
      if (du02>0)
#endif
        return 0;
      
      SUB(E1,VV1,VV0);
      SUB(E2,UU1,UU0);
      CROSS(N,E1,E2);
      SUB(tmp,UU0,VV0);
      du01=DOT(N,tmp);
#if USE_EPSILON_TEST==TRUE
      if (du01<-EPSILON)
#else
      if (du01<0)
#endif
        return 0;
    }
    else
    {
      SUB(E1,VV1,VV0);
      SUB(E2,UU0,UU2);
      CROSS(N,E1,E2);
      SUB(tmp,UU0,VV0);
      du02=DOT(N,tmp);
#if USE_EPSILON_TEST==TRUE
      if (du02>EPSILON)
#else
      if (du02>0)
#endif
        return 0;
      
      SUB(E1,VV0,VV2);
      SUB(E2,UU1,UU0);
      CROSS(N,E1,E2);
      SUB(tmp,UU0,VV0);
      du01=DOT(N,tmp);
#if USE_EPSILON_TEST==TRUE
      if (du01<-EPSILON)
#else
      if (du01<0)
#endif
        return 0;
    }
  }
  else
  {
    if ((tdv0>=0) && (tdv1<=0))
    {
      SUB(E1,VV0,VV2);
      SUB(E2,UU1,UU0);
      CROSS(N,E1,E2);
      SUB(tmp,UU0,VV0);
      du01=DOT(N,tmp);
#if USE_EPSILON_TEST==TRUE
      if (du01>EPSILON)
#else
      if (du01>0)
#endif
        return 0;
      
      SUB(E1,VV1,VV0);
      SUB(E2,UU0,UU2);
      CROSS(N,E1,E2);
      SUB(tmp,UU0,VV0);
      du02=DOT(N,tmp);
#if USE_EPSILON_TEST==TRUE
      if (du02<-EPSILON)
#else
      if (du02<0)
#endif
        return 0;
    }
    else
    {
      SUB(E1,VV1,VV0);
      SUB(E2,UU1,UU0);
      CROSS(N,E1,E2);
      SUB(tmp,UU0,VV0);
      du01=DOT(N,tmp);
#if USE_EPSILON_TEST==TRUE
      if (du01>EPSILON)
#else
      if (du01>0)
#endif
        return 0;
      
      SUB(E1,VV0,VV2);
      SUB(E2,UU0,UU2);
      CROSS(N,E1,E2);
      SUB(tmp,UU0,VV0);
      du02=DOT(N,tmp);
#if USE_EPSILON_TEST==TRUE
      if (du02<-EPSILON)
#else
      if (du02<0)
#endif
        return 0;
    }
  }

  return 1;
}
コード例 #3
0
ファイル: tri_coll_test.cpp プロジェクト: Arcadiaprime/japp
qboolean tri_tri_intersect( vector3 *V0, vector3 *V1, vector3 *V2, vector3 *U0, vector3 *U1, vector3 *U2 ) {
	vector3 E1, E2, N1, N2, D;
	float d1, d2;
	float du0, du1, du2, dv0, dv1, dv2;
	float isect1[2], isect2[2];
	float du0du1, du0du2, dv0dv1, dv0dv2;
	short index;
	float vp0, vp1, vp2, up0, up1, up2;
	float bb, cc, max;
	float a, b, c, d, e, f, x0, x1, y0, y1;
	float xx, yy, xxyy, tmp;

	// compute plane of tri(V0, V1, V2)
	VectorSubtract( V1, V0, &E1 );
	VectorSubtract( V2, V0, &E2 );
	CrossProduct( &E1, &E2, &N1 );
	d1 = -DotProduct( &N1, V0 );

	// put U0,U1,U2 into plane equation 1 to compute signed distances to the plane
	du0 = DotProduct( &N1, U0 ) + d1;
	du1 = DotProduct( &N1, U1 ) + d1;
	du2 = DotProduct( &N1, U2 ) + d1;

	// coplanarity robustness check
	if ( Q_fabs( du0 ) < epsilon ) {
		du0 = 0.0f;
	}
	if ( Q_fabs( du1 ) < epsilon ) {
		du1 = 0.0f;
	}
	if ( Q_fabs( du2 ) < epsilon ) {
		du2 = 0.0f;
	}

	du0du1 = du0 * du1;
	du0du2 = du0 * du2;

	// same sign on all of them + not equal 0, no intersection occurs
	if ( du0du1 > 0.0f && du0du2 > 0.0f ) {
		return qfalse;
	}

	// compute plane of tri(U0, U1, U2)
	VectorSubtract( U1, U0, &E1 );
	VectorSubtract( U2, U0, &E2 );
	CrossProduct( &E1, &E2, &N2 );
	d2 = -DotProduct( &N2, U0 );

	// put V0,V1,V2 into plane equation 1 to compute signed distances to the plane
	dv0 = DotProduct( &N2, V0 ) + d2;
	dv1 = DotProduct( &N2, V1 ) + d2;
	dv2 = DotProduct( &N2, V2 ) + d2;

	// coplanarity robustness check
	if ( Q_fabs( dv0 ) < epsilon ) {
		dv0 = 0.0f;
	}
	if ( Q_fabs( dv1 ) < epsilon ) {
		dv1 = 0.0f;
	}
	if ( Q_fabs( dv2 ) < epsilon ) {
		dv2 = 0.0f;
	}

	dv0dv1 = dv0 * dv1;
	dv0dv2 = dv0 * dv2;

	// same sign on all of them + not equal 0, no intersection occurs
	if ( dv0dv1 > 0.0f && dv0dv2 > 0.0f ) {
		return qfalse;
	}

	// compute direction of intersection line
	CrossProduct( &D, &N1, &N2 );

	// compute and index to the largest component of D
	max = Q_fabs( D.x );
	index = 0;
	bb = Q_fabs( D.y );
	cc = Q_fabs( D.z );
	if ( bb > max ) {
		max = bb;
		index = 1;
	}
	if ( cc > max ) {
		max = cc;
		index = 2;
	}

	// this is the simplified projection onto L
	vp0 = V0->raw[index];
	vp1 = V1->raw[index];
	vp2 = V2->raw[index];

	up0 = U0->raw[index];
	up1 = U1->raw[index];
	up2 = U2->raw[index];

	// compute_intervals
	if ( dv0dv1 > 0.0f ) {
		a = vp2;
		b = (vp0 - vp2) * dv2;
		c = (vp1 - vp2) * dv2;
		x0 = dv2 - dv0;
		x1 = dv2 - dv1;
	}
	else if ( dv0dv2 > 0.0f ) {
		a = vp1;
		b = (vp0 - vp1) * dv1;
		c = (vp2 - vp1) * dv1;
		x0 = dv1 - dv0;
		x1 = dv1 - dv2;
	}
	else if ( dv1 * dv2 > 0.0f || dv0 != 0.0f ) {
		a = vp0;
		b = (vp1 - vp0) * dv0;
		c = (vp2 - vp0) * dv0;
		x0 = dv0 - dv1;
		x1 = dv0 - dv2;
	}
	else if ( dv1 != 0.0f ) {
		a = vp1;
		b = (vp0 - vp1) * dv1;
		c = (vp2 - vp1) * dv1;
		x0 = dv1 - dv0;
		x1 = dv1 - dv2;
	}
	else if ( dv2 != 0.0f ) {
		a = vp2;
		b = (vp0 - vp2) * dv2;
		c = (vp1 - vp2) * dv2;
		x0 = dv2 - dv0;
		x1 = dv2 - dv1;
	}
	else {
		return coplanar_tri_tri( &N1, V0, V1, V2, U0, U1, U2 );
	}

	// compute_intervals
	if ( du0du1 > 0.0f ) {
		d = up2;
		e = (up0 - up2) * du2;
		f = (up1 - up2) * du2;
		y0 = du2 - du0;
		y1 = du2 - du1;
	}
	else if ( du0du2 > 0.0f ) {
		d = up1;
		e = (up0 - up1) * du1;
		f = (up2 - up1) * du1;
		y0 = du1 - du0;
		y1 = du1 - du2;
	}
	else if ( du1 * du2 > 0.0f || du0 != 0.0f ) {
		d = up0;
		e = (up1 - up0) * du0;
		f = (up2 - up0) * du0;
		y0 = du0 - du1;
		y1 = du0 - du2;
	}
	else if ( du1 != 0.0f ) {
		d = up1;
		e = (up0 - up1) * du1;
		f = (up2 - up1) * du1;
		y0 = du1 - du0;
		y1 = du1 - du2;
	}
	else if ( du2 != 0.0f ) {
		d = up2;
		e = (up0 - up2) * du2;
		f = (up1 - up2) * du2;
		y0 = du2 - du0;
		y1 = du2 - du1;
	}
	else {
		return coplanar_tri_tri( &N1, V0, V1, V2, U0, U1, U2 );
	}

	xx = x0 * x1;
	yy = y0 * y1;
	xxyy = xx * yy;

	tmp = a * xxyy;
	isect1[0] = tmp + b * x1 * yy;
	isect1[1] = tmp + c * x0 * yy;

	tmp = d * xxyy;
	isect2[0] = tmp + e * xx * y1;
	isect2[1] = tmp + f * xx * y0;

	// sort so that a <= b
	sort( &isect1[0], &isect1[1] );
	sort( &isect2[0], &isect2[1] );

	if ( isect1[1] < isect2[0] || isect2[1] < isect1[0] ) {
		return qfalse;
	}

	return qtrue;
}
コード例 #4
0
ファイル: tri_tri.c プロジェクト: cogitokat/brlcad
int bn_tri_tri_isect_with_line(point_t V0, point_t V1, point_t V2,
			       point_t U0, point_t U1, point_t U2,
			       int *coplanar, point_t *isectpt1, point_t *isectpt2)
{
    point_t E1, E2;
    point_t N1, N2;
    fastf_t d1, d2;
    fastf_t du0, du1, du2, dv0, dv1, dv2;
    fastf_t D[3];
    fastf_t isect1[2] = {0, 0};
    fastf_t isect2[2] = {0, 0};
    point_t isectpointA1 = VINIT_ZERO;
    point_t isectpointA2 = VINIT_ZERO;
    point_t isectpointB1 = VINIT_ZERO;
    point_t isectpointB2 = VINIT_ZERO;
    fastf_t du0du1, du0du2, dv0dv1, dv0dv2;
    short index;
    fastf_t vp0, vp1, vp2;
    fastf_t up0, up1, up2;
    fastf_t b, c, max;
    int smallest1, smallest2;

    /* compute plane equation of triangle(V0, V1, V2) */
    VSUB2(E1, V1, V0);
    VSUB2(E2, V2, V0);
    VCROSS(N1, E1, E2);
    d1=-VDOT(N1, V0);
    /* plane equation 1: N1.X+d1=0 */

    /* put U0, U1, U2 into plane equation 1 to compute signed distances to the plane*/
    du0=VDOT(N1, U0)+d1;
    du1=VDOT(N1, U1)+d1;
    du2=VDOT(N1, U2)+d1;

    /* coplanarity robustness check */
#if USE_EPSILON_TEST
    if (fabs(du0)<EPSILON) du0=0.0;
    if (fabs(du1)<EPSILON) du1=0.0;
    if (fabs(du2)<EPSILON) du2=0.0;
#endif
    du0du1=du0*du1;
    du0du2=du0*du2;

    if (du0du1>0.0f && du0du2>0.0f) /* same sign on all of them + not equal 0 ? */
	return 0;                    /* no intersection occurs */

    /* compute plane of triangle (U0, U1, U2) */
    VSUB2(E1, U1, U0);
    VSUB2(E2, U2, U0);
    VCROSS(N2, E1, E2);
    d2=-VDOT(N2, U0);
    /* plane equation 2: N2.X+d2=0 */

    /* put V0, V1, V2 into plane equation 2 */
    dv0=VDOT(N2, V0)+d2;
    dv1=VDOT(N2, V1)+d2;
    dv2=VDOT(N2, V2)+d2;

#if USE_EPSILON_TEST
    if (fabs(dv0)<EPSILON) dv0=0.0;
    if (fabs(dv1)<EPSILON) dv1=0.0;
    if (fabs(dv2)<EPSILON) dv2=0.0;
#endif

    dv0dv1=dv0*dv1;
    dv0dv2=dv0*dv2;

    if (dv0dv1>0.0f && dv0dv2>0.0f) /* same sign on all of them + not equal 0 ? */
	return 0;                    /* no intersection occurs */

    /* compute direction of intersection line */
    VCROSS(D, N1, N2);

    /* compute and index to the largest component of D */
    max=fabs(D[0]);
    index=0;
    b=fabs(D[1]);
    c=fabs(D[2]);
    if (b>max) max=b, index=1;
    if (c>max) index=2;

    /* this is the simplified projection onto L*/
    vp0=V0[index];
    vp1=V1[index];
    vp2=V2[index];

    up0=U0[index];
    up1=U1[index];
    up2=U2[index];

    /* compute interval for triangle 1 */
    *coplanar=compute_intervals_isectline(V0, V1, V2, vp0, vp1, vp2, dv0, dv1, dv2,
					  dv0dv1, dv0dv2, &isect1[0], &isect1[1], isectpointA1, isectpointA2);
    if (*coplanar) return coplanar_tri_tri(N1, V0, V1, V2, U0, U1, U2);


    /* compute interval for triangle 2 */
    compute_intervals_isectline(U0, U1, U2, up0, up1, up2, du0, du1, du2,
				du0du1, du0du2, &isect2[0], &isect2[1], isectpointB1, isectpointB2);

    SORT2(isect1[0], isect1[1], smallest1);
    SORT2(isect2[0], isect2[1], smallest2);

    if (isect1[1]<isect2[0] || isect2[1]<isect1[0]) return 0;

    /* at this point, we know that the triangles intersect */

    if (isect2[0]<isect1[0]) {
	if (smallest1==0) { VMOVE(*isectpt1, isectpointA1); } else { VMOVE(*isectpt1, isectpointA2); }

	if (isect2[1]<isect1[1]) {
	    if (smallest2==0) { VMOVE(*isectpt2, isectpointB2); } else { VMOVE(*isectpt2, isectpointB1); }
	} else {
	    if (smallest1==0) { VMOVE(*isectpt2, isectpointA2); } else { VMOVE(*isectpt2, isectpointA1); }
	}
    } else {
	if (smallest2==0) { VMOVE(*isectpt1, isectpointB1); } else { VMOVE(*isectpt1, isectpointB2); }

	if (isect2[1]>isect1[1]) {
	    if (smallest1==0) { VMOVE(*isectpt2, isectpointA2); } else { VMOVE(*isectpt2, isectpointA1); }
	} else {
	    if (smallest2==0) { VMOVE(*isectpt2, isectpointB2); } else { VMOVE(*isectpt2, isectpointB1); }
	}
    }
    return 1;
}