Khari Thompson
Khari Thompson

Reputation: 99

moving a point along a circular path via mouse motion (python/pygame)

The problem: move a point along a circular path with mouse input as a guide.

There are plenty of solutions online for moving a point along a circular path, namely using the center + math.sin||cos(angle) * radius equation and incrementing the angle. This doesn't work with mouse input, however; even at a fraction of the original x/y value and converted to radians your "circle" has no constant radius and the path point moves in a strange relationship to the mouse's position.

My inkling is that the path point (point on the circumference of the circle) needs to be restricted to a certain distance from the origin (an enforced radius). I also get the feeling that either y needs to be a function of x or x needs to be a function of y.

I've gone down the road of using the distance formula to check the distance from the path point to the center of the circle. The idea was to then "snap" the x and y values back by the allowed distance - true distance but that...didn't work. Namely because there's a difference between the distance between two points and the difference between two points (how I'm beginning to understand it is that the difference between two points yields a vector?). At any rate, I'm sure there's a more straightforward solution.

rotating arm guided by a mouse (let's...pretend the rotating arm is centered, for the sake of the illustration)

Upvotes: 2

Views: 1821

Answers (2)

Meyer
Meyer

Reputation: 1712

There is no need for trigonometric functions. You were on a good path by calculating the distance to the center. Imagine a vector from circle center to mouse position. The point now has to lie somewhere in the same direction as this vector, which means we can calculate its position with a simple scalar multiplication. The only thing that remains is to calculate the scalar, which is the proportion between mouse distance and circle radius:

from __future__ import division # For Python 2.7
import pygame

pygame.init()
screen = pygame.display.set_mode((400, 400))

CENTER = (200, 200)
RADIUS = 100

satelliteCenter = (CENTER[0]+RADIUS, CENTER[1])

running = True
while running:
  for event in pygame.event.get():
    if event.type == pygame.QUIT: running = False

  mouse = pygame.mouse.get_pos()
  vector = (mouse[0]-CENTER[0], mouse[1]-CENTER[1])
  distance = (vector[0]**2 + vector[1]**2)**0.5

  if distance > 0:
    scalar = RADIUS / distance
    satelliteCenter = (
      int(round( CENTER[0] + vector[0]*scalar )),
      int(round( CENTER[1] + vector[1]*scalar )) )

  screen.fill((152,206,231))
  pygame.draw.circle(screen, (71,153,192), CENTER, RADIUS)
  pygame.draw.circle(screen, (243,79,79), satelliteCenter, 16)
  pygame.display.update()

Upvotes: 2

Mark Omo
Mark Omo

Reputation: 990

You can use the x, y origin of the circle, and the x, y position of the mouse to calculate the angle between the mouse and the circle using: tan((y_mouse-y_circle)/(x_mouse-x_circle)) then the position of the point would be (x_circle + r * cos(angle), y_circle + r * sin(angle))

Upvotes: 0

Related Questions