Collision of dot and line in 2D space - java

So I'm trying to make my first game on android. The thing is I have a small moving ball and I want it to bounce from a line that I drew. For that I need to find if the x,y of the ball are also coordinates of one dot from the line.
I tried to implement these equations about lines
x=a1 + t*u1
y=a2 + t*u2 => (x-a1)/u1=(y-a2)/u2 (t=t which has to be if the point is on the line)
where x and y are the coordinates I'm testing, dot[a1,a2] is a dot that is on the line and
u(u1,u2) is the vector of the line.
heres the code:
public boolean Collided()
{
float u1 =Math.abs(Math.round(begin_X)-Math.round(end_X));
float u2 =Math.abs(Math.round(begin_Y)-Math.round(end_Y));
float t_x =Math.round((elect_X - begin_X)/u1);
float t_y =Math.round((elect_Y - begin_Y)/u2);
if(t_x==t_y)
{
return true;
}
else
{
return false;
}
}
points [begin_X,end_X] and [begin_Y,end_Y] are the two points from the line and [elect_X,elect_Y] are the coordinates of the ball
theoretically it should work, but in the reality the ball most of the time just goes straight through the line or bounces somewhere else where it shouldn't

I'm not sure what your code is doing, but looks weird
you do some operations on x coordinates of your data, then on y, and at the end you want them to be equal;
go and try hereShortest distance between a point and a line segment and then if distance == 0 (or smaller on equal to radius of your ball) you will have collision

The issue lies in the fact that you're testing whether the dot 'hits' the line that you want it to bounce from. I'm assuming that you're incrementing the position of your dot every frame with a small amount.
Say your dot is placed at [1,1], your line runs from [0,0] to [5,0], the velocity of your dot is 1 unit per second and the direction is [-1,0]. I'm assuming your calculating the increment based on the time per frame to allow for smoother animation.
What's happening is the following:
Dot at [1,1]
Time per frame = 0,7
Dot is moved to [0.3,0]
Test intersection = false
--- next frame ---
Dot at [0.3,0]
Time per frame = 0.5 (this usually varies per frame)
Dot is moved to [0.2,0]
Test intersection = false
So the tests say there hasn't been an intersection because your testing discrete positions of your dot.
As Aki Suihkonen suggests you want to test for line intersection between a line formed by the last position + the current position and the line that you want your dot to collide with.
java.awt.geom.Line2D.linesIntersect(double X1, double Y1, double X2, double Y2, double X3, double Y3, double X4, double Y4) allows you to check for these intersections easily.

Your math is OK, but you the code isn't.
It's simpler to use the genearl line equation y = y1 + a(x - x1) where a = (y2 - y1) / ( x2 - x1) , being (x1,y1) and (x2,y2) to points from the line.
To get ball the distance from the line when the ball is at point (bx,by)use:
double a = (y2 - y1) / (x2 - x1);
double distance = (by - y1 - a * (bx - x1)) * Math.cos(Math.atan(a));
Now you can compare if Math.abs(distance) is bellow a specific value (i.e. ball diameter) to confirm collision.
Note: this only works for non vertical lines. If you have a vertical line just use:
double distance = bx - x1;
good luck.

Related

How to check if a line lies between a prism

If I have 2 points in 3d space how can I determine if a rectangular prism lies between those 2 points? Also the only information I have about the the rectangular prism is its min and max x, y, and z value. I know I could iterate down the line between those 2 points checking to see if that point is within the rectangular prism but that seems very resource heavy. What I really need is a way to check if a line segment intersects the prism but I am not sure how to do that any ideas?
I found these two resources that seem similar to my question
https://math.stackexchange.com/questions/2134505/how-to-check-if-an-infinite-line-intersects-a-rectangular-prism-in-3d-space
How to check if an infinite line intersects a rectangular prism in 3d space?
Looking at that bottom link it just simply says to find parameters t that intersects the rectangular prism which is obvious but the problem is I dont know how to do that any thoughts?
project your line points and prism edges onto 2D plane that is perpendicular to your line.
On the 2D plane, the two points of line will be just one point and prism edges is just a bunch of connected vertices forming a closed region. check if the one point is within the closed region, this will be easy to do for 2D.
If your point is within then the line intersects the prism in 3D, if not then no.
now there is a case where it is a line segment where the two ends don't touch the prism. In this case you just check point to prism surface distance, there is a equation for that.
Let line segment is defined by two points (X1, Y1) and (X2, Y2).
Let box is defined by ranges xmin..xmax, ymin..ymax, zmin..zmax.
We can write parametric eqiation for line segment, where t is in range 0..1:
X = X1 + t * (X2 - X1)
Y = Y1 + t * (Y2 - Y1)
Z = Z1 + t * (Z2 - Z1)
Box has 6 facets. Let the first one is at xmin. We can substitute xmin in the first equation and find parameter t where line intersects this facet.
xmin = X1 + t1 * (X2 - X1)
t1 = (xmin - X1) / (X2 - X1)
Now check that t1 is in range 0..1. If yes, substitute this t1 value in the second and third equations
Y = Y1 + t1 * (Y2 - Y1)
Z = Z1 + t1 * (Z2 - Z1)
and check that resulting Y and Z lie in ranges ymin..ymax and zmin..zmax respectively.
If yes - line segment does intersect the box
If no, repeat for other faces xmax, ymin and so on.
P.S. Also you can consider special case when line segment is fully inside the box (just check if X1,Y1,Z1 is in box range)
P.P.S. When line is parallel to some coordinate plane, don't check intersections with corresponding faces (for example, if X2-X1==0, you cannot divide by zero, but you just don't need check xmin and xmax faces)
Quick-made Python-like pseudocode for reference:
def DoesSegmentIntersectBox(x1,y1,z1,x2,y2,z2,xmin,xmax,yin,ymax,zmin,zmax):
if zmin<=z1<=zmax and ymin<=y1<=ymax and xmin<=x1<=xmax:
return True #end inside the box
if (x2-x1):
t = (xmin-x1) / (x2-x1)
if 0<=t<=1: #line intersects plane in segment range
y = y1+t*(y2-y1)
if ymin<=y<=ymax: #segment intersects face in y range
z = z1+t*(z2-z1)
if zmin<=z<=zmax: #segment intersects face in z range
return True #segment does intersect face xmin
t = (xmax-x1) / (x2-x1)
#same 6 lines
if (y2-y1):
t = (ymin-y1) / (y2-y1)
if 0<=t<=1:
x = x1+t*(x2-x1)
if xmin<=x<=xmax:
z = z1+t*(z2-z1)
if zmin<=z<=zmax:
return True
t = (ymax-y1) / (y2-y1)
#same 6 lines
if (z2-z1):
t = (zmin-z1) / (z2-z1)
if 0<=t<=1:
x = x1+t*(x2-x1)
if xmin<=x<=xmax:
y = y1+t*(y2-y1)
if ymin<=y<=ymax:
return True
t = (zmax-z1) / (z2-z1)
#same 6 lines
return False

java intersecting 2dobject

So I have made the following game:
The player moves around freely and shoot bullets which bounce off the walls . I am trying to implement auto aiming. I have tried to implement this using lines, which go around the player.
Now what I am having problems with is calculating where the lines intersect with the walls. I am unsure of how to do this.
I can't use getBounds() as the lines are not 2DRectangles. If anyone has any idea on how I can calculate where the lines intersect with a wall, and return that position, it would be very helpful.
You just need to do the math here.
Suppose your line has start at (startX, startY) and end at (endX, endY). Then using basic grade-school geometry, any point (x,y) on the line satisfies the equation
(y-startY) / (x-startX) = (endY - startY) / (endX - startX)
Of course,
(endY - startY) / (endX - startX)
is just the slope of the line, so set
slope = (endY - startY) / (endX - startX)
and then you have
(y-startY) / (x-startX) = slope
This might be more convenient if you know the starting point (startX and startY for the line) and the angle, as you can just do slope = Math.tan(angle).
For the example of the intersection with a horizontal wall, all points on the edge of the wall have the same y-coordinate, call it wallY. So if x is the x-coordinate of the intersection, you have
(wallY-startY) / (x-startX) = slope
which you can rearrange to
x = startX + (wallY-startY) / slope
so the intersection point is (x, wallY) with x as in the last equation.
If the wall is finite (i.e. it has start and end x points), then the check to see if the line actually intersects the wall is simply x >= wallStartX && x <= wallEndX, assuming wallStartX is the left end of the wall and wallEndX the right end.
If the wall is vertical, then the math is basically the same, except you know the x coordinate on the wall (say x = wallX), and you want to find the y coordinate. So just substitute wallX for x in the first (or fourth) equation and solve for y.
If the wall is not horizontal or vertical, then the math is a little more complicated, though not much. (Left as an exercise for the reader.)
You can use the well tested JTS library for doing such things.

Drawing a circle in a turtle program

I am currently working on a Processing (as in the language) sketch, which is driven by Turtle logic (see https://en.wikipedia.org/wiki/Turtle_graphics). This means that I draw a line from the current coordinate to a supplied coordinate. This supplied coordinate will then become the new current coordinate. I want to approximate a circle and have written a simple piece of code using trigonometrics. The code looks as follow:
void drawCircle(int radius){
// The circle center is radius amount to the left of the current xpos
int steps = 16;
double step = TWO_PI /steps;
for(double theta = step; theta <= TWO_PI; theta += step){
float deltaX = cos((float)theta) - cos((float)(theta - step));
float deltaY = sin((float)theta) - sin((float)(theta - step));
moveXY(deltaX*radius, deltaY*radius);
}
}
The program logic is simple. It will use the variable theta to loop through all the radians in a circle. The amount of steps will indicate how large each theta chunk is. It will then calculate the x,y values for the specific point in the circle governed by theta. It will then deduct the x,y values of the previous cycle (hence the theta-step) to get the amount it will have to move from this position to attain the desired x,y position. It will finally supply those delta values to a moveXY function, which draws a line from the current point to the supplied values and makes them the new current position.
The program seems to work quite well when using a limited amount of steps. However, when the step count is increased, the circles become more and more like a Fibonacci spiral. My guess is that this is due to imprecision with the float number and the sine and cosine calculations, and that this adds up with each iteration.
Have I interpreted something wrong? I am looking to port this code to Javascript eventually, so I am looking for a solution in the design. Using BigDecimal might not work, especially since it does not contain its own cosine and sine functions. I have included a few images to detail the problem. Any help is much appreciated!
Step count 16:
Step count 32:
Step count 64:
Step count 128:
Float and sine/cosine should be sufficiently precise. The question is: How precise is your position on the plane? If this position is measured in pixels, then each of your floating point values is rounded to integer after each step. The loss of precision then adds up.
At each iteration round the loop, you are calculating the delta without regard of what the current coordinate is. So effectively, you are "dead-reckoning", which is always going to be inaccurate, since errors at each step build up.
Since you know that you want a circle, an alternative approach would be at each iteration, to first determine the actual point on the circle you want to get to, and then calculate the delta to get there - so something like the following (but I must admit I haven't tested it !):
void drawCircle(int radius){
// The circle center is radius amount to the left of the current xpos
int steps = 16;
double step = TWO_PI /steps;
float previousX = 0;
float previousY = radius;
for(double theta = step; theta <= TWO_PI; theta += step){
float thisX = radius * sin((float)theta);
float thisY = radius * cos((float)theta);
moveXY(thisX - previousX, thisY - previousY);
previousX = thisX;
previousY = thisY;
}
}

Java Scanline fill

I am currently developing an application and want to understand the core principles of computer graphics. I was wandering if anyone can provide a formula to check if a point in three variables (x,y,z) intersects a line that consist of two points (x1,y1,z1) and (x2,y2,z2)
Say if you wanted to find if point0 =(x0,y0,z0) intersects line which cross at point1=(x1,y1,z1) and point2 = (x2,y2,z2).
Formula to check if point0 lies on line (point1->point2) would be to check if (X0,y0,z0) = (x1,y1,z1) + t(x2-x1,y2-y1,z2-z1).
For any value of t that is constant for x , y and z axes.
so
x0 = x1 + t(x2-x1)
y0 = y1 + t(y2-y1)
etc..

Algorithm to detect the point intersect the semi circle in android Java [duplicate]

This question already has answers here:
What algorithm can I use to determine points within a semi-circle?
(11 answers)
Closed 8 years ago.
I have a points x and y and I need to check the point which intersect within a semi- pie.
I need an algorithm to find the point is intersect in the semi circle. for rectangle we have point contains method to check the point intersect the rectangle, but this doesn't work for semi circle segments with start and end angle.
I have created many semi pie segment, when I touch the pie segment, I need to check the point intersect of which segment.
I'm assuming this is speed-critical, and also that you want to be able to specify the semi-circle as having a center and arbitrary start and end angles, so not just a semi-circle but a circular sector. For a semi-circle just make the start and end angles 180 degrees apart, or remove the test against endVector.
Make the test a two-step process. For a given point, first check that it is inside a rectangle enclosing the semi-circle. You can use your existing sort and binary search algorithm for this. If a point is not in the rectangle then reject the point, if it is then test against the semi-circle.
Also, outside of the loop, convert the values specifying the semi-circle into a form that will enable the tests to be done faster:
Convert the radius to radius squared. Compare the distance of a point from the center squared, to the radius squared. This saves a square root when computing the distance.
Convert the start and end angles of the semi-circle to a couple of 2D vectors, and then use these to check whether the point is inside the sector. Then you won't have to use any trig functions like atan2(y, x), which are slow, or do annoying fiddly comparisons to start and end angles and handling the case where angles wrap around from 360 to 0.
pseudo code:
float radiusSquared;
float startVectorX;
float startVectorY;
float endVectorX;
float endVectorY;
float centerX;
float centerY;
void convertSector(float radius, float startAngle, float endAngle)
{
radiusSquared = radius * radius;
startVectorX = cos(startAngle);
startVectorY = sin(startAngle);
endVectorX = cos(endAngle);
endVectorY = sin(endAngle);
}
boolean testPoint(float x, float y)
{
// check if point is within the radius:
float distanceX = x - centerX;
float distanceY = y - centerY;
if((distanceX * distanceX) + (distanceY * distanceY)) > radiusSq)
return false;
// check if point is outside start radius vector using 2D dot-product with normal:
if(((distanceX * -startVectorY) + (distanceY * startVectorX)) < 0.0f)
return false;
// check if point is outside end radius vector using 2D dot-product with normal:
if(((distanceX * -endVectorY) + (distanceY * endVectorX)) > 0.0f)
return false;
return true;
}
The above code will only work for sectors with an internal angle of <= 180 degrees. To test a point against sectors larger than that (i.e. Pac-Man like shapes), test if the point is inside the circle and then test that it is not inside the sector making up the remainder of the circle.

Categories

Resources