public static bool ArcCircleCollides(Vector2F arcCenter, Vector2F arcDirection, float arcRadius, float arcLength, Circle circle) { Vector2F arcDelta = arcDirection - arcCenter; Vector2F circleDelta = circle.Center - arcCenter; if (arcDelta == circleDelta) return true; if (arcDelta.Angle(circleDelta) < arcLength / 2f) return Vector2F.Distance(arcCenter, circle.Center) <= arcRadius + circle.Radius; else return false; }
public static bool MovingCircleCollides(Circle mover, Vector2F velocity, Circle target) { Vector2F closest = ClosestPointOnLineSegment(target.Center, mover.Center, mover.Center + velocity); float distanceSq = (float)(Math.Pow(closest.X - target.Center.X, 2) + Math.Pow(closest.Y - target.Center.Y, 2)); return distanceSq <= (float)Math.Pow(mover.Radius + target.Radius, 2); }
private void _CheckCollisions() { if (OnCollision == null) return; // check if we collided with anything since last update float radius = this.ActorData.Cylinder.Ax2; Circle startCircle = new Circle(_prevUpdatePosition.X, _prevUpdatePosition.Y, radius); // make a velocity representing the change to the current position Vector2F velocity = PowerMath.VectorWithoutZ(this.Position - _prevUpdatePosition); Actor hit = null; TargetList targets = this.Context.GetEnemiesInRadius(this.Position, radius + 25f); if (CollisionFilter != null) targets.Actors.RemoveAll(actor => !CollisionFilter(actor)); targets.SortByDistanceFrom(_prevUpdatePosition); foreach (Actor target in targets.Actors) { float targetRadius = 1.5f; // TODO: use target.ActorData.Cylinder.Ax2 ? if (PowerMath.MovingCircleCollides(startCircle, velocity, new Circle(target.Position.X, target.Position.Y, targetRadius))) { hit = target; break; } } if (hit != null) OnCollision(hit); }
public static bool CircleInBeam(Circle circle, Vector3D beamStart, Vector3D beamEnd, float beamThickness) { // NOTE: right now this does everything in 2d, ignoring Z // offset start beam position by beam thickness beamStart = TranslateDirection2D(beamStart, beamEnd, beamStart, beamThickness); return MovingCircleCollides(new Circle(beamStart.X, beamStart.Y, beamThickness), VectorWithoutZ(beamEnd - beamStart), circle); }
private void _CheckCollisions() { if (OnCollision == null) return; // check if we collided with anything since last update float radius = this.ActorData.Cylinder.Ax2; Circle startCircle = new Circle(_prevUpdatePosition.X, _prevUpdatePosition.Y, radius); // make a velocity representing the change to the current position Vector2F velocity = PowerMath.VectorWithoutZ(this.Position - _prevUpdatePosition); Actor hit = null; foreach (Actor target in this.Context.GetEnemiesInRadius(this.Position, radius + 25f) .OrderBy(t => PowerMath.Distance2D(_prevUpdatePosition, t.Position))) { float targetRadius = 1.5f; // target.ActorData.Cylinder.Ax2; if (PowerMath.MovingCircleCollides(startCircle, velocity, new Circle(target.Position.X, target.Position.Y, targetRadius))) { hit = target; break; } } if (hit != null) OnCollision(hit); }