public RayCollisionInfo getRayCollisionInfo(Vector rayStart, Vector rayDir) { VectorSet set = calculateTrans(); Vector? pClosest = null; Edge eClosest = null; if (rayDir.Length > 0) { float distance = float.MaxValue; set.forEachEdge(edge => { float x = rayStart.X * edge.Unit.Y - rayStart.Y * edge.Unit.X - edge.V1.X * edge.Unit.Y + edge.V1.Y * edge.Unit.X; x /= rayDir.Y * edge.Unit.X - rayDir.X * edge.Unit.Y; float y = rayStart.X * rayDir.Y - rayStart.Y * rayDir.X + rayDir.X * edge.V1.Y - rayDir.Y * edge.V1.X; y /= rayDir.Y * edge.Unit.X - rayDir.X * edge.Unit.Y; if (x > 0 && y > 0 && y < edge.Length) { Vector p = edge.V1 + y * edge.Unit; float testDistance = (p - rayStart).Length; if (testDistance < distance) { distance = testDistance; pClosest = p; eClosest = edge; } } }); } if (pClosest.HasValue) { return(new RayCollisionInfo(rayStart, rayDir, eClosest.Normal, pClosest.Value)); } else { return(null); } }
/// <summary> /// Run an SAT test against the other convex object /// </summary> /// <param name="conv"></param> /// <returns></returns> public CollisionInfo getCollisionInfo(Convex conv) { List <Vector> axisSet = new List <Vector>(); VectorSet aSet = calculateTrans(); VectorSet bSet = conv.calculateTrans(); Vector mtv = Vector.One * 10000; bool colliding = true; aSet.forEachEdge(e => axisSet.Add(e.Normal)); bSet.forEachEdge(e => axisSet.Add(e.Normal)); foreach (Vector a in axisSet) { //create the axis Vector axis = a.Unit; float aMin = float.MaxValue, aMax = float.MinValue; float bMin = float.MaxValue, bMax = float.MinValue; //project conv, a, onto axis aSet.forEachVector(v => { float p = (v).dot(axis); if (p < aMin) { aMin = p; } if (p > aMax) { aMax = p; } }); //project conv, b, onto axis bSet.forEachVector(v => { float p = (v).dot(axis); if (p < bMin) { bMin = p; } if (p > bMax) { bMax = p; } }); //are a and b overlapping? if ((aMin > bMin && aMin < bMax) || (aMax > bMin && aMax < bMax) || (bMin > aMin && bMin < aMax) || (bMax > aMin && bMax < aMax) ) { //they are overlapping //calculate overlap vector float overlap = Math.Min(aMax, bMax) - Math.Max(aMin, bMin); if (aMax < bMax) { overlap *= -1; } if (Math.Abs(overlap) < mtv.Length) { mtv = axis * overlap; } } else { //they are not overlapping. no collision can be occuring. colliding = false; break; } } CollisionInfo collInfo = new CollisionInfo(mtv); if (!colliding) { return(null); } else { return(collInfo); } }