How to move a dot when given 2 coordinate points?

Started by
14 comments, last by tom_mai78101 12 years, 3 months ago

That is a bug. Perhaps you are using `int' in some place where you should be using `double'?


Nope. On second thought, I shouldn't have used "double" in the first place. Pixel manipulation don't need to use double, right? I'm using "int" variables to calculate the simple pathing in a one-dimensional array, so it wouldn't be wise to use a double as an array iterator.

I'll try to find my logic errors. I'm pretty sure calculating xVel and yVel are done at the same pace, and not calculating the results separately.

Or better yet, I will upload my source code here, archived into ZIP, exported from Eclipse. (Hosted at Mediafire)
Advertisement
Do your computations using doubles and then round only when you need to convert to a pixel. In general, things work much better when you keep your computations independent from the way you'll display the results.

[quote name='alvaro' timestamp='1326571040' post='4902740']
That is a bug. Perhaps you are using `int' in some place where you should be using `double'?


Nope. On second thought, I shouldn't have used "double" in the first place. Pixel manipulation don't need to use double, right? I'm using "int" variables to calculate the simple pathing in a one-dimensional array, so it wouldn't be wise to use a double as an array iterator.

I'll try to find my logic errors. I'm pretty sure calculating xVel and yVel are done at the same pace, and not calculating the results separately.

Or better yet, I will upload my source code here, archived into ZIP, exported from Eclipse. (Hosted at Mediafire)
[/quote]

Tom, you'll screw yourself if you only use int. Just use doubles or else your calculations will never be very precise, and you'll miss badly. Often time, your pixel location during one step will be different from the previous step. For example, a velocity of 1.5, moving from 0,0 to 10,0:
Frame 1: x = 1.5 (draw at 1)
Frame 2: x = 3.0 (draw at 3)
Frame 3: x = 4.5 (draw at 4)
Frame 4: x = 6.0 (draw at 6)
Frame 5: x = 7.5 (draw at 7)
Frame 6: x = 9.0 (draw at 9)
Frame 7: x = 10.0 (draw at 10)

If you use int, then your velocity will be rounded down to 1, and it will take 10 frames when it should take 7.

Again, I prefer the trig method when doing this, but you can use which ever you want.

One other thing. There's obviously a bug in your code if you can't move diagonally. Each frame you should be able to change x and y location.

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

Unfortunately, the diagonal velocity is less than 1 (velocity vector = 1/sqrt(starting point and finishing point)), which when converted to "int" for the pixel coordinates, it is misplaced as 0. Same goes for all of the calculations done per frame.

When using the trigonometric method and the vector method, all of the xVel and yVel ranges from 0.4 to 0.9. If I increase my speed, I would get a more accurate range of 1.0 to 1.5, but it causes the dot pixel to jump around. Other than the jumping, the direct path movement for speed more than 5 is correct.

Due to the way I set my speed to 1 pixel per tick, 60 ticks per second, I have to click multiple times in order for the program is obtain a number larger than 1.0, which by that point, the dot then moves.

I even tried adding a new thread to do the calculations in case the reaction time is less than par, but then it complicates things; I have discarded it.

Here's my next theory:

What if I add this:


xa -= (xm * Math.cos(rot) + ym * Math.sin(rot)) * speed;
ya -= (ym * Math.cos(rot) - xm * Math.sin(rot)) * speed;


Where rot is the angle from Point 2 to Point 1 in radians, xm and ym are the directional vectors for Point 1 and Point 2, xm for X axis, ym for Y axis, and the xa and ya are the acceleration for the dot.
This is why you should use floating point for your positions, and only convert to ints when you want to render something.
I credit C++ Programming Forum members, dwks and _Mike, for giving me the information I lack in my linear algebra class, or I should blame my school for teaching the lessons up to subspaces before we even reached vectors for this semester's linear algebra course and gave us a winter vacation. The source for the information is linked here.

I credit RulerOfNothing in his very last post for giving me the inspiration to rewrite my program from scratch, and from there I finally took notice of a bug when comparing the new project with my old in Subversion.

This time, from dwks, I calculate the two points by using normal vectors and distances, along with doing the arithmetic entirely in double. I revised my Dot class by not using the java.awt.Point class, and added a few more functions to separate the logic in a more versatile way.

Here is my results:


public class Dot implements Tickable {
public double xPosition = 0;
public double yPosition = 0;
public double xTarget = 0;
public double yTarget = 0;
public double xDist = 0;
public double yDist = 0;
public void tick() {
// Setting up a vector.
xDist = xTarget - xPosition;
yDist = yTarget - yPosition;
// Normalize the vector.
double length = Math.sqrt(xDist * xDist + yDist * yDist);
xDist /= length;
yDist /= length;
}
public void update() {
if (Math.abs(xTarget - xPosition) < 1)
xDist = 0;
if (Math.abs(yTarget - yPosition) < 1)
yDist = 0;
xPosition += xDist;
yPosition += yDist;
System.out.println(xPosition + " " + yPosition + " " + xDist + " " + yDist + " " + xTarget + " " + yTarget);
}
public void render(int[] pixels, int offset, int width, int height) {
if (xPosition < 0 || xPosition >= width)
return;
if (yPosition < 0 || yPosition >= height)
return;
pixels[(((int) xPosition) + offset) + ((int) yPosition) * width] = -1;
}
public void getInput(MouseInputHandler i) {
if (xTarget == -1 || yTarget == -1)
return;
xTarget = i.X / Game.SCALE;
yTarget = i.Y / Game.SCALE;

}
}


There is no trigonometric calculations involved, due to Math.atan2() function containing many special cases, and there's one of the special cases turning into the source of my logic error, resulting in a bug, as mentioned by most people in this thread. I didn't use plain vectors, due to me lacking information in this subject. In fact, I don't even know what it's called until I read the thread mentioned at the top of this post.

There is room for improvements in this class, but I'm pretty sure I have laid a nice looking foundation that works pretty nicely. All there's left to do, is to thank the people who helped in this thread.

In short, I have my problem solved, thanks to the people mentioned at the top.

This topic is closed to new replies.

Advertisement