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.
Related
ive been looking for a while and cannot find solution
so I am trying to find a point on a polyline that is either a certain distance toward the opposite point or away from the main point.(I have pictures) if you are familiar with celestial navigation this is called the intercept method. so here is the almost working code.
double distance = ap.distanceToAsDouble(gp)*0.00053996;
double convert = nauticalMiles;
double t = convert / distance;
double actlon = ((1 - t)*ap.getLongitude() + t*gp.getLongitude());
double actlat = ((1 - t)*ap.getLatitude() + t*gp.getLatitude());
bear = ap.bearingTo(new GeoPoint(actlat,actlon));
actual = ap.destinationPoint(nauticalMiles/0.00053996,bear);
so "ap" is the point that the point I am trying to find will be (nauticalMiles) "away" or "toward" the "gp" and they are correct so "bear" is the angle kind of from ap to gp that almost works completely. "actual" is the point I am trying to find. here is an image of how this works out.
as you can see th actual point is toward the gp point from the ap point denoted with the yellow polyline. BUT!!!! if you look at the picture the yellow line is not exactly on the red line so I think that it is off a bit. so I tried to do
bear = ap.bearingTo(gp);
actual = ap.destinationPoint(nauticalMiles/0.00053996,bear);
instead doing that whole calculation that was in the code sample previously which should work but I am getting this
which is totally off it is not on the line. so for right now I am sticking with the first approach because it is relatively accurate but that is why I am asking this question. What calculation could I do to make the yellow line exactly on the red line? I am trying to get the most accurate calculation that I can get. thank you for your time.
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.
So I'm programming a recursive program that is supposed to draw Koch's snowflake using OpenGL, and I've got the program basically working except one tiny issue. The deeper the recursion, the weirder 2 particular vertices get. Pictures at the bottom.
EDIT: I don't really care about the OpenGL aspect, I've got that part down. If you don't know OpenGL, all that the glVertex does is draw a line between the two vertices specified in the 2 method calls. Pretend its drawLine(v1,v2). Same difference.
I suspect that my method for finding points is to blame, but I can't find anything that looks incorrect.
I'm following the basically standard drawing method, here are the relevant code snips
(V is for vertex V1 is the bottom left corner, v2 is the bottom right corner, v3 is the top corner):
double dir = Math.PI;
recurse(V2,V1,n);
dir=Math.PI/3;
recurse(V1,V3,n);
dir= (5./3.)* Math.PI ;
recurse(V3,V2,n);
Recursive method:
public void recurse(Point2D v1, Point2D v2, int n){
double newLength = v1.distance(v2)/3.;
if(n == 0){
gl.glVertex2d(v1.getX(),v1.getY());
gl.glVertex2d(v2.getX(),v2.getY());
}else{
Point2D p1 = getPointViaRotation(v1, dir, newLength);
recurse(v1,p1,n-1);
dir+=(Math.PI/3.);
Point2D p2 = getPointViaRotation(p1,dir,newLength);
recurse(p1,p2,n-1);
dir-=(Math.PI*(2./3.));
Point2D p3 = getPointViaRotation(p2, dir, newLength);
recurse(p2,p3,n-1);
dir+=(Math.PI/3.);
recurse(p3,v2,n-1);
}
}
I really suspect my math is the problem, but this looks correct to me:
public static Point2D getPointViaRotation(Point2D p1, double rotation, double length){
double xLength = length * Math.cos(rotation);
double yLength = length * Math.sin(rotation);
return new Point2D.Double(xLength + p1.getX(), yLength + p1.getY());
}
N = 0 (All is well):
N = 1 (Perhaps a little bendy, maybe)
N = 5 (WAT)
I can't see any obvious problem code-wise. I do however have a theory about what happens.
It seems like all points in the graph are based on the locations of the points that came before it. As such, any rounding errors that occurs during this process eventually start accumulating, eventually ending with it going haywire and being way off.
What I would do for starters is calculating the start and end points of each segment before recursing, as to limit the impact of the rounding errors of the inner calls.
One thing about Koch's snowflake is, that the algorithm will lead to a rounding issue one time (it is recursive and all rounding errors add up). The trick is, to keep it going as long as possible. There're three things you can do:
If you want to get more detailed, the only way is to expand the possibilities of Double. You will need to use your own range of coordinates and transform them, every time you actually paint on the screen, to screen coordinates. Your own coordinates should zoom and show the last recursion step (the last triangle) in a coordination system of e.g. 100x100. Then calculate the three new triangles on top of that, transform into screen coordinates and paint.
The line dir=Math.PI/3; divides by 3 instead of (double) 3. Add the . after the 3
Make sure you use Point2D.Double anywhere. Your code should do so, but I would explicitely write it everywhere.
You won the game, when you still have a nice snowflake but get a Stackoverflow.
So, it turns out I am the dumbest man alive.
Thanks everyone for trying, I appreciate the help.
This code is meant to handle an equilateral triangle, its very specific about that (You can tell by the angles).
I put in a triangle with the height equal to the base (not equilateral). When I fixed the input triangle, everything works great.
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
I've just tried to write "line" code to visualize a simple math;
Here it is
Ploygon polygon=new Ploygon();
int x,y;
ploygon.addPoint(0,0);
polygon.addPoint(width,height);
g.drawPolygon(polygon);
The code gives y=x effect;
OK... it is quite simple code; But the thing I am interested to get is points each N pixels during the statement period as {x0,y0}{0,0} and {x1,y1} {width,height} and that is the problem :(
The polygon xpoints array is not handy because it may contain just the same points which were added when addPoint(x,y) method was invoked; so in my case there just two added points which are connected by Polygon but what about all the rest points which stay between these points {x0,y0}{0,0} and {x1,y1} {width,height} ? How to get them?
For example. Coming back to the previous snippet how to find out what point x,y value is when (height%N)=0 etc?
Is there the most optimal way?
Thanks
What you have to realise here is that you are no longer working with pixels/coordinates per se, but you are working with vectors. You'd get much the same image from a polygon contained the coordinates (-500,-500) and (500,500) which is drawn onto a Graphics object which represents the (clipped) area from (0,0) in the bottom left to (100,100) in the bottom right. (ignoring for now that the actual coordinate system of Graphics has an inverted y-axis).
Therefore you have to solve this in a more back-to-basic's Math way rather than a “read the pixels” way. Unless you just want to determine if a given point is in the shape (for which the Shape interface offers a built-in method), you would be looking at calculating the slope of a line and determining functions which represent your line. For instance continuing from the example you have two points (-500,-500) and (500,500) which gives a slope of 1000/1000 = 1. So you could rewrite that function in terms of your x-coordinates as f(x) = -500 + (x + 500). Then if you want to know if the point (100,200) is on that line all you need to do is calculate f(100) and see that it isn't.
Getting back to your example, finding points which match a predicate (height%N =0), we'd be looking for f(x) == 0 mod N and so 'all' you'd need to do is solve the equation for x.