|
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