I want to move a label in a GUI in a circular path.I hope to maintain the speed using threads.
Can anyone tell me how to do circular movement? What is the logic we should use for it?
You can use the circumference formula : x^2 + y^2 = radius^2
Knowing that formula, if you know the radius you want (constant), you can do something like this (pseudocode, I hope you get the idea):
for (x from initial_x to end_x) {
y = Math.sqrt(radius^2 - x^2)
draw the label at position (x, y)
}
Related
I am reading an android tutorial for game development that explains how to convert in-game coordinates to actual pixels. Simple enough. This is done via function worldToScreen() as follows:
public Rect worldToScreen(float objectX, float objectY, float objectWidth, float objectHeight){
int left = (int) (screenCentreX - ((currentViewportWorldCentre.x - objectX) * pixelsPerMetreX));
int top = (int) (screenCentreY - ((currentViewportWorldCentre.y - objectY) * pixelsPerMetreY));
int right = (int) (left + (objectWidth * pixelsPerMetreX));
int bottom = (int) (top + (objectHeight * pixelsPerMetreY));
convertedRect.set(left, top, right, bottom);
return convertedRect;
}
It seems to return a rectangle object containing the four points that a square object would occupy.
Why does it use a square?
Why is it substracting top/left and adding bottom/right?
A thorough explanation will be much appreciated.
Answer to question 1
He's using a rectangle probably because it's a simple geometry object that is already implemented in Java and in most gaming libraries, like the one you are using (i can see he's using the Rect class).
Rectangle is also a common solution in 2D games when you want to implement simple collision detection for example.
Answer to question 2
You ask why he's adding bottom and right... But i can only see that he's adding top and left.
He's doing that because the y axis goes from up to down, and the x axis goes from left to right.
So to get the bottom point you have to add the y coordinate of the top point to the height of the rectangle.
Same for the right point, you have to add the x coordinate of the left point to the width of the rectangle.
In the hope that my Paint skills can come useful i made a drawing that probably will help you understand:
To make the drawing and my answer even more clear:
top + height = bottom
left + width = right
PS: "he" is the guy who made the tutorial that you're following.
I have been trying to solve this for a few hours, and the internet is pretty unfruitful on the subject.
I need help detecting and solving collisions between rectangles, and not just detecting, but note I mentioned solving as well.
These are two boxes, with x/y width/heights. I simply need to detect when they are overlapping, and push one of the boxes out of the other one smoothly.
Also, note that one box is stationary - and the other is moving.
Does anyone have anything on this (or can give me an example?) I'd really appreciate it.
I need the boxes to be able to rest on top of each other as well.
Thank you!
I'm not sure what the context here is (Are these boxes moving or stationary? Are you looking for a physically accurate resolution, or simply a geometrically correct one?), but it seems like you could accomplish this in the following way:
1) Determine if there is a box collision
2) Determine the intersection of the two boxes, which would produce a third box. The width and height of the box is your penetration depth.
3) move the center of one of the boxes by the penetration depth, (x - width, y - height).
This should cause the boxes to become disjoint.
FYI: Intersection of two boxes can be computed by taking the max of the mins and the mins of the maxes from both boxes.
Here is some code from my engine for box intersection:
bool Bounds::IntersectsBounds(const Bounds &other) const
{
return !(min.x > other.max.x || max.x < other.min.x
|| min.y > other.max.y || max.y < other.min.y);
}
bool Bounds::Intersection(const Bounds &other, Bounds &outBounds) const
{
if (!this->IntersectsBounds(other)) {
return false;
}
outBounds.min.x = std::max(min.x, other.min.x);
outBounds.min.y = std::max(min.y, other.min.y);
outBounds.max.x = std::min(max.x, other.max.x);
outBounds.max.y = std::min(max.y, other.max.y);
return true;
}
In this case, the "outBounds" variable is the intersection of the two boxes (which in this case is your penetration depth). You can use the width/height of this box to perform your collision resolution.
Yeah! This is a pretty common problem! You may want to check out the gamedev portion of the stack exchange network!
Detection
bool collide(float x1,float y1,float sx1,float sy1, float x2, float y2, float sx2, float sy2){
if (x1+sx1 <= x2)
return false;
if (x2+sx2 <= x1)
return false;
if (y1+sy1 <= y2)
return false;
if (y2+sy2 <= y1)
return false;
return true;
}
Resolution
As far as an answer, this depends on the type of application you are going for. Is it a sidescroller, top-down, tile based? The answer depends on the response to this question. I'll assume something dynamic like a sidescroller or top-down action game.
The code is not difficult, but the implementation can be. If you have few objects moving on the screen you can use a similar system to mine, which goes something like the following:
Get a list of objects you are currently colliding with, in order of distance from the current object.
Iterate through the objects, and resolve collisions using the following method
Check if the object has some special collision type (teleporter, etc) by sending that object a message, and checking on the return value (a teleporter will take care of the collision resolution)
check if the previous bottom position of our current object (A) was above the top side of the object in question(B), if so that means you have had a bottom collision. Resolve by setting the y position of A to the y position of B minus the height of A
(IF THE PREVIOUS FAILED) check if the previous right side of A was to the left of the left side of B, if so that means you have had a right side collision. Resolve by setting the x position of A to B's position minus A's width
(IF THE PREVIOUS FAILED) check if the previous left side of A was to the right of the right side of B, if so that means you have had a left side collision. Resolve by setting the x position of A to B's x position plus B's width
(IF THE PREVIOUS FAILED) check if the previous top side of A was below the bottom side of B, if so you have had a top side collision. Resolve by setting the y position of A to the y position of B plus B's height
Whew. It is important that you have the objects sorted according to distance, it will catch on edges if you check collisions with an object that is farther away!
I hope that makes sense!
Edit: Apparently doesn't work in Android.
https://stackoverflow.com/a/15515114/3492994
Using the available classes from the 2D Graphics API.
Rectangle r1 = new Rectangle(100, 100, 100, 100);
Line2D l1 = new Line2D.Float(0, 200, 200, 0);
System.out.println("l1.intsects(r1) = " + l1.intersects(r1));
What this doesn't tell you, is where...
This problem is hard to explain, so I'll use an image to aid me:
I'm trying to find an angle between the middle of the tank, to the mouse. The orange dot denotes the mouse position, the red line separates the two instances, and the green/lime line shows the tank's turret angle. I've been looking through stack overflow multiple times, and yet to no avail have I found a solution to my problem. I've even googled. In both, I have found many groups of code to 'find an angle'. I'm sure that these work, so I doubt my problem lies in the hands of bad code. I'm GUESSING that the error is found within the MouseMotionListener.
The two points I'm using to create the psuedo-line (NOT the green or red lines) to are the tank's middle point new Point(Tank.getX() + 16, Tank.getY() + 16) (the tanks size is 32x32) and the mouse point (set when there is a new mouse moved event).
Details about my program:
A frame is created and has a MouseMotionListener attached to it.
A JPanel is created and added to the frame.
Everything is drawn onto the JPanel.
In short, my getAngle() code is wrong, my MouseMotionListener is wrong, or I'm giving the wrong parameters. What is the problem?...
EDIT: As asked for in the comments here is my code and the output:
Code:
public static float getAngle(Point source, Point destination) {
System.out.println(source + "\n" + destination);
double xDiff = source.x - destination.x;
double yDiff = source.y - destination.y;
System.out.println((float) Math.toDegrees(Math.atan2(yDiff, xDiff)));
return (float) Math.toDegrees(Math.atan2(yDiff, xDiff));
}
Output:
java.awt.Point[x=116,y=116] // Source point
java.awt.Point[x=134,y=123] // Destination point
-158.7495
Well, after plenty of Googling, I found that there really was no error. All the code was correct, all.. pretty much everything was correct. The only thing that was wrong was that it was off by 90 degrees. This thought had crossed my mind multiple times, but every time I looked at the dot and the line, it just didn't seem right... The fixed code is below:
public static float getAngle(Point source, Point destination) {
System.out.println(source + "\n" + destination);
double xDiff = source.x - destination.x;
double yDiff = source.y - destination.y;
System.out.println((float) Math.toDegrees(Math.atan2(yDiff, xDiff)));
return (float) Math.toDegrees(Math.atan2(yDiff, xDiff)) + 90.0F;
}
For some reason, I feel like I've just dropped a couple IQ points for overlooking this multiple time.
I'm attempting an exercise where a vehicle is following the Lemniscate of Bernoulli (or more simply, a figure-8 track). I want to use glTranslatef and glRotatef to achieve this. So far, I have been able to successfully get the vehicle to follow/translate along this path by using the parametric form as follows:
X = (width * cos(t)) / (1+sin^2(t))
Y = (width * cos(t) * sin(t)) / (1+sin^2(t))
Where t is in -pi, pi
In the code, this is as follows:
carX = (float) ((Math.cos(t) / (1 + Math.sin(t)*Math.sin(t))));
carY = 0.0f;
carZ = (float) ((Math.cos(t) * (Math.sin(t))) / (1 + Math.sin(t)*Math.sin(t)));
gl.glTranslatef(carX,carY,carZ);
So that works well enough. My problem now is rotating the vehicle so that it follows the path defined by the Lemniscate of Bernoulli. I want to achieve this by using glRotatef to rotate around the Y axis, but I am not sure how to proceed in regards to finding the angle to input in glRotatef. The rotate is currently in place so that it only manipulates the vehicle, and appears to just need the correct mathematics to follow the path.
Things I have tried:
Using the derivative of the X and Y forms listed above. I used them independently of each other, because I'm not sure how to/if they need to be combined to be used for the angle. With some
minor manipulation they follow the straight areas near the origin,
but broke down around the curves.
Directly finding the tangent of the
t value and converting to degrees. Erratic spinning resulted.
If anyone has any suggestions that may be better than the glRotatef method, that would be appreciated as well. I've seen that gluLookAt may be helpful, and I may attempt to find a solution using that.
(Note: I'm working in JOGL using Java and the FFP, but I'm comfortable with C/C++ code snippets.)
assuming camera view is the driver's view, gluLookAt is exactly what you need! based on your carX,carY,carZ computations (assuming that the math is good), you can store previous values and use it:
//globals & imports:
import javax.vecmath.*;
Vector3f current = new Vector3f();
Vector3f prev = new Vector3f();
computation is as followed:
//on drawing:
prev.set(current);
current.x = (float) ((Math.cos(t) / (1 + Math.sin(t)*Math.sin(t))));
current.z = (float) ((Math.cos(t) * (Math.sin(t))) / (1 + Math.sin(t)*Math.sin(t)));
glu.gluLookAt(current.x, 0f, current.z,
current.x - prev.x, 0f, current.z - prev.z,
0f, 1f, 0f);
i'll test it when i get back home, to make sure it's working, but as far as i can tell, this should do the trick.
This is something I'm trying to do for a university assignment and I'm quite new to it, but I've done a lot of reading on the subject. Please could someone to explain, in the simplest terms, how to do what I'm trying to do, so that I can understand what needs to happen?
I have an array of objects, each draw a circle to the screen; I have them bouncing within a bounding box but now I'd like them to collide.
I wrote the method below, which is working... but only just. The balls occasionally get stuck and 'jitter' on one another and I have no idea why this is happening. Also, I think I'm checking for more collisions than necessary(?).
void handleObjectCollision() {
for(int i = 0; i < _myBtns.length; i++) {
if(i != _id) {
float dx = _myBtns[i].x - x;
float dy = _myBtns[i].y - y;
float distance = sqrt(dx*dx + dy*dy);
if(distance < r * 2) {
xS = -xS;
yS = -yS;
// Debug
// println("Collision!");
}
}
}
A full paste of my class and pertaining segments can be found here: http://pastebin.com/eJawiHAE.
Also, here is an example I've been working from, http://processing.org/learning/topics/bouncybubbles.html.
I'm trying to achieve a simple bounce (reversal in speed?), without added physics or using vectors, as I want to be able to understand what's happening in it's simplest form, first.
Thank you.
You cannot just reverse the direction in which your object is moving, because the collision may happen almost from behind it, in which case the reversal will put it again in collision course against the object which collided with it. That explains the jitter that you see. You need to consider the direction from which the collision occurred, and adjust your direction vector accordingly, using the related physics formulas for what is known in physics as "elastic collisions".
Here, check this out: http://en.wikipedia.org/wiki/Elastic_collision