Search code examples
pythonpython-3.xtrigonometry

Calculating the new center of a rectangle using trigonometry


I am currently having trouble with an assignment, and I've been trying to pinpoint my error for hours.

I have a circle and a rectangle (both drawn by user clicks). As shown here:

Using the center point of the rectangle, I want to calculate a new center point (for the rectangle) that lies on the circle. I achieve this by calculating the angle (theta) and using trigonometry to get the new centerpoint.

However, when I run my program I am not getting the correct results. Shown here:

I've checked a hundred times, and I can't seem to pinpoint where I messed up. I've checked theta, and the resulting degrees is correct. Here is the relevant code, where I suspect I made an error:

theta = math.atan((initialrec_y-click1.y)/(initialrec_x-click1.x))
theta = int(math.degrees(theta))

rec_x = click1.x + radius*math.cos(theta)
rec_y = click1.y + radius*math.sin(theta)

Here is the full code if you would like to run it:

from graphics import *
import math

def main():

#setup window
win = GraphWin("Traveling Rectangle",600,450)
win.setCoords(0,0,600,450)

click1 = win.getMouse()
click2 = win.getMouse()
radius = click2.x - click1.x
circle = Circle(click1, radius)
circle.draw(win)

click3 = win.getMouse()
click4 = win.getMouse()
rect = Rectangle(click3, click4)
rect.draw(win)
rect.setFill("red")
rect.setOutline("red")

#the centerpoint of the initial rectangle
initialrec_x = (click3.x + click4.x) / 2
initialrec_y = (click3.y + click4.y) / 2

#the trig to calculate the point on the circle
theta = math.atan((initialrec_y-click1.y)/(initialrec_x-click1.x))
theta = int(math.degrees(theta))

#the new centerpoint values of x and y
rec_x = click1.x + radius*math.cos(theta)
rec_y = click1.y + radius*math.sin(theta)

main()

The graphics library can be found here: https://mcsp.wartburg.edu/zelle/python/graphics.py


Solution

  • I am using a different graphics package, but the following works for me:

    ...
    initialrec_y = (click3.y + click4.y) / 2
    
    theta = math.atan2(initialrec_y - click1.y, initialrec_x - click1.x)
    rec_x = click1.x + radius * math.cos(theta)
    rec_y = click1.y + radius * math.sin(theta)
    

    This uses the atan2 function, which takes note of the signs on the y and x inputs to correctly calculate the quadrant the point is in and return an angle accordingly. Other than that, the only difference from your code is that there is no conversion from radians (which atan2 returns) to degrees. sin and cos want radians.