Using a QuadTree to get all points within a bounding circle - java

I have a set of 100 to 200 points (x,y). I have to check which ones fall within a particular distance of the others. The particular distance is fixed for the entire program, say 50. Say point 1 falls within the range of points 5,7,25,90,96,105...etc. Similarly point 2 falls within range of 23,45, etc...
Storing objects for locating by x,y coordinates
Here QuadTree is suggested, but it can be used to get all the points within a bounding rectangle. But how to get all points within a bounding circle? there is a method which returns a point closest to a lat/long within a maximum distance, but how to get all the points within the distance?
http://openmap.bbn.com/doc/api/com/bbn/openmap/util/quadtree/QuadTree.html#QuadTree(float, float, float, float, int)
one way maybe to remove each point from the tree as I get it, then query for the closest point again, until i get null. is that the only way?

Suppose that you have a circle centered at (x, y) with radius r and want to find all points in a quadtree that are in the circle. One idea is as follows:
Construct the bounding box inscribing the circle. This is the smallest rectangle containing the circle, which has upper-left corner (x - r, y - r) and lower-right corner (x + r, y + r). Any point in the circle must also be in the square, but not the other way around.
Query the quadtree for the set of points lying in that rectangle. Let these points be P.
For each point in P which is known to be in the rectangle, see if it is also in the circle. You can do this by checking whether the distance from that point to (x, y) is no greater than r. In other words, given a point (x0, y0), you would compute (x - x0)2 + (y - y0)2, and if this value is less than or equal to r2, then the point is contained in the circle.
Although this may seem inefficient, it's actually quite fast. The ratio of the area of the square to the area of the circle is 4 / π ≈ 1.27. In other words, assuming that your points are distributed somewhat evenly, you'll only find about 27% more points than you need to.

Related

How to find the corresponding subtriangle of a position inside a rectangle

I have a dynamic rectangle in which 4 subtriangles (t0-t3) are created (by adding the diagonals from the vertices). When given a certain x|y coordinate what is the fastest way to find the corresponding triangle?. The rectangle has a specific position and dimension. I only need the right "id" so not the vertices of the triangle, so for example in the graphic when p1 is given as position 0 should be returned, 3 at p2 and 2 at p3, ...
One possible solution of course would be to create the triangles and query if the point is contained in one of them, but it feels like a very complicated solution for something that simple.
I also thought about creating a vector from the center and measuring the angle but it also seems complicated in a rectangle with varying dimensions.
Example Rectangle
Consider the following:
Let the bottom left corner of the rectangle be (0,0) and the top right corner be (1,1). Now, the two lines that form the triangles are defined as:
y = x and y = 1-x
For every point except (.5,.5) we have a ternary conditional for a given x or y. For example, given that x = .2, we know that:
if y < .2, we're in the bottom triangle (t2),
elif .2 < y < .8, we're in the left triangle (t3),
else, we're in the top triangle (t0).
Hopefully this helps without explicitly giving you the code.

Java: plot points based on distances

I need to plot a group of points based on distances. I have three unknown points X, Y, and Z. I then get another unknown point (A) and its distances from the originals (AX, AY, AZ). I will continue getting points and distances (B, BX, BY, BZ; C, CX, CY, CZ) etc.
My question is whether its possible to plot all of the points. If so, how many points would I need for an exact plot map? What about an approximate map?
This is similar to this question but I get a different set of distances and am not limited to the original number of points.
Also, if it would help I could add more points to the X, Y, Z group which would give me more distances for A, B, etc.What I don't know until it's been somehow calculated are any of the Distances XY, XZ, YZ, AB, AC, etc.
I am not sure exactly what you mean by exact plot map or approximate plot map. I think I might know but I am not sure. But plotting all points in this case, to me is not possible if the user can continue to "add more points to the XYZ group", which is dynamic. It would sound like you need to know what the user is going to plot before he does. Now if all this is static, it is possible
I assume you use 2D space
If it is 1D then 2 points are enough (not identical !!!).
If 2D then 3 distances is enough but the points used must not lay on the same line !!!
position/orientation of the plot
for relative plot are above conditions enough if you want also the exact orientation and position then you need to know exact position of first 3 points otherwise your plot will look the same but can be offseted,rotated and mirrored to original geometry.
knowing 1 point eliminates offset
knowing 2 point eliminates rotation
knowing 3 point eliminates mirroring
[notes]
you need n+1 points for n-D coordinate system
[edit1] equations
original question text did not contain any equations need but comments requires it so here are some:
You will need intersection point between two hyperspheres (in 2D circles, in 3D spheres,...) so look here:
circle-circle intersection
Cast circle from each point as center with radius equal to the distance from that point. Find out intersection point that is the same between all combinations of circles (0,1),(0,2),(1,2)
Yellow intersection is the same in all 3 combinations so that is the next point or for 2D just solve this system:
(x-x0)^2+(y-y0)^2=l0^2
(x-x1)^2+(y-y1)^2=l1^2
(x-x2)^2+(y-y2)^2=l2^2
where x,y is the intersection point, xi,yi are center of circle and li is distance from that point.
The first option should be simpler and more accurate if done right but need some knowledge on vector and trigonometry math. You will need to add rotation or compute on vectors and use perpendicular vector feature in 2D
V(x,y) -> V0(+y,-x),V1(-y,+x)
where V0,V1 are perpendicular to V

How can I rotate the CannonBall around the ship?

Sorry about the bad title, but I could not think of anything else.
Let me explain: I have got 2 ships. The ship in the collision world, and the ship in the real world.
Now the ship in the real world is rotating, however I am unable to rotate the ship in the collision world (Or move it), which means that the collision objects must be rotated around the ship in the collision world.
When a CannonBall is near the ship, I get the distance from the CannonBall to the ship (for x, y, and z) and then compare that to a triple array of coordinates which are the collision points (About 2000+) - If the result from the triple array is "1", then they have collided. In other words, the collision ship does not move, but in the collision code the CannonBall's location is the same as the distance to the real-world ship and the real-world CannonBall.
Now here is the problem: If the ship is rotated, I need to rotate the CannonBall around the ship, because the ship cannot rotate.
How would I do this? What sort of mathematical formula?
Note: I have - Ship's rotation, x, y, and z coordinates, and the CannonBall's x, y, and z coordinates.
Thanks if anybody can give me an answer!
Edit: Lets make this more clear.
In the real world, ship1 could fire a CannonBall at ship2. If I refer to "The ship", I mean ship2.
When the CannonBall gets near to the ship, I want it to check for collisions. To do this,(Physics world) I check if array[CannonBall.distance(ship).x][CannonBall.distance(ship).y][CannonBall.distance(ship).z] returns a "1", and if it does, it collides.
However, because I cannot change an array without a large amount of processing, I cannot change the ship's rotation. Therefore, I must rotate the CannonBall around it so that it is relative to the CannonBall's true rotation compared to the ship.
If I got you right, then you are having a ship (e.g. in the middle of the screen) that has a canon ball rotating around it in order to aim towards another ship that is movable. All of that in 3D(?). Assuming that is what you mean, here is an answer ;) :
Lets do that in a 2 Dimensional Space first. What you need first is a formula to calculate a circle. As a function can only have one y-Value for each x-Value, you will actually need two. The smartest thing to do would probably divide the direction your canon ball is facing from the static ship into the common 360°, then have the formula calculate x and y coordinates. One approach could work with the formula for a circle (+/-r²=x²+y², with r being the radius), but I think a approach with cos and sin would be easier. Therefore:
You might want to have an input of an angle. If this angle is 90°, then your cannon ball is to the right of the ship. 180° would be underneath your ship, and 270° to the left, 0°/360° would be above. I would then take that input and add 90° to it, so that you can start to the left of your ship (IMPORTANT for cos and sin to work!). What we know now is the angle of the cannon ball, and the radius of the circle. Assuming that you know the coordinates of the middle of the ship, you can then imagine yourself in a coordinate system, with your ship being the origin. Now you need to calculate x. This can be done by:
x = -cos^-1(ANGLE)*radius. The result will be your x-Coordinate, that you have to subtract from the middle of the ship coordinate. Then, with x and the Angle being known, you can calculate y= x/tan-1(ANGLE). If the original angle is greater then 90°, you have to multiply the y coordinate with -1.
The method for this would be:
public void calculateCordinates(int degrees, int r){
degrees = degrees+90;
while(degrees>=360){degrees=degrees-360;}//ensures that degree < 360°
double x;
double y;
x = Math.acos(Math.toRadians((double)degrees))*r;
y = x/Math.atan(Math.toRadians((double)degrees));
}
The Coordinates are now in double as the results are most of the time not going to be whole numbers. Round them to ints before you subtract them from the origin coordinates.
If you want to do this in 3D, you can calculate the y coordinate by using the same method. This time, the angle you enter is your 3rd Dimension angle, so "the angle that you look at as in into the screen, out of the screen, with your right ear on the screen and so on" (sorry, didn't know how to describe that better). Of course you can combine the Methods to one as well, would look something like that:
public void calculateCordinates(int degrees, int degrees3D, int r){
degrees = degrees+90;
while(degrees>=360){degrees=degrees-360;}
double x;
double y;
double z;
x = Math.acos(Math.toRadians((double)degrees))*r;
y = x/Math.atan(Math.toRadians((double)degrees));
z = x/Math.atan(Math.toRadians((double)degrees3D));
}
I hope this is what you asked for, and I hope it helps!

Collision Handling... Confused where to go

So, I'm working on a 2D physics engine, and I have an issue. I'm having a hard time conceptualizing how you would calculate this:
Take two squares:They move, collide, and at some vector based off of the velocity of the two + the shape of them.
I have two vector lists(2D double lists) that represent these two shapes, how does one get the normal vector?
The hit vector is just (s1 is the first shape, s2 the second) s2 - s1 in terms of the position of the center of mass.
Now, I know a normal vector is one perpendicular to an edge, and I know that you can get the perpendicular vector of a line by 90 degrees, but what edge?
I read in several places, it is the edge a corner collided on. How do you determine this?
It just makes no sense to me, how you would mathematically or programmatically determine what edge.
Can anyone point out what I'm doing wrong in my understanding? Sorry for providing no code to explain this, as I'm having an issue writing the code for it in the first place.
Figure1: In 2D the normal vector is perpendicular to the tangent line:
Figure2: In 3D the normal vector is perpindicular to the tangent plane
Figure3: For a square the normal vector is easy if you are not at a corner; It is just perpendicular to the side of the square (in the image above, n = 1 i + 0 j, for any point along the right side of the square).
However, at a corner it becomes a little more difficult because the tangent is not well-defined (in terms of derivatives, the tangent is discontinuous at the corner, so perpendicular is ambiguous).
Even though the normal vector is not defined at a corner, it is defined directly to the left and right of it. Therefore, you can use the average of those two normals (n1 and n2) as the normal at a corner.
To be less technical, the normal vector will be in the direction from the center of the square to the corner of the collision.
EDIT: To answer the OP's further questions in the chat below: "How do you calculate the normal vector for a generic collision between two polygons s1 and s2 by only knowing the intersecting vertices."
In general, you can calculate the norm like this (N is total verts, m is verts inside collision):
vcenter = (∑N vi) / N
vcollision = (∑m vi) / m
n = vcollision - vcenter
Fig. 1 - vcollision is only a single vertex.
Fig. 2 - vcollision is avg of two verts.
Fig. 3 - vcollision for generic polygon intersection.

How to calculate the lat/lng of a point a certain distance from another point?

consider having a circle on map with center GLatLng (A) and a radius (r) in meters.
How to calculate the GLatLng at position B? Assuming that r is parallel to the equator.
Getting the radius when A and B is given is trivial using the GLatLng.distanceFrom() method - but doing it the other way around not so.
to summarize, given Lat/lng of Point A and R in meters, I need to get Lat/Lng of Point B. direction is not important.
All you need to do is take the original point and compute the distance for one degree to the east or west. That will give you the distance per degree along that line of latitude. Then divide r by the distance per degree and it will tell you how many degrees B is to the east or west.

Categories

Resources