Example #1
0
static int
circle2segment(const cpCircleShape *circleShape, const cpSegmentShape *segmentShape, cpContact *con)
{
	cpVect seg_a = segmentShape->ta;
	cpVect seg_b = segmentShape->tb;
	cpVect center = circleShape->tc;
	
	cpVect seg_delta = cpvsub(seg_b, seg_a);
	cpFloat closest_t = cpfclamp01(cpvdot(seg_delta, cpvsub(center, seg_a))/cpvlengthsq(seg_delta));
	cpVect closest = cpvadd(seg_a, cpvmult(seg_delta, closest_t));
	
	if(circle2circleQuery(center, closest, circleShape->r, segmentShape->r, con)){
		cpVect n = con[0].n;
		
		// Reject endcap collisions if tangents are provided.
		if(
			(closest_t == 0.0f && cpvdot(n, segmentShape->a_tangent) < 0.0) ||
			(closest_t == 1.0f && cpvdot(n, segmentShape->b_tangent) < 0.0)
		) return 0;
		
		return 1;
	} else {
		return 0;
	}
}
Example #2
0
static void
cpSegmentShapePointQuery(cpSegmentShape *seg, cpVect p, cpPointQueryExtendedInfo *info){
	if(!cpBBContainsVect(seg->shape.bb, p)) return;
	
	cpVect a = seg->ta;
	cpVect b = seg->tb;
	
	cpVect seg_delta = cpvsub(b, a);
	cpFloat closest_t = cpfclamp01(cpvdot(seg_delta, cpvsub(p, a))/cpvlengthsq(seg_delta));
	cpVect closest = cpvadd(a, cpvmult(seg_delta, closest_t));
	
	cpVect delta = cpvsub(p, closest);
	cpFloat distsq = cpvlengthsq(delta);
	cpFloat r = seg->r;
	
	if(distsq < r*r){
		info->shape = (cpShape *)seg;
		
		cpFloat dist = cpfsqrt(distsq);
		info->d = r - dist;
		info->n = cpvmult(delta, 1.0/dist);
	}

}