Or, to stop at a fixed distance away from the object, modify like so:
def moveTowardsOrbit(mover, target, maxStep, stopDistance):
deltaX = target.x - mover.x
deltaY = target.y - mover.y
distance = sqrt(deltaX * deltaX + deltaY * deltaY)
unitScale = 1 / distance
deltaX *= unitScale
deltaY *= unitScale
onCircleX = target.x - deltaX * stopDistance
onCircleY = target.y - deltaY * stopDistance
fromStop = distance - stopDistance
if abs(fromStop) <= maxStep:
mover.x = onCircle.x
mover.y = onCircle.y
else:
if fromStop < 0:
deltaX *= -1
deltaY *= -1
mover.x += deltaX * maxStep
mover.y += deltaY * maxStep
Call this with moveTowards(obj, anchor, speed * dt, 10)
.
Picks a point on the circle
stopDistance
away from theanchor
and moves toward that - whether that takes it inward or outward along the line joiningobj
andanchor
.Moves the object at most a distance of
maxStep
toward the targetper invocation.When the targetdestination is closer than
maxStep
, it snaps the object directly to the targetstopDistance
circle, with no under- or over-shooting.Uses no trigonometric functions, and no transcendentals at all when within one step of the target. It also handles all angles correctly, unlike the sample code (hint: you probably want
atan2
when trying to find an angle from two coordinates).