Python movement of hands on analogue clock - python-2.7

I am trying to draw a clock face in which the second hand moves as the time changes.
I am using the following to calculate the points on my circle:
def points_on_circle():
global time, radius, centre, x, y
theta = time% math.pi * 2
c = math.cos(theta)
s = math.sin(theta)
x= centre[0] + radius * c
y =centre[1] + radius * s
return x,y
my timer 'ticks' every tenth second, the radius of my circle is 50, the centre is at (150,150) which is also the origin of my hand, the other end of the hand being (x,y) as calculated above. How do I calculate , I assume by multiplying time by some constant, how fast the x,y should change for this circle ( but for any circle) .
I am using CodeSkulptor from Coursera to try to do this ( the original assignment created a digital timer which I am done. This is not part of the homework ( yet??)

The hand rotates 2 Pi radians every 60 seconds. Assuming you're syncing with real time, time.time() will return the current time in seconds (and milliseconds which I suggest you ignore). If you take the time and first do numseconds = int(time.time()) % 60, you now need to translate that, which is a simple as numseconds * 2 * pi / 60. (Example: numseconds = 0, theta = 0, numseconds = 15, theta = pi /2 (90 degrees).
You will also need to play with your equations as normally theta=0 implies the line is horizontal pointing right (which would be numseconds = 15) and theta=Pi implies the line is vertical pointing up (which would be numseconds = 0)

Related

Projectile Motion in 3D: Calculating Time of Collision

I'm writing a function that takes in an object with a trajectory (including starting position, starting velocity, and acceleration, all represented as Vector3s) in 3D space and if it hits another object, returns the point of collision and time of the collision. I'm using kinematic equations with a timestep to detect possible collisions and I can get the point of collision that way, but once I have that I want to find the exact time that that collision would occur at.I thought of rearranging a kinematic equation to solve for time and plug in what I already had, but I can't figure out how I can use all three axes of motion to do this, since my other values are Vec3's and time is just scalar. I've thought about just doing the calculation on one axis, but I'm not sure if that would lead to an accurate result.
Would it be accurate to calculate just based on one axis, or is there a way to incorporate all three into the calculation? The formula I'm using to solve for time is:
t = (v_init +/- Sqrt((v_init)^2 - (accel * disp * 4 * .5)))/accel;
Where v_init is initial velocity, disp is total displacement, and accel is acceleration. I'm basing this off of the kinematic equation:
d = v*t + .5*a*t^2
Let me write in the general case. The component-wise motion law is
x(t) = x0 + v_x t + 0.5 a_x t^2
y(t) = y0 + v_y t + 0.5 a_y t^2
z(t) = z0 + v_z t + 0.5 a_z t^2
where (x0,y0,z0)^t is the initial position, (v_x, v_y, v_z)^t is the initial velocity vector, and (a_x, a_y, a_z)^t is the vector of acceleration. The 3rd component of the latter may include also the gravity acceleration.
I assume that the collision plane is horizontal, having thus equation z = k. Solve in t the equation
z(t) = k
for finding the time t_c in which the projectile hits the plane. Compute then the collision coordinates x(t_c) and y(t_c) using the above formula by substituting t with t_c.
If the plane has the general equation
a x + b y +c z + d = 0
I suggest to put the frame of reference on the plane, having the xy plane on the collision plane, and then apply the above procedure.
You may also solve the non linear system
x = x0 + v_x t + 0.5 a_x t^2
y = y0 + v_y t + 0.5 a_y t^2
z = z0 + v_z t + 0.5 a_z t^2
a x + b y +c z + d = 0
taking the solution for t>0 (I dropped the dependency on t for x, y and z).
To solve it in C++, you may search a math library, such as Eigen which has a module for non linear systems.

Find a longitude given a pair of (lat,long) and an offset latitude

In a geodetic coordinate system (wgs84), i have a pair of (latitude,longitude) say (45,50) and (60,20). Also i am said that a new pair of latitude,longitude lies along the line joining these two and at an offset of say 0.1 deg lat from (45,50) i.e. (45.1, x). How do i find this new point? What i tried was to apply the straight line equation
y = mx+c
m = (lat1 - lat2)/ long1-long2)
c = lat1 - m * long1
but that seemed to give wrong results.
Your problem is the calculation of m. You have turned it around!
The normal formula is:
a = (y1 - y2) / (x1 - x2)
so in your case it is:
m = (long2 -long1) / (lat1 - lat2)
so you'll get m = -2
And you also turned the calculation of c around.
Normal is:
b = y1 - a * x1
so you should do:
c = long1 - m * lat1
So you'll get c = 140.
The formula is:
long = -2 * lat + 140
Another way to think about it is given below. The result is the same, of cause.
The surface-line between two coordinates is not a straight line. It is a line drawn on the surface of a round object, i.e. earth. It will be a circle around the earth.
However all coordinates on that line will still go through a straight line.
That is because the coordinate represents the angles of a vector from center of earth to the point you are looking at. The two angles are compared to Equator (latitude) and compared to Greenwich (longitude).
So you need to setup a formula describing all coordinates for that line.
In your case the latitude goes from 45 to 60, i.e. increases by 15.
Your longitude goes from 50 to 20, i.e. decreses by 30.
So your formula will be:
(lat(t), long(t)) = (45, 50) + (15*t, -30*t) for t in [0:1]
Now you can calculate the value of t that will hit (45.1, x) and afterwards you can calculate x.
The equations you use describe a straight line in an 2D cartesian coordinate system.
Longitude and latitude describe a point in a spherical coordinate system.
A spherical coordinate system is not cartesian.
A similar question was answered here.

Variable increasing in value rather than decreasing

I am working on some simulation software, in which I have an entity that is spiraling around a particular point.
As the entity starts spiraling around the point, and the radius of the spiral continues to grow, I want to display the number of circuits that the entity has completed to the user (completion of a circuit is defined as the location/ time at which the entity reaches the same angle from the origin that it was at when it started spiralling).
I also want to display to the user, the distance from the aircraft's current location to the point at which it will complete the current circuit.
I am doing this using the following section of code:
if (m_OVF_TURN_DIR == TURN_LEFT)
{
arcAngle = 360 - (NormalAngle360(NormalAngle360(ldFAZ_CentrePos_AC) + NormalAngle360(m_circuitStartAngle)));
m_SteerData.DistanceToGo = (arcAngle * PI * m_currentRadius);
}
else
{
arcAngle = 360 - (NormalAngle360(NormalAngle360(m_circuitStartAngle) + NormalAngle360(ldFAZ_CentrePos_AC)));
m_SteerData.DistanceToGo = ((arcAngle * PI * m_currentRadius) / 180.0); // Nm
}
In this code, the lines:
m_SteerData.DistanceToGo = (arcAngle * PI * m_currentRadius);
and
m_SteerData.DistanceToGo = ((arcAngle * PI * m_currentRadius) / 180.0);
are what is calculating the distance from the aircraft's current location to the point at which it will complete a circuit.
The first block is used to calculate the distance when the entity is spiraling in an anti-clockwise direction, and the second block is used when the entity is spiraling in a clockwise direction.
The clockwise direction seems to be working correctly- it displays a number for the distance to go, and this number decreases steadily as the entity follows the path of the spiral. However, the anti-clockwise direction seems to start at a random number, and then increase steadily as the entity follows the path of the spiral... rather than decrease as it should (because the entity is moving closer to the point at which the circuit will be completed).
This suggests to me that I am using an incorrect symbol somewhere in this block (+, -, * or /), but I can't seem to figure out where... Can anyone point me in the right direction?
The function NormalAngle360() is defined with:
double NormalAngle360(const double aInAngle)
{
//## Operation [c0b17aaa-bda1-4164-8ba7-5f960c924a32]
double ldAngle = NormalAngle(aInAngle);
if (ldAngle < 0.0)
ldAngle += 360.0;
return ldAngle;
//## Operation End
}
Since you normalize the angle such that it lies between 0 and 360, there should only be two possibilities. Either the angle starts at some value and decreases to 0, in which case
m_SteerData.DistanceToGo = (arcAngle/180 * PI * m_currentRadius);
should work, or the angle starts at some value and increases up to 360, in which case
m_SteerData.DistanceToGo = ((360 - arcAngle)/180 * PI * m_currentRadius);
should work.
It's possible that you can use the first version for both cases.
If both versions don't work, I think the angle is not what it should be. Maybe you could output the values of arcAngle to check that.
The lines in your if...else branches both do the same thing:
arcAngle = 360 - (NormalAngle360(NormalAngle360(ldFAZ_CentrePos_AC) + NormalAngle360(m_circuitStartAngle)));
arcAngle = 360 - (NormalAngle360(NormalAngle360(m_circuitStartAngle) + NormalAngle360(ldFAZ_CentrePos_AC)));
because 360 - (a+b) is the same as 360 - (b+a). You'll need to rethink this logic.
Also you do not need the two inner calls to NormalAngle360, the line could be written as:
arcAngle = 360 - NormalAngle360( ldLAZ_CentrePos_AC + m_circuitStartAngle );
Perhaps what you're looking for is just changing + to - here; and/or taking out the 360 -.
Also, the NormalAngle360 function should check if the angle >= 360.0 and subtract 360 from it.
I found the issue- the problem was that I had missed out a - sign from the function being called in the if clause of the statement:
if (m_OVF_TURN_DIR == TURN_LEFT)
{
arcAngle = 360 - fabs((NormalAngle360(-NormalAngle360(ldFAZ_CentrePos_AC) + NormalAngle360(m_circuitStartAngle))));
m_SteerData.DistanceToGo = (arcAngle/180 * PI * m_currentRadius);
}
Using `-NormalAngle360(...) in the innermost bracket here resolved the issue that I was having.

OpenGL - Creating a circle, change radius?

I must be the worst person on the planet when it comes to math because i can't figure out how to change this circle radius:
from math import *
posx, posy = 0,0
sides = 32
glBegin(GL_POLYGON)
for i in range(100):
cosine=cos(i*2*pi/sides)+posx
sine=sin(i*2*pi/sides)+posy
glVertex2f(cosine,sine)
I'm not entirely sure how or why this becomes a circle because the *2 confuses me a bit.
Note that this is done in Pyglet under Python2.6 calling OpenGL libraries.
Followed Example 4-1: http://fly.cc.fer.hr/~unreal/theredbook/chapter04.html
Clarification: This works, i'm interested in why and how to modify the radius.
This should do the trick :)
from math import *
posx, posy = 0,0
sides = 32
radius = 1
glBegin(GL_POLYGON)
for i in range(100):
cosine= radius * cos(i*2*pi/sides) + posx
sine = radius * sin(i*2*pi/sides) + posy
glVertex2f(cosine,sine)
But I would pick another names for variables. cosine and sine is not exactly what these variables are.
And as far as I see, you son't need a loop from 1 to 100 (or from 0 to 99, I'm not too good at Python), you just need a loop from 1 to sides.
Explanation:
When you calculate
x = cos (angle)
y = sin(angle)
you get a point on a circle with radius = 1, and centre in the point (0; 0) (because sin^2(angle) + cos^2(angle) = 1).
If you want to change a radius to R, you simply multiply cos and sin by R.
x = R * cos (angle)
y = R * sin(angle)
If you want to transfer the circle to another location (for example, you want the circle to have it's centre at (X_centre, Y_centre), you add X_centre and Y_xentre to x and y accordingly:
x = R * cos (angle) + X_centre
y = R * sin(angle) + Y_centre
When you need to loop through N points (in your case N = sides) on your circle, you should change the angle on each iteration. All those angles should be equal and their sum should be 2 * pi. So each angle should be equal to 2 * pi/ N. And to get i-th angle you multiply this value by i: i * 2 * pi / N.
math : P=pr^2=p*r*r= p*r*2 programming i*2*pi/sides
together : i = p i*2, *2=r^2 this should help you

Two points rotating around same center but distance grows

I want to achieve that two points are rotating around each other. I therefore use a rotation matrix. However I now get the problem that the distance between the points is growing (see atached video 1). The distance however should stay constant over my whole simulation.
Here is my code I use for calculating the speed:
Where p1 and p2 are the two points.
double xPos = p0.x+p1.x;
double yPos = p0.y+p1.y;
//The center between p1 and p2
xPos /=2;
yPos /=2;
//the rotating angle
double omega = 0.1;
//calculate the new positions
double x0new = xPos + (p0.x-xPos)*std::cos(omega) - (p0.y-yPos)*std::sin(omega);
double y0new = yPos + (p0.x-xPos)*std::sin(omega) + (p0.y-yPos)*std::cos(omega);
double x1new = xPos + (p1.x-xPos)*std::cos(omega) - (p1.y-yPos)*std::sin(omega);
double y1new = yPos + (p1.x-xPos)*std::sin(omega) + (p1.y-yPos)*std::cos(omega);
//the speed is exatly the difference as I integrate one timestep
p0.setSpeed(p0.x-x0new, p0.y-y0new);
p1.setSpeed(p1.x-x1new, p1.y-y1new);
I then integrate the speed exactly one timestep. What is wrong in my calculation?
Update
It seems that my integration is wrong. If I set the positions direct it works perfect. However I do not now what is wrong with this integration:
setSpeed(ux,uy){
ux_=ux;
uy_=uy;
}
// integrate one timestep t = 1
move(){
x = x + ux_;
y = y + uy_;
}
Video of my behaviour
There's nothing clearly wrong in this code, but the "speed" integration that isn't shown, suggests that you might be integrating linearly between old and new position, which would make the orbits expand when speed > nominal speed and to contract when speed < nominal_speed.
As I suspected. The integration is actually extrapolation at the line segment between point p0 and p1 which are supposed to be at a fixed distance from origin (a physical simulation would probably make the trajectory elliptical...)
Thus if the extrapolation factor would be 0, the new position would be on the calculated perimeter. If it was < 0 (and > -1), you'd be interpolating inside the expected trajectory.
O This beautiful ascii art is trying to illustrate the integration
/ x is the original position, o is the new one and O is the
/ ___----- "integrated" value and the arc is a perfect circle :)
o-- Only at the calculated position o, there is no expansion.
--/
/ /
/ /
| /
x
At the first glance, the main reason is that you update p0 and p1 coordinates in the each iteration. That would accumulate inaccuracies, which are possibly coming from setSpeed.
Instead, you should use the constant initial coordinates p0 and p1, but increase omega angle.