How to make a circle move in circles? - java

Circle c1 = new Circle(20);
c1.relocate(200,200); //Set X and Y
What I want to do is make the circle move in circles around an invisible center of rotation. How can that be achieved?
Thanks.
Edit: I have extremely poor trigonometry skills.

You can use equations for a point on a circle using polar coordinates:
circle_x = rot_center_x + radius * cos(angle)
circle_y = rot_center_y + radius * sin(angle)
Using this you'll get a center point for your new circle. Then you just need to increase (counter clock wise) or decrease (clockwise) your angle, blank screen and draw the circle again.
The angle for trigonometric function is in radians, you have 2*pi radians in a full circle. So if you want angle zero degrees, put in 0. For 90 degrees, put in pi/2.0.
For any other angle use this conversion formula:
angle_rad = pi/180.0 * angle_degrees
If you want to time your rotation you have to choose the angular speed of rotation omega.
omega = 2*pi*f
where f is frequency of rotation, for example f=1Hz means your object will rotate in full circle after one seecond. Omega is in radians per second, so if you have omega 10 radians, then your object will rotate 10 radians during one second, or 100 radians during 10 seconds.
Now you have to determine how much angle you need to add each frame of animation:
ang_inc = omega / fps_avg;
ang += ang_inc;
where fps_avg is measured average of frames per second.

Related

libGDX cone rotation while maintaing location in X,Y,Z

I am trying to create some sort of "lighthouse" effect by creating a cone and rotating it around the X/Y. The result "runs off" on the Z axis and is also wrong on the Y/X axis if there is a combination of both a Yaw and Pitch degrees.
(The Z axis goes from right to left, X towards the screen, Y upwards).
The yellow cone is the effect. it starts as the see-through cone.
This is hoe the x,y,z locations of the cone are set:
float c = this.height/2;
this.locationX = player.getPosition().x - c*((float)Math.sin(Math.toRadians(tiltOnY)));
this.locationY = player.getPosition().y + c*((float)Math.sin(Math.toRadians(tiltOnX)));
this.locationZ = player.getPosition().z-c;
where height is the height of the cone, and tilt starts at 0 and is added or reduced (as a result of input) with module of 360 degrees.
This is the code in render:
inst = new ModelInstance(this._game_.viewConeModel);
inst.transform.setToTranslation(cone.getX(),cone.getY(),cone.getZ())
.rotate(Vector3.Y,cone.getTiltOnY()).rotate(Vector3.X,cone.getTiltOnX()).rotate(Vector3.X,90);
this._game_.modelBatch.render(inst,this._game_.environment);
The desired result is that the point of the cone remains in the same location, but the cone itself rotates by the tilts on X and Y axis.

LWJGL: Rotate quad based on mouse position

I am trying to have a character hold a gun, but I want the gun to move with the mouse. For example, if the mouse is up, the gun points up. If the mouse is to the left, the gun points to the left. I used the player position and the mouse position to construct a right triangle, then used inverse sine to find the angle of elevation. However, this only works for 90 degrees of movement. Any ideas of how else I could approach this so that I get a full 360 degrees of rotation?
Code for calculating the angle:
private double calcAngle()
{
double mouseX,mouseY,subX,subY,playerToMouse,mouseToSub,angle;
mouseX = Mouse.getX();
mouseY = Mouse.getY();
subX = mouseX;
subY = y;
playerToMouse = Math.sqrt(Math.pow(x-mouseX,2)+Math.pow(y-mouseY,2));
mouseToSub = Math.sqrt(Math.pow(mouseX-subX,2)+Math.pow(mouseY-subY,2));
angle = Math.toDegrees(Math.asin(mouseToSub/playerToMouse));
return angle;
}
Current rotation (Pink represents player; Green represents gun; Yellow represents mouse):
You can use Math.atan2(mouseY-gunY, mouseX-gunX) which will return an angle between pi and -pi radians, or 180 and -180 degrees after you convert it to degrees. The problem with using asin is that 1/1 is equal to -1/-1 which makes it impossible for the function to tell them apart, and you want different results in each case.

How does the rotation angle using a rotation matrix correspond to a degree

I am trying to rotate a box in java using a rotation matrix.
(I am using the LWJGL and Slick 2D libraries)
my code to rotate 1 point around the center point is this:
point1X = (float) (centerX * Math.cos(rotation) - centerY * Math.sin(rotation));
point1Y = (float) (centerX * Math.sin(rotation) + centerY * Math.cos(rotation));
Right now I just update the rotation every update like so:
rotation += delta * 0.001;
This works great except the rotation number does not seem to correspond to a degree from 0˚ to 360˚
Is there a formula or something that will translate the rotation number to a readable degree and vice versa?
Normally, trig functions expect their arguments to be in radians, not degrees.
2*pi radians = 360 degrees.

how can I rotate an opengl 3d object to point to a GPS position (lat, long)?

I have a 3D arrow drawn with OpenGL that points to the coordinates (0, 0, 0) and I want it to point to a specific GPS location depending on my GPS position and Orientation.
I've tried calculating the azimuth (with my phone's orientation) and adjusting it to be the real north (not the magnetic north).
SensorManager.getOrientation(remappedRotationMatrix, orientation);
// convert radians to degrees
float azimuth = orientation[0];
azimuth = azimuth * 360 / (2 * (float) Math.PI);
GeomagneticField geoField = new GeomagneticField(
Double.valueOf(loc.getLatitude()).floatValue(),
Double.valueOf(loc.getLongitude()).floatValue(),
Double.valueOf(loc.getAltitude()).floatValue(),
System.currentTimeMillis());
// converts magnetic north into true north
azimuth -= geoField.getDeclination();
Then getting the bearing from my Location to the Location I want to point.
target.setLatitude(42.806484);
target.setLongitude(-1.632482);
float bearing = loc.bearingTo(target); // (it's already in degrees)
if (bearing < 0) {
bearing = bearing + 360;
}
float degrees = bearing - azimuth;
if (degrees < 0) {
degrees = degrees + 360;
}
and calculating the degrees I have to rotate the arrow
gl.glRotatef(degrees, 0.0f, 1.0f, 0.0f);
arrow.draw(gl);
Is there someway to do it? Could another possibility be to convert the GPS position to the OpenGL coordinates and use GLU.gluLookAt to point to it?
Thanks.
This seem to be purely a math problem.
Your question is pretty vague, I don't think I can help you without understanding more precisely how your scene is set up and what you want.
Do you know how to use 3D rotation matrices? If not, you probably should learn how they work.
It shouldn't be complicated to calculate the bearing and then rotate the arrow by the degrees you get. I have done the same in 2D although not in OpenGL. I based my code on the Radar sample (http://apps-for-android.googlecode.com/svn/trunk/Radar/). Here is how I draw the 2D arrow:
double bearingToTarget = mBearing - mOrientation;
// Draw an arrow in direction of target
canvas.rotate((float) bearingToTarget, center, center);
final int tipX = center;
final int tipY = center-radius;
canvas.drawLine(center, center, tipX, tipY, mArrowPaint);
final int tipLen = 30;
final int tipWidth = 20;
Path path = new Path();
path.moveTo(tipX, tipY);
path.lineTo(tipX + tipWidth/2, tipY + tipLen);
path.lineTo(tipX - tipWidth/2, tipY + tipLen);
path.lineTo(tipX, tipY);
path.close();
canvas.drawPath(path, mArrowPaint);
canvas.restore();
mBearing is calculated using the method GeoUtils.bearing from the Radar sample which takes care of the complicated math. mOrientation is just the orientation from the sensor listener. So the idea is to compute the difference between the bearing of the GPS location you want to point to (mBearing) and the current orientation of the phone (mOrientation). This gives us the angle bearingToTarget. We then rotate the view about its center by that angle before drawing the arrow along the y axis. This is the same as drawing the arrow rotated by bearingToTarget degrees.
You should be able to apply the same logic in OpenGL by rotating the view about the center of the screen by bearingToTarget degrees before you draw the arrow. Exactly what point you rotate about depends on how your view is set up. To make it simple, make the starting point of your arrow at the origin. Then you can simply rotate about the origin using glRotatef. Otherwise you would first need to translate to the center of the rotation, rotate and then translate back again (this is the common OpenGL technique for rotation about a point).

How to position a Node along a circular orbit around a fixed center based on mouse coordinates (JavaFX)?

Im trying to get into some basic JavaFX game development and I'm getting confused with some circle maths.
I have a circle at (x:250, y:250) with a radius of 50.
My objective is to make a smaller circle to be placed on the circumference of the above circle based on the position of the mouse.
Where Im getting confused is with the coordinate space and the Trig behind it all.
My issues come from the fact that the X/Y space on the screen is not centered at 0,0. But the top left of the screen is 0,0 and the bottom right is 500,500.
My calculations are:
var xpos:Number = mouseEvent.getX();
var ypos:Number = mouseEvent.getY();
var center_pos_x:Number = 250;
var center_pos_y:Number = 250;
var length = ypos - center_pos_y;
var height = xpos - center_pos_x;
var angle_deg = Math.toDegrees(Math.atan(height / length));
var angle_rad = Math.toRadians(angle_deg);
var radius = 50;
moving_circ_xpos = (radius * Math.cos(angle_rad)) + center_pos_x;
moving_circ_ypos = (radius * Math.sin(angle_rad)) + center_pos_y;
I made the app print out the angle (angle_deg) that I have calculated when I move the mouse and my output is below:
When the mouse is (in degrees moving anti-clockwise):
directly above the circle and horizontally inline with the center, the angle is -0
to the left and vertically centered, the angle is -90
directly below the circle and horizontally inline with the center, the angle is 0
to the right and vertically centered, the angle is 90
So, what can I do to make it 0, 90, 180, 270??
I know it must be something small, but I just cant think of what it is...
Thanks for any help
(and no, this is not an assignment)
atan(height/length) is not enough to get the angle. You need to compensate for each quadrant, as well as the possibility of "division-by-zero". Most programming language libraries supply a method called atan2 which take two arguments; y and x. This method does this calculation for you.
More information on Wikipedia: atan2
You can get away without calculating the angle. Instead, use the center of your circle (250,250) and the position of the mouse (xpos,ypos) to define a line. The line intersects your circle when its length is equal to the radius of your circle:
// Calculate distance from center to mouse.
xlen = xpos - x_center_pos;
ylen = ypos - y_center_pos;
line_len = sqrt(xlen*xlen + ylen*ylen); // Pythagoras: x^2 + y^2 = distance^2
// Find the intersection with the circle.
moving_circ_xpos = x_center_pos + (xlen * radius / line_len);
moving_circ_ypos = y_center_pos + (ylen * radius / line_len);
Just verify that the mouse isn't at the center of your circle, or the line_len will be zero and the mouse will be sucked into a black hole.
There's a great book called "Graphics Gems" that can help with this kind of problem. It is a cookbook of algorithms and source code (in C I think), and allows you to quickly solve a problem using tested functionality. I would totally recommend getting your hands on it - it saved me big time when I quickly needed to add code to do fairly complex operations with normals to surfaces, and collision detections.

Categories