2017-02-11 128 views
2

问题:以鼠标输入为圆心,沿圆形路径移动一个点作为指导。通过鼠标移动沿圆形路径移动一个点(python/pygame)

有大量的解决方案的在线用于移动点沿圆形路径,即使用中央+ math.sin || COS(角度)*半径方程和递增的角度。但是,这不适用于鼠标输入。即使只是原始x/y值的一小部分,并转换为弧度,“圆”的半径也不会变化,路径点与鼠标位置之间的关系变得异常。

我暗示的是,该路径点(在圆的圆周上点)需要被限制为从原点一定距离(强迫半径)。我也感觉到,要么y需要是x或x的函数才能成为y的函数。

我已经走了下来使用的距离公式来检查圆的中心,距离路径点的距离之路。这个想法是然后将x和y值“反弹”到允许的距离 - 真正的距离,但是......不起作用。这是因为两点之间的距离和两点之间的差异(我如何开始了解它是两点之间的差异产生矢量?)。无论如何,我确信有一个更直接的解决方案。

rotating arm guided by a mouse (让我们...假装旋转臂的中心,为说明起见)

回答

0

不需要三角函数。 通过计算到中心的距离,您已经走上了一条很好的道路。 想象一下从圆心到鼠标位置的矢量。 点现在必须某处位于相同的方向作为 这种载体,这意味着我们可以计算出其位置 用简单scalar multiplication。剩下的唯一事情是 计算标量,这是鼠标的距离与圆的半径的比例 :

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() 
+0

感谢@马克!三角函数提出了一个零分割错误。通过在圆的中心周围设置一个屏障,将鼠标和鼠标的所有值都设置为1,可能可以解决此问题。我还遇到了敏感性 - 当我移动鼠标时,终点会围绕该圆圈飞行。我想知道是否没有办法在方程中引入角速度来弥补这一点。 @Meyer,这太棒了!矢量元组里面的元素叫什么? (如果有名称) –

+0

另外,不是直接在主题上,但我注意到CENTER [0] +矢量[0] *标量具有与中心+ cos(theta)*半径相同的形式。好奇。 –

+0

我知道元素为矢量坐标或矢量元素。 至于零除,我尴尬地忘记了, 并相应地修复了代码。请注意,'satelliteCenter'现在只在距离不为零时更新。是的,与矢量之间角度的余弦关系密切, 参见[矢量投影](https://en.wikipedia.org/wiki/Vector_projection)上的维基百科条目。 – Meyer

0

您可以使用x,圆y原点和X,Y位置的鼠标计算鼠标和圆之间的角度:tan((y_mouse-y_circle)/(x_mouse-x_circle))那么点的位置将是(x_circle + r * cos(angle), y_circle + r * sin(angle))