|
4 | 4 |
|
5 | 5 | In pygame, +y is down. Python's arctangent functions expect +y to be up.
|
6 | 6 | This wreaks havoc with the unit circle if you want to find the angle between
|
7 |
| -two points (for, say, collision detection or aiming a gun). |
| 7 | +two points (for, say, collision detection or aiming a gun). You can avoid the |
| 8 | +problem entirely by calling atan2(-y, x) and adding 2*pi to the result if it's |
| 9 | +negative. |
8 | 10 |
|
9 | 11 | Note that math.atan2(numerator, denominator) does the division for you.
|
10 | 12 |
|
11 |
| -This applet demonstrates the confusing result. The range of the arctangent |
12 |
| -(-pi, pi], which is mathematically accurate but hard to work with. Much worse |
13 |
| -is that the direction of increasing angular measure is reversed! |
14 |
| -
|
15 |
| -You can avoid the problem entirely by calling atan2(-y, x) and adding 2*pi to |
16 |
| -the result if it's negative. |
17 |
| -
|
18 | 13 | Controls: move the mouse near the axes.
|
19 | 14 |
|
20 | 15 | """
|
21 | 16 |
|
22 | 17 | import pygame, sys, os
|
23 | 18 | from pygame.locals import *
|
24 | 19 | from math import atan2, degrees, pi
|
25 |
| -halfpi = pi/2.0 |
26 | 20 |
|
27 | 21 | def quit():
|
28 | 22 | pygame.quit()
|
@@ -67,35 +61,36 @@ def quit():
|
67 | 61 | if 0 < event.pos[0] < 400 and 0 < event.pos[1] < 400:
|
68 | 62 | pos = event.pos
|
69 | 63 |
|
70 |
| - x = pos[0] - origin[0] |
71 |
| - y = pos[1] - origin[1] |
72 |
| - theta = atan2(y,x) |
| 64 | + #Angle logic |
| 65 | + dx = pos[0] - origin[0] |
| 66 | + dy = pos[1] - origin[1] |
| 67 | + rads = atan2(-dy,dx) |
| 68 | + rads %= 2*pi |
| 69 | + degs = degrees(rads) |
73 | 70 |
|
74 | 71 | screen.fill(white)
|
75 | 72 |
|
| 73 | + #Draw coordinate axes and labels |
76 | 74 | pygame.draw.circle(screen, black, origin, 5)
|
77 | 75 | pygame.draw.line(screen, black, (0, 440), (440, 440), 3)
|
78 | 76 | pygame.draw.line(screen, black, (200, 15), (200, 380))
|
79 |
| - screen.blit(font.render("-pi/2", True, black), (180,10)) |
80 |
| - screen.blit(font.render( "pi/2", True, black), (187, 380)) |
81 |
| - pygame.draw.line(screen, black, (10, 200), (355, 200)) |
82 |
| - screen.blit(font.render("-pi", True, black), (5, 180)) |
83 |
| - screen.blit(font.render( "pi", True, black), (12, 200)) |
| 77 | + screen.blit(font.render( "pi/2", True, black), (178, 10)) |
| 78 | + screen.blit(font.render("3pi/2", True, black), (175, 380)) |
| 79 | + pygame.draw.line(screen, black, (28, 200), (355, 200)) |
| 80 | + screen.blit(font.render("pi", True, black), (8, 190)) |
84 | 81 | screen.blit(font.render("0", True, black), (360, 190))
|
85 | 82 |
|
| 83 | + #Draw lines to cursor |
86 | 84 | pygame.draw.line(screen, blue, origin, (pos[0], origin[1]), 2)
|
87 | 85 | pygame.draw.line(screen, red, (pos[0], origin[1]), (pos[0], pos[1]), 2)
|
88 | 86 | pygame.draw.line(screen, purple, origin, pos, 2)
|
89 |
| - if theta < 0: |
90 |
| - pygame.draw.arc(screen, green, arcRect, 0, -theta, 4) |
91 |
| - else: |
92 |
| - pygame.draw.arc(screen, green, arcRect, -theta, 0, 4) |
93 |
| - |
94 |
| - screen.blit(font.render(str(x)+" x", True, blue), (10, 450)) |
95 |
| - screen.blit(font.render(str(y)+" y", True, red), (100, 450)) |
96 |
| - screen.blit(font.render(str((x**2 + y**2)**.5)+" d", True, purple), (10, 480)) |
97 |
| - screen.blit(font.render("arctangent(y/x) =", True, black), (10, 510)) |
98 |
| - screen.blit(font.render(str(degrees(theta))+" deg", True, green), (30, 540)) |
99 |
| - screen.blit(font.render(str(theta/pi)+"*pi rad", True, green), (30, 570)) |
| 87 | + pygame.draw.arc(screen, green, arcRect, 0, rads, 4) |
| 88 | + #Note that the function expects angles in radians |
| 89 | + |
| 90 | + #Draw numeric readings |
| 91 | + screen.blit(font.render(str(dx)+" x", True, blue), (10, 450)) |
| 92 | + screen.blit(font.render(str(dy)+" y", True, red), (100, 450)) |
| 93 | + screen.blit(font.render(str((dx**2 + dy**2)**.5)+" d", True, purple), (10, 480)) |
| 94 | + screen.blit(font.render(str(degs)+" degrees", True, green), (10, 510)) |
100 | 95 |
|
101 | 96 | pygame.display.flip()
|
0 commit comments