Example #1
0
static void
cpPolyShapeNearestPointQuery(cpPolyShape *poly, cpVect p, cpNearestPointQueryInfo *info) {
    int count = poly->numVerts;
    cpSplittingPlane *planes = poly->tPlanes;
    cpVect *verts = poly->tVerts;

    cpVect v0 = verts[count - 1];
    cpFloat minDist = INFINITY;
    cpVect closestPoint = cpvzero;
    cpBool outside = cpFalse;

    for(int i=0; i<count; i++) {
        if(cpSplittingPlaneCompare(planes[i], p) > 0.0f) outside = cpTrue;

        cpVect v1 = verts[i];
        cpVect closest = cpClosetPointOnSegment(p, v0, v1);

        cpFloat dist = cpvdist(p, closest);
        if(dist < minDist) {
            minDist = dist;
            closestPoint = closest;
        }

        v0 = v1;
    }

    info->shape = (cpShape *)poly;
    info->p = closestPoint; // TODO div/0
    info->d = (outside ? minDist : -minDist);
}
Example #2
0
static void
cpSegmentShapeNearestPointQuery(cpSegmentShape *seg, cpVect p, cpNearestPointQueryInfo *info)
{
	cpVect closest = cpClosetPointOnSegment(p, seg->ta, seg->tb);
	
	cpVect delta = cpvsub(p, closest);
	cpFloat d = cpvlength(delta);
	cpFloat r = seg->r;
	
	info->shape = (cpShape *)seg;
	info->p = (d ? cpvadd(closest, cpvmult(delta, r/d)) : closest);
	info->d = d - r;
}
Example #3
0
static void
cpSegmentShapePointQuery(cpSegmentShape *seg, cpVect p, cpPointQueryInfo *info)
{
	cpVect closest = cpClosetPointOnSegment(p, seg->ta, seg->tb);
	
	cpVect delta = cpvsub(p, closest);
	cpFloat d = cpvlength(delta);
	cpFloat r = seg->r;
	cpVect g = cpvmult(delta, 1.0f/d);
	
	info->shape = (cpShape *)seg;
	info->point = (d ? cpvadd(closest, cpvmult(g, r)) : closest);
	info->distance = d - r;
	
	// Use the segment's normal if the distance is very small.
	info->gradient = (d > MAGIC_EPSILON ? g : seg->n);
}
static void
cpPolyShapeNearestPointQuery(cpPolyShape *poly, cpVect p, cpNearestPointQueryInfo *info){
	int count = poly->numVerts;
	cpSplittingPlane *planes = poly->tPlanes;
	cpVect *verts = poly->tVerts;
	cpFloat r = poly->r;
	
	cpVect v0 = verts[count - 1];
	cpFloat minDist = INFINITY;
	cpVect closestPoint = cpvzero;
	cpVect closestNormal = cpvzero;
	cpBool outside = cpFalse;
	
	for(int i=0; i<count; i++){
		if(cpSplittingPlaneCompare(planes[i], p) > 0.0f) outside = cpTrue;
		
		cpVect v1 = verts[i];
		cpVect closest = cpClosetPointOnSegment(p, v0, v1);
		
		cpFloat dist = cpvdist(p, closest);
		if(dist < minDist){
			minDist = dist;
			closestPoint = closest;
			closestNormal = planes[i].n;
		}
		
		v0 = v1;
	}
	
	cpFloat dist = (outside ? minDist : -minDist);
	cpVect g = cpvmult(cpvsub(p, closestPoint), 1.0f/dist);
	
	info->shape = (cpShape *)poly;
	info->p = cpvadd(closestPoint, cpvmult(g, r));
	info->d = dist - r;
	
	// Use the normal of the closest segment if the distance is small.
	info->g = (minDist > MAGIC_EPSILON ? g : closestNormal);
}
static void
cpPolyShapePointQuery(cpPolyShape *poly, cpVect p, cpPointQueryInfo *info){
	int count = poly->count;
	struct cpSplittingPlane *planes = poly->planes;
	cpFloat r = poly->r;
	
	cpVect v0 = planes[count - 1].v0;
	cpFloat minDist = INFINITY;
	cpVect closestPoint = cpvzero;
	cpVect closestNormal = cpvzero;
	cpBool outside = cpFalse;
	
	for(int i=0; i<count; i++){
		cpVect v1 = planes[i].v0;
		outside = outside || (cpvdot(planes[i].n, cpvsub(p,v1)) > 0.0f);
		
		cpVect closest = cpClosetPointOnSegment(p, v0, v1);
		
		cpFloat dist = cpvdist(p, closest);
		if(dist < minDist){
			minDist = dist;
			closestPoint = closest;
			closestNormal = planes[i].n;
		}
		
		v0 = v1;
	}
	
	cpFloat dist = (outside ? minDist : -minDist);
	cpVect g = cpvmult(cpvsub(p, closestPoint), 1.0f/dist);
	
	info->shape = (cpShape *)poly;
	info->point = cpvadd(closestPoint, cpvmult(g, r));
	info->distance = dist - r;
	
	// Use the normal of the closest segment if the distance is small.
	info->gradient = (minDist > MAGIC_EPSILON ? g : closestNormal);
}