コード例 #1
0
//--------------------------------------------------------------------------------------------------
/// This needs to be rewritten because we need to test for crossing edges, not only point inside.
/// In addition the test for polygon 
//--------------------------------------------------------------------------------------------------
bool FanEarClipTesselator::isTriangleValid(size_t u, size_t v, size_t w)
{
    CVF_ASSERT(m_X > -1 && m_Y > -1);

    cvf::Vec3d A = (*m_nodeCoords)[u];
    cvf::Vec3d B = (*m_nodeCoords)[v];
    cvf::Vec3d C = (*m_nodeCoords)[w];

    if (  m_areaTolerance > (((B[m_X]-A[m_X])*(C[m_Y]-A[m_Y])) - ((B[m_Y]-A[m_Y])*(C[m_X]-A[m_X]))) ) return false;

    std::list<size_t>::const_iterator c;
    for (c = m_polygonIndices.begin(); c != m_polygonIndices.end(); ++c)
    {
        // The polygon points that actually make up the triangle candidate does not count
        // (but the same points on different positions in the polygon does! )
        // Todo so this test below is to accepting !! Bug !!
        if ( (*c == u) || (*c == v) || (*c == w)) continue;

        cvf::Vec3d P = (*m_nodeCoords)[*c];

        if (isPointInsideTriangle(A, B, C, P)) return false;
    }

    return true;
}
コード例 #2
0
ファイル: PAW.cpp プロジェクト: 09Hero/code
bool PAW::isPointInsideTriangleIndex(int px, int py, int triangleIndex){
    //look for triangles in source landmarks
    int v1, v2, v3;
    v1 = triangles.at<int>(triangleIndex,0);
    v2 = triangles.at<int>(triangleIndex,1);
    v3 = triangles.at<int>(triangleIndex,2);

    int x1 = srcLandmarks.at<int>(v1,0);
    int y1 = srcLandmarks.at<int>(v1,1);
    int x2 = srcLandmarks.at<int>(v2,0);
    int y2 = srcLandmarks.at<int>(v2,1);
    int x3 = srcLandmarks.at<int>(v3,0);
    int y3 = srcLandmarks.at<int>(v3,1);

    return isPointInsideTriangle(px,py,x1,y1,x2,y2,x3,y3);
}
コード例 #3
0
bool EarClipTesselator::isTriangleValid( std::list<size_t>::const_iterator u, std::list<size_t>::const_iterator v, std::list<size_t>::const_iterator w) const
{
    CVF_ASSERT(m_X > -1 && m_Y > -1);

    cvf::Vec3d A = (*m_nodeCoords)[*u];
    cvf::Vec3d B = (*m_nodeCoords)[*v];
    cvf::Vec3d C = (*m_nodeCoords)[*w];

    if (  m_areaTolerance > (((B[m_X]-A[m_X])*(C[m_Y]-A[m_Y])) - ((B[m_Y]-A[m_Y])*(C[m_X]-A[m_X]))) ) return false;

    std::list<size_t>::const_iterator c;
    std::list<size_t>::const_iterator outside;
    for (c = m_polygonIndices.begin(); c != m_polygonIndices.end(); ++c)
    {
        // The polygon points that actually make up the triangle candidate does not count
        // (but the same points on different positions in the polygon does! 
        // Except those one off the triangle, that references the start or end of the triangle)

        if ( (c == u) || (c == v) || (c == w)) continue;

        // Originally the below tests was not included which resulted in missing triangles sometimes

        outside = w; ++outside; if (outside == m_polygonIndices.end()) outside = m_polygonIndices.begin();
        if (c == outside && *c == *u) 
        {
            continue;
        }

        outside = u; if (outside == m_polygonIndices.begin()) outside = m_polygonIndices.end(); --outside; 
        if (c == outside && *c == *w) 
        {
            continue;
        }

        cvf::Vec3d P = (*m_nodeCoords)[*c];

        if (isPointInsideTriangle(A, B, C, P)) return false;
    }

    return true;
}
コード例 #4
0
//returns how many triangles were inserted in the last recursion step
int trueSeparateTriangles(Point* points, PhysicsObject* object, int currentTriangle, int size){
	float* signals = (float*)malloc(size*sizeof(float));
	int i=0;
	//verifies if any of the points is a concave point. we assumed that the points are given at counter-clockwise order
	for (i=0; i<size; i++) {
		int j = i-1<0?size-1:i-1;
		int k = i+1>=size?0:i+1;
		
		Point p1 = points[j];
		Point p2 = points[i];
		Point p3 = points[k];
		
		signals[i] =(p2.x-p1.x)*(p3.y-p2.y)-(p3.x-p2.x)*(p2.y-p1.y);
	}
	
	char isConvex = 1;
	int removable = 0;
	for(i=0;i<size;i++){
		if(signals[i]<0){//is a concave point, so the polygon is concave
			isConvex = 0;
			int j= i-1<0?size-1:i-1;
			if(signals[j]>0){//the point just before the concave one is an option for a triangle
				int k = j==0?size-1:j-1;
				char hasPointInside = 0;
				int l=0;
				for(l=0;l<size;l++){//check if the triangle has a point inside it
					if(l == i || l == j || l==k){
						continue;
					}
					if(isPointInsideTriangle(points[i], points[j], points[k], points[l])){
						hasPointInside = 1;
						break;
					}
				}
				if(hasPointInside){
					continue;
				}
				//if everything is ok, add the triangle to the structure
				object->format.polygonInfo.triangles[currentTriangle][0] = points[i];
				object->format.polygonInfo.triangles[currentTriangle][1] = points[j];
				object->format.polygonInfo.triangles[currentTriangle][2] = points[k];
				currentTriangle++;
				removable = j;
				break;
			}
			j = i+1>=size?0:i+1;
			if(signals[j]>0){//the point just after the concave one is an option for a triangle
				int k = j==size-1?0:j+1;
				char hasPointInside = 0;
				int l=0;
				for(l=0;l<size;l++){//check if the triangle has a point inside it
					if(l == i || l == j || l==k){
						continue;
					}
					if(isPointInsideTriangle(points[i], points[j], points[k], points[l])){
						hasPointInside = 1;
						break;
					}
				}
				if(hasPointInside){
					continue;
				}
				//if everything is ok, add the triangle to the structure
				object->format.polygonInfo.triangles[currentTriangle][0] = points[i];
				object->format.polygonInfo.triangles[currentTriangle][1] = points[j];
				object->format.polygonInfo.triangles[currentTriangle][2] = points[k];
				currentTriangle++;
				removable = j;
				break;
			}
		}
	}
	
	free(signals);
	
	//in the case object is convex, just fix a point and trace a line to all other points.
	if(isConvex){
		int maxTriangles = size -2;
		for(i=0;i<maxTriangles; i++){
			object->format.polygonInfo.triangles[currentTriangle][0] = points[0];
			object->format.polygonInfo.triangles[currentTriangle][1] = points[i+1];
			object->format.polygonInfo.triangles[currentTriangle][2] = points[i+2];
			currentTriangle++;
		}
		
		return size-2;
	}
	//if is a concave structure
	
	Point* points2 = copyPoints(size, points);
	for(i=removable;i<size-1;i++){
		points2[i] = points2[i+1];
	}
	
	trueSeparateTriangles(points2, object, currentTriangle, size-1);
	
	free(points2);
	
	return 1;
}
コード例 #5
0
ファイル: intr_tribox.cpp プロジェクト: sutuglon/Motor
OZCOLLIDE_API bool testIntersectionTriBox(const Vec3f *_triPts[3],
										 const Vec3f &_triNormal,
										 const Box &_box,
										 const Vec3f &_boxVel,
										 float &_distTravel,
										 Vec3f &_reaction)
{
	int i, j;
	float d0, d1;
	float t;

	Plane tri_plane;
	tri_plane.fromPointAndNormal(*_triPts[0], _triNormal);

	Vec3f n_boxvel = _boxVel;
	n_boxvel.normalize();

	if (_triNormal.dot(n_boxvel) > 0)
		return false;

	float minDist = FLT_MAX;
	int col = -1;

	// box vertices VS triangle
	for (i = 0; i < 8; i++) {
		Vec3f box_vertex = _box.getPoint(i);

		Vec3f box_vertex_normal = _box.getVertexNormal(i);
		if (box_vertex_normal.dot(n_boxvel) < -OZ_COS45)
			continue;

		float t;
		if (!tri_plane.intersectWithLine(box_vertex, box_vertex + n_boxvel, t) )
			continue;

		if (t >= minDist)
			continue;
		if (t < 0)
			continue;

		Vec3f inter;
		inter = box_vertex + n_boxvel * t;

		if (!isPointInsideTriangle(*_triPts[0], *_triPts[1], *_triPts[2], inter))
			continue;

		minDist = t;
		_reaction = _triNormal;
		col = 0;
	}

	// triangle vertices VS box faces
	for (i = 0; i < 3; i++) {
		float tnear, tfar;
		PLANE plane = intersectRayBox(*_triPts[i], -n_boxvel, _box, tnear, tfar);
		if (plane == -1)
			continue;

		if (tnear < 0)
			continue;

		if (tnear < minDist) {
			minDist = tnear;
			_reaction = -_box.getFaceNormal(plane);
			col = 1;
		}
	}

	// box edges VS triangle edges
	for (i = 0; i < 12; i++) {
		BoxEdge boxEdge = _box.getEdge(i);
		Plane boxEdgePlane;
		boxEdgePlane.fromPoints(boxEdge.p1, boxEdge.p0, boxEdge.p0 + _boxVel);

		Vec3f boxEdgeNormal = Vec3f(boxEdgePlane.a, boxEdgePlane.b, boxEdgePlane.c);

		Vec3f v0 = boxEdge.p1 - boxEdge.p0;

		for (j = 0; j < 3; j++) {
			const Vec3f *tpt0;
			const Vec3f *tpt1;
			tpt0 = _triPts[j];
			if (j < 2) tpt1 = _triPts[j + 1];
			else tpt1 = _triPts[0];

			d0 = boxEdgePlane.dist(*tpt0);
			d1 = boxEdgePlane.dist(*tpt1);
			if (d0 * d1 > 0)
				continue;

			if (!boxEdgePlane.intersectWithLine(*tpt0, *tpt1, t))
				continue;

			Vec3f v1 = *tpt1 - *tpt0;
			Vec3f ipt = *tpt0 + v1 * t;

			int a0 = 0, a1 = 1;
			float pl_x = fabsf(boxEdgePlane.a);
			float pl_y = fabsf(boxEdgePlane.b);
			float pl_z = fabsf(boxEdgePlane.c);
			if (pl_x > pl_y && pl_x > pl_z) {
				a0 = 1;
				a1 = 2;
			}
			else {
				if (pl_y > pl_z) {
					a0 = 0;
					a1 = 2;
				}
			}

			float dist = v0[a0] * (ipt[a1] - boxEdge.p0[a1]) - v0[a1] * (ipt[a0] - boxEdge.p0[a0]);
			float denom = v0[a1] * -n_boxvel[a0] - v0[a0] * -n_boxvel[a1];
			if (!denom)
				continue;
			dist /= denom;

			if (dist < 0)
				continue;

			ipt -= dist * n_boxvel;

			Vec3f r1 = boxEdge.p0 - ipt;
			Vec3f r2 = boxEdge.p1 - ipt;
			if (r1.dot(r2) > 0)
				continue;

			if (dist < minDist) {
				minDist = dist;
				_reaction = v0 | v1;
				_reaction.normalize();
				if (_reaction.dot(n_boxvel) > 0)
					_reaction = -_reaction;
				col = 2;
			}
		}
	}

	if (col == -1)
		return false;

	_distTravel = minDist;

	return true;
}