I am trying to rewrite the Game "Achtung, die Kurve" (Attention, the Curve)
Now, i am stuck with the Problem:
How can i draw a Curve, which goes through N Points(x/y Coords)
for(int i = 0;i < xList.size();i++)
{
path.lineTo(player1.getShape().getCenterX(),player1.getShape().getCenterY());
}
^This will always create a new Line, so my FPS get to 10 very quickly
Any Help?
This is an algebra problem that can be solved with systems of linear equations. http://en.wikipedia.org/wiki/System_of_linear_equations
Generally, a curve that passes through N points is an (N-1)th degree polynomial. So if you want to find a polynomial that passes through 3 points (e.g. (-1,1), (0, 3), (1, -1)) you would need a quadratic equation like this: ax^2+bx+c=y.
To find the values of a,b, and c, you need the plug the x and y coordinates in, then solve the system of equations.
a(-1)^2+b(-1)+c=1
a(0)^2+b(0)+c=3
a(1)^2+b(1)+c=-1
that simplifiles to
a-b+c=1
c=3
a+b+c=-1
Nicely, we already have c=3. By combining the first equation and the second we can get
2a+2c=0
Since we know c=3, this becomes
2a+3=0
So a=-1.5.
From here we can put these values of a and c into the last equation to get this
-1.5+b+3=-1
Which gives a b=-3.5. Plugging these values of a,b, and c back into the quadratic equation yields this
-1.5x^2-3.5x+3=y
I haven't double checked my math, but if I did it correctly, this will give a quadratic curve that passes through the three points.
Undoubtedly, there is already a library out there for doing this, but I'm sorry to say I don't know what that would be. Hopefully, knowing about the math behind your problem will help you find your answer.
Related
I am making my own implementation of a raycaster in a game I am making, and I have come across a very hard problem. I have a player (the black dot), and I need to find the intersection nearest to the player. In the image below, the arrow is pointing to the intersection point I need.
What I guess I am trying to say is that I need a function something like this:
// Each line would take in 2 map values for it's 2 points
// In turn, the map would have to have an even number of points
public Point getNearestIntersection(int playerX, int playerY, int lineDir, Point[] map) {
// whatever goes here
}
I am going to have to do this about 50 times every frame, with about 100 lines. I would like to get 40 fps at the least if possible... Even if I divide it up into threads I still feel that it would cause a lot of lag.
The class Point has a method called distance which calculates the distance of two points. You then could loop all points to get the nearest. Could be something like this:
Point currentNearestIntersection;
double smallestDistance;
for (Point inter : intersections) {
double distance = player.distance(inter );
if (distance < smallestDistance) {
currentNearestIntersection= inter;
smallestDistance = distance;
}
}
axis/line intersection is in reality solving:
p(t)=p0+dp*t
q(u)=q0+(q1-q0)*u
p(t)=q(u)
t=? u=?
where:
p0 is your ray start point (vector)
dp is ray direction (vector)
q0,q1 are line endpoints (vectors)
p(t),q(u) are points on axis,line
t,u are line parameters (scalars)
This is simple system of 2 linear equations (but in vectors) so it lead to N solutions where N is the dimensionality of the problem so choose the one that is not division by zero ... Valid result is if:
t>=0 and u=<0.0,1.0>
if you use unit dp vector for direction of your ray then from computing intersection between axis and line the t parameter is directly distance from the ray start point. So you can directly use that ...
if you need to speed up the intersections computation see
brute force line/line intersection with area subdivision
And instead of remebering all intersections store always the one with smallest but non negative t ...
[Notes]
if you got some lines as a grid then you can compute that even faster exploiting DDA algorithm and use real line/line intersection only for the iregular rest... nice example of this is Wolfenstein pseudo 3D raycaster problem like this
Ok, I need to write a java algorithm which simulates the SMOOTH function written in IDL. But I'm not quite sure how that algorithm works. The smooth equation is given by:
I know there is already a similar post regarding boxcar averaging. But the algorithm seems to be different.
What I understand in this equation is that there is two states (if statement), the first one is calculating the weight average, the second one is to ignore the boundary.
In the first equation, I think I got the summation notation, it starts from 0 to (w - 1).
What I don't get is the one inside summation Ai+j-w/2.
The following is the sample data (just corner part of large data) that was calculated using IDL. I used weight 5 to calculate this.
Please, explain me how that algorithm works.
Thanks
You want the i'th average to be from a window around the i'th point. So it has to start before that point, and end after.
Subtracting off w/2 in the index causes j=0 to be the start of the window you want, and j=w-1 to be the end of the window you want.
It would be entirely equivalent to sum from j=-w/2 to j=w/2-1 instead.
I would like to find a way, given a set of any points on a 2 dimensional (or 3 dimensional if possible) plane, to connect as many of these points as possible with an equation, preferably in the form of X^n+BX^n and so on. X being of course a variable, and b and n being any numbers.
This would hopefully work in a way that given say, 50 random points, I would be able to use the equation to draw a line that would pass through as many of these points as possible.
I plan on using this in a compression format where data is converted to X,Y coordinate pairs, the goal is then to create equations that can reproduce these points. The equation would then be stored and the data would be replaced with a pointer to the equation as well as the number to enter into the equation to get the data back.
Any feedback is nice, this is just an idea I thought of during class and wanted to see if it would be possible to implement in a usable format.
To connect n points you need a polynomial of at most degree n-1. You can use Polynomial Regression to form your line.
ADDED INFO:
I'm using the inside of a square as an arena. On start up, the square spawns in a random position, and rotation, and I can't access any of the squares attributes.
I then have a moving object inside the square, that I'm building AI for, and I want the object to 'learn' where the arena walls are. Every time the object bumps into a wall, I get a touch return, so I know if its hit or not. I'm using this to map the global position of where the object hit the wall and save it ... After 3 hits on the same wall, I want to mathematically 'draw a straight line' down those dots which will represent the arena walls - with this, I can tell my object not to go near these coordinates.
The reason for 3 dots? Well, if the object hit one side of a wall, then was to hit another side of a wall, I will have a line drawn from one side to another, giving false data about where the wall is.
If Java sees three (or more) dots inline, it knows that the object has hit the same wall (either being further up or so).
CONTINUED:
I'm trying to map out lines with given coordinate data. Basically I have an array that holds X and Y coordinates, and I want to be able to mathematically detect if it's they make up a straight line (give or take a few pixels). (The coordinate are a boarder of a square)
For example, the array might be like this:
[x0][y0] - 1,1
[x1][y1] - 2,2
[x2][y2] - 5,5
Which will present a diagonal line of on side of the square, like so:
But sometimes I might get one coordinate of one side of the square, and then another side, all mixed up (and not necessarily on a 90 degree angle either!). So I want to be able to run through the array, and detect what coordinates make a line (or the boarder side of the square), like so:
So right now, I have a 2D array:
private double wallLocations[][] = new double[10][10];
and a while loop that doesn't do the job. I don't really know where to even start with this one:
for(int r = 0; r < wallIndex; r++){
for(int c = 0; c < wallIndex; c++){
int index = 0;
if(wallLocations[r][index] == wallLocations[r][c] && wallLocations[r][index + 1] == wallLocations[r][c] &&
wallLocations[r][index + 2] == wallLocations[r][c]){
System.out.println("***** Wall Here! *****");
index++;
}
}
}
---- UPDATE ----
Heres a better example in what I'm looking for. The red dots represent the coordinates coming in, a line is detected when 3 or more dots line up (if it was 2 dots, then it would detect any and ever dot) ... You notice that this is starting to look like the boarder of a square?
This seems to essentially be a clustering problem, and those can be generally pretty hard. Part of a reason clustering is hard is that there may be more than one applicable mapping.
For instance (please forgive my bad ascii art):
X X X
X X X
X X X X
could be mapped
X---X---X X X X
\ / \ / \
X---X---X or X X X
/ \ / \ \
X---X---X---X X X X X
I've seen uses of the Expectation Maximization algorithm using mixed Gaussian models used for this kind of thing (when there were a lot of points but only a few expected lines) but you generally do have to give that algorithm a definite number of clusters, and while its results are good, it's a pretty slow algorithm requiring possibly many iterations. I'm kinda thinking I've seen something generally faster that's some sort of image processing algorithm but I'd have to do some research.
I'm kinda wondering about something where you find y=mx+b for every pair of points and them sort them over m and b. It might be advantageous to find the angle θ in [0,pi) for each pair instead and sort over the angles instead of m, or maybe beter cluster by cos(2θ)-- the point of that being that the group of lines {y= -0.0001x + 1, y =1, and y=0.0001x + 1} are very similar, the group of lines {y= -10000x + 10, x = 0, and y=10000x - 10} are also very similar, but cos(2θ) should put them as far apart as possible, as any two pairs between each group should be nearly perpendicular.
Also note, in my example, b doesn't matter much for the lines nearly perpendicular to the x axis, so "b" might not be so useful for direct clustering.
I guess, perhaps, there may be some utilizable measure of "distance" between two lines, I'm just not sure what it would be. Two lines that are nearly parallel that converge "on screen" (where the points generally are) might ought to be considered "closer" than if they converge a trillion units a way from the screen--or should they? Purely speaking, three lines can never pairwise be considered closer to one another if none of them are parallel (If they're on a plane, they'll all meet somewhere), but intuitively, if we have two lines that are generally one inch apart in the area we're concerned with, we'd pick that pair as closer over two identically pointed lines that are a mile apart in the area of concern. That makes me think maybe the area between the lines,as bound by our area* ought to be used as a metric.
Sorry, I'm not sure how useful all that brainstorming might be, but it might put a different light on things.
Edit: You know what, a better answer might possibly be found by researching this:
http://en.wikipedia.org/wiki/Hough_transform
Edit II & III:
Ok,... the situation you've just described is a lot simpler and less generic (although, to be honest, I think I misread your initial query to be more generic than it really was).
You've got 4 candidate walls. Let your AI bounce around until it finds three co-linear points. That should be a simple test of combinations. Assign those three points a wall. Depending upon what other points you have, you actually might be able to determine or at least estimate the other three walls (assuming it is a square). If you have 5 points with 3 on separate walls, you should be able to calculate the distance between walls, and therefore the likely position of the 4th wall. To test if the other two points are on separate walls, make sure they're pair-wise not co-linear with a line perpendicular or parallel to the line defined by your wall, or if they are on a line parallel, test to see if the distance between them is less than the distance between the wall and them (if that's the case, they're on the wall opposite of the first candidate wall). Given that they are on separate walls, either one is facing the first found wall, or they're on walls perpendicular to that wall. Either way you can find the lines defining the walls with a little tricky geometry.
(and actually, to determine the dimensions, I don't think you need to even test to see that you have 3 co-linear points... I think you just need to test to see that you've made two turns... which takes 4 points minimum but likely more if you're unlucky. two of the points would have to be determinable to be on a different wall from the other two, which means really big bounces!)
There's a bit of math involved, and I'm a bit too tired to explain further tonight, and I don't know how much of the geometry of points around a square you want to take advantage of, because you wouldn't be able to use those properties in a more general case, so I'll leave it at that, and maybe also remove some of my other previous brainstorm cruft later.
If you have two points you can calculate the slope of the connecting line with Math.atan2.
currently i have using a framework and it has a function called distance2D, and it has this description:
Calculate the Euclidean distance
between two points (considering a
point as a vector object). Disregards
the Z component of the vectors and is
thus a little faster.
and this is how i use it
if(g.getCenterPointGlobal().distance2D(target.getCenterPointGlobal()) > 1)
System.out.println("Near");
i have totally no idea what a Euclidean distance is, i am thinking that it can be used to calculate how far 2 points are? because i am trying to compare distance between 2 objects and if they are near within a certain range i want to do something. how would i be able to use this?
Euclidean distance is the distance between 2 points as if you were using a ruler. I don't know what are the dimensions of your Euclidean space, but be careful because the function you are using just takes in consideration the first two dimensions (x,y). Thus if you have a space with 3 dimensions(x,y,z) it will only use the first two(x,y of x,y,z) to calculate the distance. This may give a wrong result.
For what I understood, if you want to trigger some action when two points are within some range you should make:
<!-- language: lang-java -->
if(g.getCenterPointGlobal().distance2D(target.getCenterPointGlobal()) < RANGE)
System.out.println("Near");
The Euclidean distance is calculated tracing a straight line between two points and measuring as the hypotenuse of a imaginary isosceles triangle between the two lines and a complementary point. This measure is scalar, so it's a good metric for your calculations.
Euclidean geometry is a coordinate system in which space is flat, not curved. You don't need to care about non-Euclidean geometry unless for example you're dealing with coordinates mapped onto a sphere, such as calculating the shortest travel distance between two places on Earth.
I imagine this function will basically use Pythagoras' theorem to calculate the distance between the two objects. However, as the description says, it disregards the Z component. In otherwords, it will only give a correct answer if both points have the same Z value (aka "depth").
If you wish to compare distances and save time, use not the distance itself, but its square: (x1-x2)^2 + (y1-y2)^2. Don't take sqrt. So, your distances will work exactly as euclidian ones, but quickly.