I am working on a game and I am writing an Entity base class. Since many of the entities will behave like particles(2D) I want to use a normal instead of a rotation in degrees. However since I am using OpenGL I need to have the degree of the normal to rotate. What is the fastest way to convert from the normal to degrees and vice versa. I know that I can use trigonometric functions such as atan2 sin cos etc, but I am pretty sure there is a faster method. Any help or direction would be appreciated.
If you're constrained to two dimensions and you're trying to convert a directional vector (x, y) to degrees from the x-axis, then atan2(y, x) is almost definitely going to be your fastest method, unless you're constraining the possible values of x and y to some pretty trivial cases. To get the degrees from the y-axis, just use atan2(x, y), of course. This angle will be in radians. Multiply by 180/pi to convert to degrees. This should require a trivial amount of time.
The figure you're drawing suggests that atan2(x, y) * 180 / Math.PI will give you the results you desire.
Don't be concerned with speed unless you've profiled your code and have determined that there is a bottleneck in this calculation (which is unlikely).
Related
I'm developing a very simple physical engine.
I have to calculate the final speed of a circle in an elastic collision against another circle. Each circle has a specific mass, radius and speed.
In order to calculate x and y speed I solve a system with conservation on momentum and conservation of kinetic energy equations.
By the way these equations don't consider the "shape" of circles.
So I calculate the rebound angle by finding the tangent where 2 circles intersect.
Now I have 2 different final speeds directions: the one calculated with momentum law and the one calculated with rebound.
I don't know how to combine the 2 speeds to get the final one
You'll need to calculate the speed in both the X and the Y direction.
Basically, what you do is calculate the results of the x component of the collision, the results of the collision in the y direction, and then combine them to find the resultant angles and speeds.
This is a common AP physics question, so you'll find lots of writeups on the internet about how to do it. This one looks like it should work for you:
http://spiff.rit.edu/classes/phys311.old/lectures/coll2d/coll2d.html
The solution I found is to consider normal and tangential components of my 2 circles velocities, and not their X and Y components.
This way I can apply law of conservation of momentum related to tangent and normal, and at the same time it considers the geometry of circles too.
The last part of this tutorial is very helpful, even if I used a different algorithm, with some different logics: https://www.youtube.com/watch?v=LPzyNOHY3A4
I am trying to bounce a projectile off of a wall in Slick. When the wall is vertical or horizontal, I can just invert the x or y velocity of the projectile, but when this is not the case I am struggling. I found another answer to a similar question in C# and have tried to implement it, but the result is just that the ball goes off at 180 degrees every time. What I have is:
Vector2f norm = wall.getNormal();
float comp = (vect.dot(norm)/norm.dot(norm));
Vector2f u = new Vector2f(norm.getX()*comp,norm.getY()*comp);
Vector2f w = new Vector2f(vect.getX()-u.getX(),u.getX());
vect.set(w.getX()-u.getX(),w.getY()-u.getY());
Where wall is a Vector2f that I am trying to bounce off of (converted from a line to a vector, but not sure if this was necessary) and vect is the trajectory of my projectile.
Any advice would be really helpful. I would love if someone could explain an answer to me rather than just giving me the code, because I think I may need to implement something slightly different later.
Thanks.
The answer here is going to wind up being mostly a question of math. I briefly go over the math/physics involved and trust that you should be able to implement the math/physics in code yourself.
How projectiles are supposed to bounce off of walls
In classical physics, or at least in a reasonably representative model of classical physics, when a projectile collides with a wall, the magnitude of the angle at which it leaves the wall relative to the 'normal' vector of the wall is equal to the magnitude at which it approaches the wall relative to the 'normal' vector. In other words, draw a line perpendicular to the wall the object is colliding with. The angle between this line and the vector of your projectile moving towards the wall will be the same as the angle of the vector of your projectile moving away from the wall.
This is most commonly discussed for light rays, but it works the same way for simple projectiles.
http://hyperphysics.phy-astr.gsu.edu/hbase/phyopt/fermat.html
How to calculate these angles
So let's say you have a vector for the normal of the wall, and a vector for the projectile. For 2-dimensional vectors, this is actually quite easy. You should have a couple of decent options here. One way might be to get the angles of the two vectors and subtract them to find the difference.
Now we know the magnitude of the angle, but we now need to create a vector with the same angle but on the other side of the normal vector. Your vector library conveniently allows you to adjust your vector by a given angle. You should be able to take the projectile's current velocity vector and adjust in the correct direction it by twice the angle between it and the normal-to-wall vector and get the desired velocity vector post-reflection. The trick I will leave you to figure out is a good way to determine if you need to adjust your vector in the clockwise or counter-clockwise direction.
Some things to keep in mind about Vector2f
The getNormal() method returns a unit vector in the same direction as the vector
If you want a vector normal to a certain vector, you must use the getPerpendicular() method
A vector may be rotated/adjusted by a certain angle using the sub(double theta) method
If you would like to retrieve the angle of a vector, you may do so using the getTheta() method
I've looked around for ways to rotate BufferedImages in Java and all I have found is AffineTransform. That's fine, but it seems like a bit of overkill if all I want to do is rotate 90 degrees. Would it be more efficient to just do it pixel-by-pixel? Is there some other method I could use?
From the Javadoc of the class you mention:
Handling 90-Degree Rotations
In some variations of the rotate methods in the AffineTransform class, a double-precision argument specifies the angle of rotation in radians. These methods have special handling for rotations of approximately 90 degrees (including multiples such as 180, 270, and 360 degrees), so that the common case of quadrant rotation is handled more efficiently.
That makes it seem like you shouldn't worry about performance without solid proof to the contrary.
In addition take note of the following method: quadrantRotate(int numQuadrants)
I am developing an augmented reality application for android and trying to use openGl to place cubes at locations in the world. My current method can be seen in the code below:
for(Marker ma: ARData.getMarkerlist().values()) {
Log.d("populating", "");
gl.glPushMatrix();
Location maLoc = new Location("loc");
maLoc.setLatitude(ma.lat);
maLoc.setLongitude(ma.lng);
maLoc.setAltitude(ma.alt);
float distance = currentLoc.distanceTo(maLoc);
float bearing = currentLoc.bearingTo(maLoc);
Log.d("distance", String.valueOf(distance));
Log.d("bearing", String.valueOf(bearing));
gl.glRotatef(bearing,0,0,1);
gl.glTranslatef(0,0,-distance);
ma.cube.draw(gl);
gl.glPopMatrix();
}
gl.glRotatef(y, 0, 1, 0);
gl.glRotatef(x, 1, 0, 0);`
Where y is yaw and x is the pitch. currently I am getting a single cube on the screen at a 45 degree angle someway in the distance. It looks like I am getting sensible bearing and distance values. Could it have something to do with the phones orientation? If you need more code let me know.
EDIT: I updated bearing rotation to gl.glRotatef(bearing,0,1,0); I am now getting my cubes mapped horizontally along the screen at different depths. Still no movement using heading and pitch but #Mirkules has identified some reasons why that might be.
EDIT 2: I am now attempting to place the cubes by rotating the matrix by the difference in angle between heading and bearing to a marker. However, all I get is a sort of jittering where the cubes appear to be rendered in a new position and then jump back to there old position. Code as above except for the following:
float angleDiff = bearing - y;
gl.glRotatef((angleDiff),0,1,0);
gl.glTranslatef(0,0,-distance);
bearing and y are both normalised to a 0 - 360 scale. Also, I moveed my "camera rotation" to above the code where I set the markers.
EDIT 3: I have heading working now using, float angleDiff = (bearing + y)/2;. However, I cant seem to get pitch working. I have attempted to use gl.glRotatef(-x,1,0,0); but that doesn't seem to work.
It's tricky to tell exactly what you're trying to do here, but there are a few things that stick out as potential problems.
Firstly, your final two rotations don't seem to actually apply to anything. If these are supposed to represent a movement of the world or camera (which mostly amounts to much the same thing) then they need to happen before drawing anything.
Then your rotations themselves perhaps won't entirely do what you intend.
Your cube is rotated around the Z axis. The usual convention in GL is for the camera to look down the Z axis, with the Y axis being considered 'up'. You can naturally interpret axes however you like, but a rotation around 'Z' would not typically be 'bearing', but 'roll'. 'Bearing' to me would be analogous to 'yaw'.
As you translate along the Z axis, I assume you are trying to position the object by rotating and translating, but obviously if the rotation is around the same axis as you translate along, it won't actually alter the position of the cube - it will always just be directly in front of the camera, spinning on its axis.
I'm not really clear on why you're trying to position the cube like that when it seems like you start off with a more specific location. You could probably directly construct a more appropriate matrix.
Finally, your camera/world rotation is two concatenated rotations around Y and X. You call these pitch and roll, but typically using euler angles for a camera rotation does not result in an intuitive result where terms like pitch and roll make complete sense. It is common to maintain an orientation and apply individual rotations to that in order to update it, rather than attempting to update several dependent rotations.
So yes, I would expect that this code, in the absence of other matrix operations, would likely result in drawing one or more cubes straight ahead which are simply rotated by some angle around the view direction.
I need to make a wheel fall on 1 of five angles and I want it to teeter when it gets to the angle. After the user spins the wheel, I have it slow down by multiplying the rotation velocity by .98 per tick. I sort of have it working by finding the closest of the angles and adding a small value in its direction to the velocity. However this looks unrealistic and can be glitchy.
I was thinking of implementing a damped sine wave but i'm not sure how I would do this.
Current Pseudocode:
var rotation, rotationVelocity, stoppingPoints[5];
update(deltaT) {
velocity -= rotationVelocity * 0.5 * dt;
closestAngle = findClosestAngle().angle;
rotationVelocity += (closestAngle - rotation) / 36 * dt;
rotation += rotationVelocity;
}
Edit:
Teeter: move or balance unsteadily; sway back and forth:
subtract a constant amount from it's velocity every iteration until it reaches zero
not only does this actually represent how friction works in real life, but it's easier too.
If you want it to move as though it were connected to a spring:
Hooke's law for springs is F = -kx where k is a constant and x is the distance from the origin if you want it to sway back and forth as though it were on a spring. keep track of it's rotation from an origin, and add -kx where x is it's rotational distance(or angle) from the origin.
Now, if you apply both friction and hooke's law to the spring, it should look realistic.
I think the closest angle that you want is the cloest to where it will stop. You can simulate where it will end, how long it takes to end, and use that to determine how much extra(or less) velocity you'll need.
Not sure what you mean by teetering exactly.
It sounds like you want to model a wheel with weights attached at the stoppingPoints. I mean, from a physics viewpoint. There is the existing rotational velocity, then deceleration from friction, and an unknown acceleration/deceleration caused by the effects of gravity on those points (as translated to a rotational velocity based on the position of the weights). Anyway, that's my interpretation and would probably be my approach (to model the gravity).
I think the teetering you speak of will be achieved when the acceleration caused by the weights exceeds the existing rotational velocity.