So I to create a method that checks if the point " ponto " is inside the triangle given by the points A,B,C as vertices.
So far I have this :
final double PRECISION = 0.1;
public boolean dentroDoTriangulo (Point A, Point B, Point C, Point ponto){
//total
double ABC = Math.abs ((A.x*(B.y-C.y)+B.x*(C.y-A.y)+ C.x*(A.y-B.y))/2);
//parcial
double ABP = Math.abs((A.x*(B.y-ponto.y)+B.x*(ponto.y-A.y)+ponto.x*(A.y-B.y))/2);
double APC = Math.abs (A.x*(ponto.y-C.y)+ponto.x*(C.y-A.y)+C.x*(A.y-ponto.y))/2;
double PBC = Math.abs (ponto.x*(B.y-C.y)+B.x*(C.y-ponto.y)+C.x*(ponto.y-B.y))/2;
double parciais = ABP + APC + PBC ;
return Math.abs(ABC - parciais) <= PRECISION;
}
I've already tried doing it like :
ABP +APC +PBC == ABC
Nothing either, can someone help me understand what am I doing wrong here ?
EDIT: Your code seems to work OK. Here's a Point class example in case that's where you are crashing.
public class Point {
float x;
float y;
Point() {
x = 0;
y = 0;
}
Point(float x, float y) {
this.x = x;
this.y = y;
}
}
Just in case, I propose another solution:
Check out this algorithm for determining if the point is inside a triangle.
I cannot see your Point class so I do not know if there is a bug there. I assume it is two floats for x&y coordinates. We'll assume it's ok.
Can you explain your algorithm a bit better? I looks like you are taking three areas of the sub-triangles and adding them up to compare against the original triangle (with PRECISION tolerance). Try the "SameSide" function three times as mentioned in hyperlink if you want--which takes two cross products and then the dot product of the results of the cross products to determine if a point is on the "correct side" of a line between any two of the vertices (there are three such lines).
Code snippet for algorithm:
boolean SameSide(p1, p2, a, b) {
int[] cp1 = CrossProduct(b - a, p1 - a);
int[] cp2 = CrossProduct(b - a, p2 - a);
if (DotProduct(cp1, cp2) >= 0) {
return true;
}
return false;
}
boolean PointInTriangle(p, a, b, c) {
if (SameSide(p, a, b, c) && SameSide(p, b, a, c) &&
SameSide(p, c, a, b) {
return true;
}
return false;
}
Where a, b, c are the vertices and p is the point. I recommend int [] to hold the vectors. You will need to write the helper functions to calculate vector manipulations.
I could not follow your algorithm, but you could send out horizontal (or any direction for that matter) rays in two directions from the point. If it hits the triangle in both directions, then the point will be inside the triangle. You will need to be careful of special conditions where the ray hits a vertex. That would be considered as hitting two lines on one side. But as long as the ray hits the triangle in both directions, the point will be inside.
So I used your code for method dentroDoTriangulo and stuck is inside a class. I used the Point class given above. Then I called your method using the quick and dirty code given below. It seems to work without any problems. Like #TNT says above, a test case would be helpful.
public class Caller {
public static void main(String[] args) {
Triangle myTraingle = new Triangle();
boolean isInside = myTraingle.dentroDoTriangulo(new Point(1,0), new Point(3,0), new Point(2,2), new Point(2,1));
if (isInside) {
System.out.println("Point is inside");
} else {
System.out.println("Point is outside");
}
}
}
Related
I have a convex polygon and some points. I have to form a line between 2 points and then form a triangle with another point. The point from inside the triangle are inside the polygon too. The algorithm continues by forming triangles until finding all the points belonging to the polygon. I need some help, 'cause I'm new to java and don't know how to solve this problem. I managed to write the function to check if a point belongs to the line created.
public static void calculateLine(Point Q, Point P, Point x) {
double a, b;
a = Q.y - P.y;
b = P.x - Q.x;
double c = a * (P.x) + b * (P.y);
if (a * x.x + b * x.y == c)
System.out.println("point belongs to line");
else {
System.out.println("point doesn't belong to line");
}
}
}
I wanna get the different results as the inputted number.
For example, when I put 4 I get the results of the rectangle and when I put 3 I get the triangle.
import java.util.Scanner;
public class Source9_1 {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int x, y; // 클래스 Parameter(내부 변수)
Point[] v = new Point[n]
for(int i=0; i <= v.length; i++) {
v[i] = new Point();
v[i].
}
}
class Point {
int x, y; // 클래스 Parameter (내부 변수)
public void setPoint(int x, int y) { // Point 세팅
this.x = x;
this.y = y;
}
public void printPoint() { // Point 출력
System.out.println("x = " + x + ", y = " + y);
}
}
class Rectangle extends Point {
Point[] p = new Point[4];
Rectangle(Point[] p) {
this.p = p;
}
}
class Triangle extends Point {
Point[] p = new Point[3]; // 3개의 Point인스턴스를 담을 배열 생성
Triangle(Point[] p) {
this.p = p;
}
}
class Shape extends Point { // Point 배열 및 상속을 받아 세팅 후 출력가능한 클래스
Point coord[10];
static int s = 0; // 불릴 때마다 값 증가 ???
public void printShapePoint() { // 배열에 담은 Point 출력
}
public void setShapePoint() { // 배열에 담기 위해 Point 증가
}
}
So far, I coded like this but I don't know what to do now.
How can I get the different result as I put the number?
This is the result what I want
First of all, about your Rectangle and Triangle classes. I feel like you have missed your point there (pun not intended), because you've put both extending the Point class. That doesn't make much sense, since you have the Shape class, which would do a much better job as the superclass for them.
So:
class Rectangle extends Shape {
...
}
class Triangle extends Shape {
...
}
With that out of the way, what you have so far:
You are capturing the number of points from the input;
You are creating an array of that size;
You are instantiating and setting an Point object for each of the array positions.
What you need to do next:
Capture the points coordinates from the input
Set said coordinates to the Point objects
Instantiate an Triangle or Rectangle object, depending on how many points you have.
So, inside your for statement you will want to do:
for (int i=0; i <= v.length; i++) {
v[i] = new Point();
x = sc.nextInt(); // Save 'x' value into the variable
y = sc.nextInt(); // Save 'y' value into the variable
v[i].setPoint(x, y); // Set both values using the method from Point
}
Then, since both Rectangle and Triangle have Shape as a common superclass, you are allowed to put objects of either one of these class in a Shape variable. So right after the for statement you will want to do:
Shape s; // Create the empty variable here, so it will exist outside the if-else scope
if (n == 3)
s = new Triangle(v);
else
s = new Rectangle(v);
Finally, just print your points:
for (int i = 0; i < v.length; i++)
v[i].printPoint();
And that's pretty much it.
The answer from Pedro is great. I have an additional suggestion to make. Using a switch or conditional to create the different types of shapes is a bit of a code smell. I suggest using an abstract factory for this. I put up a little example of how you could do this here.
Deducing the shape from the number of points might be insufficient. For instance, a rectangle is defined by two points (not four) and so would a line, even though you are not currently modeling lines.
I think it would be more clear to select the shape by name and use a factory to instantiate it from the entered points.
Note that he shapes object hierarchy is used a lot to explain object orientation. There are several pitfalls with designing class structures like this. See for example this article. Keep in mind also the Liskov Substitution principle which is easily violated, see this article.
I have 2 coordinates (A1 and A2), connected by a straight line (my path). How can I calculate the shortest distance of a given coordinate (B1 or B2) from the straight line?
Mathematically :
As explained in wikipedia
the shortest distance between a line and a dot, can be calculated as
follows:
If the line passes through two points P1=(x1,y1) and P2=(x2,y2) then the distance of (x0,y0) from the line is:
Java implimentaion
class Point {
double x,y;
Point(double pX, double pY){
this.x= pX;
this.y= pY;
}
public double distance(Point A1, Point A2){
double numerator = Math.abs((A2.y - A1.y)*this.x + (A2.x - A1.x)*this.y + A2.x*A1.y - A2.y*A1.x);
double denominator = Math.sqrt(Math.pow(A2.y - A1.y,2) + Math.pow(A2.x - A1.x,2));
return numerator/denominator;
}
}
To calculate the distance between Point B and the line defined by Points A1 and A2, you use the method distance like this:
public static void main (String[] args) throws java.lang.Exception
{
Point A1 = new Point(0,3);
Point A2 = new Point(2,0);
Point B = new Point(0,0);
System.out.println(
B.distance(A1,A2)
);
}
And here is the code up and running in ideone.
But pleas go buck to the basics, chose some good and funny coding book or tut and give it a go, happy coding :)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am trying to create simple objects, branching out from a single point object, into a line object (two points), and then into a triangle object (three points). I understood how to create the point class, though when trying to branch into the line class, I got a bit confused with how to actually go into writing a line class or triangle class using the initial point class. I need some help with going from a single point class into
I can post some code that I have done so far.
I also have read that there are already java geometry classes out there, but I want to actually create these classes to practice with OOP.
edit --- Added code below
class Point
{
private double x;
private double y;
public Point()
{
x = 0.0;
y = 0.0;
}
public Point(double x, double y)
{
this.x = x;
this.y = y;
}
public double getX()
{
return this.x;
}
public double getY()
{
return this.y;
}
public void setX(double x)
{
this.x = x;
}
public void setY(double y)
{
this.y = y;
}
public double distance(Point p)
{
return Math.sqrt((this.x - p.x) * (this.x - p.x) + (this.y - p.y)
* (this.y - p.y));
}
public String toString()
{
String s = "(" + x + ", " + y + ")";
return s;
}
public boolean equals(Point p)
{
double delta = 1.0e-18;
return (Math.abs(this.x - p.x) < delta)
&& (Math.abs(this.y - p.y) < delta);
}
//-----------------Line Class--------------------//
class Line
{
private Point p1;
private Point p2;
public Line()
{
p1 = new Point (0,0);
p2 = new Point (1,1);
}
public Line(double x1, double y1, double x2, double y2)
{
p1 = new Point (x1, y1);
p2 = new Point (x2, y2);
}
public Line(Point p, Point q)
{
p1 = new Point(p.getX(), p.getY());
p2 = new Point(q.getX(), q.getY());
}
public Point getP1()
{
return this.p1;
}
public Point getP2()
{
return this.p2;
}
public void setP1(double x, double y)
{
Point p1 = new Point(x, y);
this.p1 = p1;
}
public void setP2(double x, double y)
{
Point p2 = new Point(x, y);
this.p2 = p2;
}
public boolean isParallelY()
{
double delta = 1.0e-18;
return (Math.abs(p1.getX() - p2.getX()) < delta);
}
public boolean isParallelX()
{
double delta = 1.0e-18;
return (Math.abs(p1.getY() - p2.getY()) < delta);
}
public boolean isParallel (Line line)
{
if (this.Slope() == line.Slope())
return true;
else
return false;
}
public double Slope()
{
double inf = Double.POSITIVE_INFINITY;
if(isParallelY())
return inf;
return ((p2.getY() - p1.getY()) / (p2.getX() - p1.getX()));
}
public double xIntercept()
{
return -(p1.getY() / Slope() - p1.getX());
}
public double yIntercept()
{
return p1.getY() - (Slope() * p1.getX());
}
I am still adding methods to the line class right now and have not started on the triangle class (though I was thinking of creating a triangle with 3 points rather than 3 lines. And sorry about the branching confusion, I am relatively new.
A Line has 2 Points, so any Line class will have 2 Point-attributes
Any Triangle has 3 Points, so any Triangle class will have 3 Point-attributes
You can create the constructor of these classes to ensure correct objects.
public Line(Point point1, Point point2)
{
this.point1 = point1;
this.point2 = point2;
}
and for the Triangle class
public Triangle(Line line1, Line line2, Line line3)
{
this.point1 = line1.firstpoint();
this.point2 = line2.firstpoint();
this.point3 = line3.firstpoint();
}
or
public Triangle(Point point1, Point point2, Point point3)
{
this.point1 = point1;
this.point2 = point2;
this.point3 = point3;
}
Since each class contains the right attributes you can calculate with them.
If you really want to do OOP, think about what objects exist in your domain, and what messages they understand - that's all Mr Kay ever talked about :)
In your case, you've found Points. Seems you are thinking in a 2D point, and that's why you've just used x and y coordinates. In a 2D world, what would we like to ask to a Point? It's position/coordinates, right - we already have them. What else? A distance to another Point, right. That seems to be pretty much everything a Point can do by now.
Wait - we can ask it to join another Point, creating a Line. So, maybe, doing aPoint.lineTo(anotherPoint) isn't that bad. But, hey, the important thing is we are actually creating Lines.
They consist in a pair of dots. What would we like to ask to a Line? It's lenght, of course. It's clearly the same as the distance between its points. We can ask it the distance to a Point (some mathematicians already defined it, yeah). We can ask a Line if it's parallel with another one, or if they cross. We can ask it at which point they cross. We can ask the angle formed by two lines. And, then, again, we can ask it to join with a third point, to create a Triangle.
Then we'll have a convex shape, so new fun things as area, perimeter, internal angles, external angles.
Try to think of things, concepts and definitions, and implement them as simply as you can. Try to make code as nearly as possible to the colloquial definitions of the concepts it represents. And construct new abstractions based on the previous ones.
Besides all of this, there's one thing you shall not forget: programming is modeling. Models are abstractions. OOP is about using objects to model the portion of the reality we are interested in. If you don't define the scope of what things you wish to model (as this case is just an educational activity, with no real requirements), you can spend your hole life adding methods to your objects, without much sense. Think in advance what things you would like to be able to do with your Points, Lines, Triangles, etc, and limit yourself to them.
Happy hacking :)
Hi I try to implement a simple Sphere collision detection algorithm as explained here: http://wp.freya.no/3d-math-and-physics/simple-sphere-sphere-collision-detection-and-collision-response/
So I implement the method to check if Collision occurs:
private boolean advancedSphereSphere(Sphere a, Sphere b) {
Vector2D s = a.getPos().sub(b.getPos());
Vector2D v = a.getVelocity().sub(b.getVelocity());
float r = a.getRadius() + b.getRadius();
double c1 = s.dot(s) - r*r;
if(c1 < 0.0) {
timeToCollision = .0f;
return true;
}
double a1 = v.dot(v);
if(a1 < 0.00001f) {
return false;
}
double b1 = v.dot(s);
if(b1 >= 0.0) {
return false;
}
double d1 = b1*b1 - a1*c1;
if(d1 < 0.0) {
return false;
}
timeToCollision = (float) (-b1 - Math.sqrt(d1) / a1);
return true;
}
Then I have a onDraw method that loops to draw all necessary elements, like this:
protected void onDraw(Canvas canvas) {
flowPhysics(false);
for(Sphere s : mSpheres) {
s.draw(canvas);
}
invalidate();
}
and the problem occurs in flowPhysics(boolean) method, at this line:
for(int i=0; i < mSpheres.size(); ++i) {
for(int j=i+1; j < mSpheres.size(); ++j) {
Sphere a = mSpheres.get(i);
Sphere b = mSpheres.get(j);
if(advancedSphereSphere(a, b) || step) {
if(timeToCollision < dt && !step) {
flowPhysics(true);
}
if(step) {
sphereCollisionResponse(a, b);
}
}
}
}
When the advancedSphereSphere() is called, the first Sphere disappears, I checked and noticed that the problem is in that method at the first line:
Vector2D s = a.getPos().sub(b.getPos());
if I put something else here and don't subtract the b from a vectors, it draws the balls (but no collision occurs). The Java code above is mostly ported code from here: http://wp.freya.no/websvn/filedetails.php?repname=Public&path=%2Fopengl%2Fcollisiondetect%2Fcollisiondetect.cpp
Can u give me an idea on what is the problem?
Thanks
UPDATE
private void sphereCollisionResponse(Sphere a, Sphere b)
{
double m1, m2, x1, x2;
Vector2D v1, v2, v1x, v2x, v1y, v2y;
Vector2D x = new Vector2D(a.getPos().sub(b.getPos()));
x.normalize();
v1 = new Vector2D(a.getVelocity());
x1 = x.dot(v1);
v1x = new Vector2D(x.multiply(x1));
v1y = new Vector2D(v1.sub(v1x));
m1 = a.getMass();
x = new Vector2D(x.multiply(-1));
v2 = new Vector2D(b.getVelocity());
x2 = x.dot(v2);
v2x = new Vector2D(x.multiply(x2));
v2y = new Vector2D(v2.sub(v2x));
m2 = b.getMass();
Vector2D nn = new Vector2D(v1x.multiply(m1-m2));
Vector2D mm = new Vector2D(nn.divide(m1+m2));
Vector2D tt = new Vector2D(v2x.multiply(2*m2));
Vector2D rr = new Vector2D(tt.divide(m1+m2));
Vector2D gg = new Vector2D(mm.add(rr));
Vector2D ss = new Vector2D(gg.add(v1y));
Vector2D nva = ss;
a.setVelocity(nva);
Vector2D nvb = new Vector2D(v1x.multiply(2*m1).divide(m1+m2).add(v2x.multiply(m2-m2).divide(m1+m2).add(v2y)));
b.setVelocity(nvb);
}
If the problem is really in this line
Vector2D s = a.getPos().sub(b.getPos());
then I suspect the problem may lie in your Vector2D class. You should check that the sub method just returns a new Vector2D and does not modify the coordinates of the original vector a. Keeping your objects immutable as far as possible makes them safer to use.
Failing that, the answer is unit testing. Learning to use JUnit or TestNG will pay off in the long run, but even a few ad-hoc print statements might help you for now. You should be able to check the mathematics is correct independent of how the spheres appear on your screen, and doing this consistently will probably guide you towards a clearer design.
Just by testing that the position of each sphere is unchanged after the collision, and that the velocities are as expected in a few simple cases, you are quite likely to discover the bug in your code. For example, if both velocities are zero beforehand then they should be zero afterwards. If the collision is elastic and one sphere (A) collides head-on with another stationary sphere (B), sphere A should be stationary afterwards and sphere B should have the velocity that A started with.
I haven't checked the maths in your code at http://pastie.org/2499691 but when I set up a few simple classes to fill the dependencies and give it some reasonable starting conditions, it doesn't conserve momentum, so I can believe for some values the balls could end up flying off the screen at the speed of light.
Once you have the physics right, you can work on any remaining problems with the display of the spheres secure in the knowledge that the problem must indeed lie there.