So I'm creating a class and have to determine if two circles are overlapping based on their distance. This is what I have:
Circle a = other;
Circle b = other;
double xDist = a.getX() - a.getX();
double yDist = b.getY() - b.getY();
double radi = a.getRadius() + b.getRadius();
double distance = Math.sqrt((xDist*xDist) + (yDist*yDist));
if((distance < radi * radi)) {
return true;
} else {
return false;
}
My process is that if the distance of the centers is less than the sum of their radii, then the circles overlap.
Your error is that you're trying to compare the distance with the square of the sum of the radii. You want to compare the distance with the sum of the radii.
Alternatively, you could compare the square of the distance to the square of the sum of the radii, which would remove the need to use Math.sqrt.
Note also that there's no point in having variables a and b, when you've already got this and other to refer to the two discs. In fact, you've incorrectly made a and b both refer to other. You could fix this as follows.
public boolean overlaps(Disk other) {
double xDistance = getX() - other.getX();
double yDistance = getY() - other.getY();
double sumOfRadii = getRadius() + other.getRadius();
double distanceSquared = xDistance * xDistance + yDistance * yDistance;
boolean isOverlapping = distanceSquared < sumOfRadii * sumOfRadii;
return isOverlapping;
}
Change 2 things:
Circle a = this; // "this" instead of "other"
and remove the call to Math.sqrt()
Related
I am trying to understand why I am having a difficult time calling two different points into a method in order to determine the distance between the two points.
This is the text provided on the website "Practice-It", where I am currently working through problems:
Add the following method to the Point class:
public double distance(Point other)
Returns the distance between the current Point object and the given other Point object. The distance between two points is equal to the square root of the sum of the squares of the differences of their x- and y-coordinates. In other words, the distance between two points (x1, y1) and (x2, y2) can be expressed as the square root of (x2 - x1)2 + (y2 - y1)2. Two points with the same (x, y) coordinates should return a distance of 0.0."
I have tried multiple ways to get the points into the method without naming individual coordinates. I believe that I am only getting the coordinates of the first point and am trying to understand where I am going wrong as I've had this problem before. I realize that the "int x1 = p1.x", etc. is redundant and I could just type "p1.x" in the return, but I am wanting to see all of the moving parts individually. Thanks for your consideration and help.
public double distance(Point other){
Point p1 = new Point();
int x1 = p1.x;
int y1 = p1.y;
Point p2 = new Point();
int x2 = p2.x;
int y2 = p2.y;
return Math.sqrt(Math.pow(x * x2, 2) + Math.pow(y * y2, 2));
}
This is my result from one of the situations tested:
test #1:(5, 2) to (8, 6)
expected output:
5.0
5.0
your output:
0.0
0.0
differences:
1,2c1,2
< 5.0
< 5.0
> 0.0
> 0.0
result: fail
Your comparison logic is off. Assuming that distance() is a method inside the Point class, then you should be comparing the x,y values of the incoming other point against the x,y value in the class:
public double distance(Point other) {
int x1 = other.x;
int y1 = other.y;
return Math.sqrt(Math.pow(this.x * x1, 2) + Math.pow(this.y * y1, 2));
}
Note that is would be more ideal to provide getters for the x and y fields in Point. Here is a more complete suggested refactor:
public class Point {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() { return x; }
public int getY() { return y; }
public double distance(Point other) {
int x1 = other.getX();
int y1 = other.getY();
return Math.sqrt(Math.pow(this.x * x1, 2) + Math.pow(this.y * y1, 2));
}
}
I'm trying to check if triangle2D is contain another triangle or overlapping it.
I can do that with circle e.g:
/** Return true if the specified point
* (x, y) is inside this circle */
public boolean contains(double x, double y) {
return Math.sqrt(Math.pow(x - this.x, 2) +
Math.pow(y - this.y, 2))
< radius;
}
/** Return true if the specified
* circle is inside this circle */
public boolean contains(Circle2D circle) {
return Math.sqrt(Math.pow(circle.getX() - x, 2) +
Math.pow(circle.getY() - y, 2))
<= Math.abs(radius - circle.getRadius());
}
/** Return true if the specified
* circle overlaps with this circle */
public boolean overlaps(Circle2D circle) {
return Math.sqrt(Math.pow(circle.getX() - x, 2) +
Math.pow(circle.getY() - y, 2))
<= radius + circle.getRadius();
}
But I don't know how to do that with triangle.
I've found this question for point only, but I don't how to do that if triangle contain other triangle or overlapping it.
You can use Line2D#contains, Line2D#linesIntersect methods inside java.awt.geom.Line2D.
Edit:
Thinking in Math:
To detect whether a point is inside a triangle, draw three dashed lines, if the point is inside a triangle, each dashed line should intersect a side only once. if a dashed line intersect a side twice, then the point must be outside the triangle.
So We can use the way in the other question (you mentioned) like below:
public boolean contains(MyPoint p) {
// double area1 = calcArea(p, p1, p2);
// double area2 = calcArea(p, p2, p3);
// double area3 = calcArea(p, p3, p1);
// double area = Math.round((area1 + area2 + area3) * 100) / 100;
// double triangleArea = Math.round(getArea() * 100) / 100;
// return (triangleArea == area)
}
But it's not efficient way, so we will implement it as below, in order to reuse it with other cases.
We should have three methods one for check max x, y, one for checking min x, y and other for checking the lineSegment.
The lineSegment would be look like:
double position = (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0);
return position <= 0.0000000001 && ((x0 <= x2 && x2 <= x1) || (x0 >= x2 && x2 >= x1));
/**
* returns true if the specified point is inside this triangle
**/
public boolean contains(MyPoint p) {
return contains(p.getX(), p.getY());
}
public boolean contains(double x, double y) {
// Get max X & Y
double maxX = getMax(p1.getX(), p2.getY(), p3.getX());
double maxY = getMax(p1.getY(), p2.getY(), p3.getX());
// Get min X & Y
double minX = getMin(p1.getX(), p2.getX(), p3.getX());
double minY = getMin(p1.getY(), p2.getY(), p3.getY());
// Outside the bounding rectangle of the triangle
if (x < minX || x > maxX || y < minY || y > maxY) return false;
// Check if point is the border of the triangle
MyPoint p = new MyPoint(x, y);
boolean side1 = p.onTheLineSegment(p1, p2); //assume A to B
boolean side2 = p.onTheLineSegment(p1, p3); //assume B to C
boolean side3 = p.onTheLineSegment(p2, p3); //assume C to A
return side1 || side2 || side3; //return true if any point of these vertices inside triangle.
}
So to check if triangle contain other one, our method would be look like:
public boolean contains(Triangle t) {
return contains(t.p1) && contains(t.p2) && contains(t.p3); //All three points is inside the triangle
}
Or simply by using Line2D class as I mention above:
Line2D line2D = new Line2D.Double(p1.getX(), p1.getY(), p2.getX(), p2.getY());
return line2D.contains(....); //check if contain triangle or point
For the case of containing you can check all vertices of a triangle. If all of them are existed inner of the other, one of them contains the other one.
For the case of overlapping, You should consider is there any intersection between any edge of these two triangle or not. If there is not and the containing case was not happened, they are separated. For the case of intersecting two edges (as two segments) on the plane, you can using this post.
Use the LeftOf predicate, which is true when the algebraic area of the triangle ABC is positive (using the appropriate sign convention), telling you that C is on the left of the line AB.
Then check if all three vertices of the first triangle lie left of some side of the second one. If not, repeat after exchanging the two triangles.
Finally if yes, the triangles do not interfere.
I want to get the Point where a Polygon and a Line collides. I know there is a class called Intersector, but in this there is only a method for checking wether they collide or not, but I need the point where they are colliding.
I am happy with any help
public static List<RayTrace> rayTrace(Line2D line, boolean quick, Collisions... collisions) {
List<RayTrace> l = new ArrayList<RayTrace>();
for (Collisions collisions1 : collisions) {
for (Collision3D collision3D : collisions1) {
RayTrace rayTrace = new RayTrace();
if (quick) {
if (Intersector.intersectLinePolygon(line.getStartV(), line.getEndV(), collision3D.getBoundingPolygon())) {
rayTrace.collisionHit = collision3D;
rayTrace.hasHit = true;
l.add(rayTrace);
}
} else {
Point2f hit = new Point2f();
if (CollisionHelper.getLinePolygonIntersection(collision3D.getBoundingPolygon(), line, hit)) {
rayTrace.collisionHit = collision3D;
rayTrace.hasHit = true;
rayTrace.hitX = hit.x;
rayTrace.hitZ = hit.y;
l.add(rayTrace);
}
}
}
}
return l;
}
public static List<Vector2> getLinePolygonIntersections(Polygon polygon, Line2D line) {
float f[] = polygon.getTransformedVertices();
//Go through every side
List<Vector2> intersections = new ArrayList<Vector2>();
for (int i = 0; i < f.length - 2; i += 2) {
Vector2 intersection = new Vector2();
Intersector.intersectLines(line.x, line.y, line.x2, line.y2, f[i], f[i + 1], f[i + 2], f[i + 3], intersection);
intersections.add(intersection);
}
return intersections;
}
public static boolean getLinePolygonIntersection(#NotNull Polygon polygon, #NotNull Line2D line, #NotNull Point2f point) {
List<Vector2> list = getLinePolygonIntersections(polygon, line);
if (list.size() == 0) return false;
double shortestDistance = line.getStart().distance(new Point2f(list.get(0).x, list.get(0).y));
int indexClosest = 0;
for (int i = 1; i < list.size(); i++) {
double d = new Point2f(list.get(i).x, list.get(i).y).distance(line.getStart());
if (shortestDistance > d) {
indexClosest = i;
shortestDistance = d;
}
}
point.set(list.get(indexClosest).x, list.get(indexClosest).y);
return true;
}
Here is the method from the LibGDX Intersector class that could be modified:
public static boolean intersectLinePolygon (Vector2 p1, Vector2 p2, Polygon polygon) {
float[] vertices = polygon.getTransformedVertices();
float x1 = p1.x, y1 = p1.y, x2 = p2.x, y2 = p2.y;
int n = vertices.length;
float x3 = vertices[n - 2], y3 = vertices[n - 1];
for (int i = 0; i < n; i += 2) {
float x4 = vertices[i], y4 = vertices[i + 1];
float d = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
if (d != 0) {
float yd = y1 - y3;
float xd = x1 - x3;
float ua = ((x4 - x3) * yd - (y4 - y3) * xd) / d;
if (ua >= 0 && ua <= 1) {
return true;
}
}
x3 = x4;
y3 = y4;
}
return false;
}
What this method is actually doing is finding the intersection between the line segment from p1 to p2 with the edge of the polygon. (In particular, it is determining if there is any intersection between the given line segments, which will be important later.) In particular, the computations are being performed on the parametric equation of these two line segments; for example, the line segment from (x1,y1) to (x2,y2) has parametric equation
L(t) = [ x2-x1, y2-y1 ] * t + [ x1, y1 ]
where t ranges from 0 to 1.
The intersection of the the lines is calculated using Cramer's rule; the variable d above represents the determinant of the matrix appearing in the denominator of that formula. When d is nonzero, there is guaranteed to be an intersection between the lines, but we aren't done yet, because we are interested in the intersection of the line segments. The variable ua in the method yields the value of t in the parametric equation above when the intersection occurs; it must be between 0 and 1 for the intersection point to lie between the endpoints of the line segment.
Thus, the coordinates of the point of intersection can be calculated by evaluating L(t) when t = ua. To find the point of intersection, therefore, you could create your own version of this function that returns the value
Vector2( (x2-x1)*ua + x1, (y2-y1)*ua + y1)
Hope this helps!
IMHO: In the Intersector class many methods calculate collisions and generally the last parameter is a Vector3 filled with the coordinates of the collision.
I've never used this library, but at first glance, it's the way it works.
I want to check if the ball and a specific line (zijde) collide. I want to do this by making the line function of the line. Than check if the coordinates that come out of the function are equal to the ball's coordinates. This is the code i'm using so far and I don't know what I'm doing wrong. Zijde z is the line that the ball needs to collide with and has the functions getStartPoint (getStartPunt) and getEndPoint (getEindpunt).
public Boolean CheckCollision(Zijde z)
{
/**
* y = ax + b
* a = delta y / delta x
* b = y - ax
*/
double deltay = z.getEindpunt().getY() - z.getStartPunt().getY();
double deltax = z.getEindpunt().getX() - z.getStartPunt().getX();
double a = deltay / deltax;
double b = z.getEindpunt().getY() - a * z.getEindpunt().getX();
double yf = a * this.x + b;
return yf == this.y;
}
Assuming there are no problems with the math, I'd change the last line to
return Math.abs(yf - this.y) < SOME_SMALL_CONSTANT;
since, given the imprecise nature of floating point arithmetics, your method would probably never return true.
I'd play with the value of SOME_SMALL_NUMBER to see what give you decent results.
I need to create a class which calculates the distance between two points. I am stuck and I am a total beginner. Here are my classes:
package org.totalbeginner.tutorial;
public class Point {
public double x;
public double y;
Point(double xcoord, double ycoord){
this.x = xcoord;
this.y = ycoord;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
}
The second class.
package org.totalbeginner.tutorial;
public class Line {
double x;
double y;
Point p1 = new Point(2.0,2.0);
Point p2 = new Point(4.0,4.0);
Point mp = new Point(x,y);
public void midpoint() {
x = (p1.getX() + p2.getX()) / 2;
y = (p1.getY() + p2.getY()) / 2;
}
}
I am not sure how to get a point object (the middle point) between both defined points.
I can create point objects but I am not sure how to return a point object through my midpoint() method that lies between those two point objects.
The distance between two points (x1,y1) and (x2,y2) on a flat surface is:
____________________
/ 2 2
\/ (y2-y1) + (x2-x1)
But, if all you want is the midpoint of your two points, you should change your midpoint function to:
public Point midpoint (Point p1, Point p2) {
return new Point ((p1.getX() + p2.getX()) / 2, (p1.getY() + p2.getY()) / 2);
}
This will return a brand new point object with the points set to the middle of the given two points (without having to concern yourself with any other math). And, since your second class is a line, you only need the two end points to describe it, so I'd make some minor changes.
First Point.java:
class Point {
double x, y;
Point (double xcoord, double ycoord) {
this.x = xcoord;
this.y = ycoord;
}
public double getX() { return x; }
public double getY() { return y; }
}
Then Line.java:
public class Line {
Point p1, p2;
Line (Point point1, Point point2) {
this.p1 = point1;
this.p2 = point2;
}
public Point midpoint() {
return new Point ((p1.getX()+p2.getX())/2, (p1.getY()+p2.getY())/2);
}
public double abstand() {
return Math.sqrt(
(p1.getX() - p2.getX()) * (p1.getX() - p2.getX()) +
(p1.getY() - p2.getY()) * (p1.getY() - p2.getY())
);
}
static public void main (String args[]) {
Line s = new Line (new Point(2.0, 2.0), new Point(5.0, 6.0));
Point mp = s.midpoint();
System.out.println ("Midpoint = (" + mp.getX() + "," + mp.getY() + ")");
double as = s.abstand();
System.out.println ("Length = " + as);
}
}
These two files, when compiled and run with the endpoints 2,2 and 5,6 (the hypotenuse of a classic 3/4/5 right-angled triangle), generate the correct:
Midpoint = (3.5,4.0)
Length = 5.0
Simple Pythag... root(dx^2 + dy^2)
Math.sqrt(Math.pow((p2.getX() - p1.getX()), 2) + Math.pow((p2.getY() - p1.getY()), 2))
X
+
|\
| \
a| \c
| \
| \
+-----+
b Y
Imagine X and Y are your points on a flat surface. Then a is X.y - Y.y and b is Y.x - X.x . The length of c is their distance, and is the length of the hypotenuse of that triangle. It is calculated using
sqrt(a^2 + b^2);
Since you see we are squaring a and b, the sign of them isn't relevant - it will come down to the same. So this method always works, where ever the points lie.
Lookup the Pythagorean theorem
Do you really need the distance, or are you trying to just get the midpoint? Because from your code snippet, it kind of looks like you just want to create a new point that is half-way between two existing points.
If you're really just after the midpoint, you don't really need an entire 2nd class (i.e., 'Line') to accomplish that. Since the thing you are trying to find is also a point, it makes sense to add a constructor to your existing Point class, like so ..
Point(Point a, Point b)
{
x = (a.x + b.x) / 2;
y = (a.y + b.y) / 2;
}
.. then, elsewhere let's say you already have a couple of points you want to use this on, you use the constructor thus:
Point p1 = new Point(2,2);
Point p2 = new Point(4,4);
Point midpoint = new Point(p1, p2);
and if you really want distance between two points, that's not really an attribute of either point, so it makes sense to use a static method for that, like so
public static double distance(Point a, Point b)
{
double dx = a.x - b.x;
double dy = a.y - b.y;
return Math.sqrt(dx * dx + dy * dy);
}
and back in the calling code, you can use it this way:
Point p1 = new Point(2,2);
Point p2 = new Point(4,4);
System.out.println("Distance between them is " + Point.distance(p1, p2));
You can use a Maths function for this:
public Point midpoint() {
//Calculate the difference between the old and new x/y
double dx = p1.getX() - p2.getX();
double dy = p1.getY() - p2.getY();
double newX = Math.pow(dx, 2D);
double newY = Math.pow(dz, 2D);
return new Point(newX, newZ);
}
Math.pow handles the issues with negative values and etc. For you,
using Math.pow gives you a safe method because it has a lot of checks built inside.
You can use the Pythagorean Theorem, as other said. Here is a visually demostration from the Wolfram Demostration Project.
alt text http://demonstrations.wolfram.com/DistanceBetweenTwoPoints/HTMLImages/index.en/popup_5.jpg
In your second class, it looks like you're trying to set the values of x and y that are used to construct your mp variable. All your formulas are correct, but you need to consider the order that everything is executed. In the code as it is, it's creating the x and y variables, which start out as 0, then the various Points. x and y are still 0, so mp is set to Point(0, 0).
What you probably want to do is change the return type of midpoint to Point, so that when you call that function, you get back a Point. Then you can create a new Point object with the values you calculate. It should look more like this:
public Point midpoint() {
// calculate the middle x and y
double x = (p1.getX() + p2.getX()) / 2;
double y = (p1.getY() + p2.getY()) / 2;
// now make a new Point with those values, and return it
return new Point(x, y);
}