How to find if point belongs to polygon by forming triangles? - java

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");
}
}
}

Related

Imagine slicing a polygon like a pizza haphazardly, how would you find the largest slice?

I have a polygon that have been divided up with multiple lines, creating new smaller polygons that make up the whole. How would I go about finding the slice with the largest area?
Imagine something like this: sliced polygon green points are vertices, lines intersect creating more vertices, looking for the largest yellow marked area.
I figured this could be solved by generating a directed graph in order to define each unique shape. I can't come up with a way to link all vertices correctly though.
All vertices and edge lengths are either given or calculated with these methods.
public static double calcDistanceBetweenPoints(Point a, Point b){
return Math.sqrt((b.y - a.y) * (b.y - a.y) + (b.x - a.x) * (b.x - a.x));
}
public static Point findIntersection(Point A, Point B, Point C, Point D){
// Line AB represented as a1x + b1y = c1
double a1 = B.y - A.y;
double b1 = A.x - B.x;
double c1 = a1*(A.x) + b1*(A.y);
// Line CD represented as a2x + b2y = c2
double a2 = D.y - C.y;
double b2 = C.x - D.x;
double c2 = a2*(C.x)+ b2*(C.y);
double determinant = a1*b2 - a2*b1;
if (determinant == 0)
{
// The lines are parallel
return new Point(Double.MAX_VALUE, Double.MAX_VALUE);
}
else
{
double x = (b2*c1 - b1*c2)/determinant;
double y = (a1*c2 - a2*c1)/determinant;
return new Point(x, y);
}
}
Data collected from the System.in input stream looks something like this:
n m
x1 y1
x.. y...
xn yn
x11 y11 x21 y21
x.. y.. x.. y..
x1m y1m x2m y2m
So I get all the starting and ending points for each line from the input.
Thanks for the help

Distance and midpoint - which belongs to Point and which belongs to Line?

From an Object Oriented Programming perspective, given two classes: Line (two Points) and Point (two floats). Which should hold the function distance() and which should hold midpoint()?
My initial thought was that midpoint() should belong to Line, and distance() to Point, because the Point should know the distance between itself and another point. Whereas midpoint() is more of a third-person calculation, that reviews two Points.
But then, when I thought about it, I realized that a Point knows its X and Y coordinates. So both functions should belong to Point. This would also save the creation of getX() and getY() getters. Line can call these functions for its own Points.
Or maybe Line should hold both functions?
So which is right? Or.. Is there another option?
You have to make the distance function & midpoint function in Line class !
Because both function required two points .
Below I am giving the code example that class point has two floating variable named as 'x' & 'y' , getx & gety functions .The other class Line has aggregate with point class & having two object p1 & p2 which is used to calculate the distance between two points & midpoint .
class point
{
float x, y;
public:
float getx()
{
return x;
}
float gety()
{
return y;
}
void setx(float _x)
{
x=_x;
}
void sety(float _y)
{
y=_y;
}
};
class line
{
point p1, p2;
public:
void distance()
{
cout << "Distance : " << sqrt(pow((p2.getx() - p1.getx()), 2) + pow((p2.gety() - p1.getx()), 2));
}
void midpoint()
{
cout << "Mid point : (" << ((p1.getx() + p2.getx()) / 2) << " , " << ((p1.gety() + p2.gety()) / 2) << " )";
}
};
void main()
{
// calling object
}

Find points on triangle

I have 3 vertices of a triangle and I'm trying to find all the integer points that lie on the inside and ON THE SIDES of the triangle. I've tried numerous methods and they all succeed in finding the inside points, but fail in finding the points on the sides of the triangle. Currently I'm using barycentric coordinates:
private static boolean pointInTriangle(int[] p, int[] c1, int[] c2, int[] c3){
float alpha = ((c2[1] - c3[1])*(p[0] - c3[0]) + (c3[0] - c2[0])*(p[1] - c3[1])) /
((c2[1] - c3[1])*(c1[0] - c3[0]) + (c3[0] - c2[0])*(c1[1] - c3[1]));
float beta = ((c3[1] - c1[1])*(p[0] - c3[0]) + (c1[0] - c3[0])*(p[1] - c3[1])) /
((c2[1] - c3[1])*(c1[0] - c3[0]) + (c3[0] - c2[0])*(c1[1] - c3[1]));
float gamma = 1.0f - alpha - beta;
return ( (alpha>=0.0f) && (beta>=0.0f) && (gamma>=0.0f) );
For example, for vertices (0,0),(0,10),(10,10) this does find (10,8) but it also finds (11,8) which is not correct.
Can somebody help me?
Thanks in advance!
Use the code you alreay have to find if a position is inside the triangle. Then for the other part, if a point is on the line or not..
I would do it like this..
Check by calculating the distance between 2 vertices at a time.
Lets say we have vertices a, b and c. And the point p.
Check if p is on the line between a and b.
This can be done by measuring the distance between a -> p and p -> b.
If those two distances equals the distance of a -> b then it is on the line. If p should be off the line the distance will be longer.
Here is a method to caluclate distance (pythagoran teorem):
private static double GetDistance(double x1, double y1, double x2, double y2)
{
double a = Math.abs(x1-x2);
double b = Math.abs(y1-y2);
return Math.sqrt(a * a + b * b);
}

How do I draw a line in java using points?

I was wondering how I'd use different points in Java to draw a line. Here is the code I have so far. I would prefer to not get the x and y of each point and just have the program use the points from x, y on its own. I am still pretty new to programming and not very good at using javadoc at this point. The following is the code I have now:
//Create a Polygon class. A polygon is a closed shape with lines joining the corner points.
//You will keep the points in an array list. Use object of java.awt.Point for the point.
//Polygon will have as an instance variable an ArrayList of Points to hold the points
//The constructor takes no parameters but initializes the instance variable. The
//Polygon class also has the following methods:
// add: adds a Point to the polygon
// perimeter: returns the perimeter of the polygon
// draw: draws the polygon by connecting consecutive points and then
// connecting the last point to the first.
//
//No methods headers or javadoc is provided this time. You get to try your hand at writing
//a class almost from scratch
// Need help starting this question? In the lesson titled
// "Starting points: Problem Set Questions", go to the
// problem titled "Problem Set 6 - Question 3" for some tips on
// how to begin.
import java.util.ArrayList; import java.awt.Point;
public class Polygon {
ArrayList<Point> points;
/**
** a Polygon represents a shape with flat lines and several points.
*/
public Polygon(){
/**
* Constructs empty array of points.
*/
points = new ArrayList<Point>();
} /** ** Adds points to the polygon points Array. *#param = points x and y coordinates to add to class */
public void addPoints(Point point){
points.add(point);
}
/**
**gets distance between points in ArrayList
*/
public double perimeter(){
double perimeter = 0;
int i = 0;
while(i<points.size()){
if(i<points.size()-1){
perimeter = perimeter + points.get(i).distance(points.get(i+1));
}
else{
perimeter = perimeter + points.get(i).distance(points.get(0));
}
}
return perimeter;
}
/** * Draws Polygon using points from points ArrayList */
public void drawPolygon(){
int i = 0;
while(i < points.size()-1){
Line2D line = Line2D.Float(points.get(i), points.get(i+1));
line.draw();
}
Line2D lastLine = Line2D.Float(points.get(0), points.get(points.size()-1));
lastLine.draw();
} }
Let me understand this correctly, you want to implement the draw() method?
If so, what you need to do is search for Bresenham's Algorithm which draws a line based on two given points.
I know this exact question, because I encountered some MAJOR issues with it too.. I stumbled across this question during Udacity's Java Basics course.
I was so stuck, until I moved onto the proceeding lessons which go onto explain more about classes. I downloaded the Problem Set 6 zip file from https://www.udacity.com/wiki/cs046/code and navigated to the Polygon Project folder. In there, I opened the BlueJay project file and could see all the other classes available for use in my Polygon class.
Once I had initialised a Line in my Polygon draw method, the connection between the Polygon class & the Line class appeared (HOORAY).
You can open the Line class to see what its constructors & methods are. Obviously the Line class is working in with a few other classes to actually be able to draw the line, but we can't see any of this in the Udacity IDE and the question doesn't really tell us either..
Nonetheless, I have added my code, that worked in the Udacity IDE to get the correct output.
I see you have used a distance method on the Point class. I don't think this exists.. Hence the garbage in the middle of my code. I probably could have condensed this somehow, but I was just happy to get the right outputs.
public class Polygon
{
private ArrayList<Point> shape; //instance variable
public Polygon() //constructs a new ArrayList of points called shape
{
shape = new ArrayList<Point>();
}
public void add(Point point) //takes in a Point and adds it to the ArrayList "shape"
{
shape.add(point);
}
public double perimeter()
{
double total = 0;
if (shape.size() > 2) //a polygon must have more than 2 sides
{
for (int i = 0; i < shape.size() - 1; i++) //for every point in the list, except for the last
{
double x1 = shape.get(i).getX();
double y1 = shape.get(i).getY();
double x2 = shape.get(i + 1).getX();
double y2 = shape.get(i + 1).getY();
double dist = Math.sqrt(Math.abs(Math.pow((x2 - x1), 2) //get the distance between the point
+ Math.pow((y2 - y1), 2))); //and the following point
total = total + dist; //add this distance to the total
}
double firstX = shape.get(0).getX();
double firstY = shape.get(0).getY();
double lastX = shape.get(shape.size() - 1).getX();
double lastY = shape.get(shape.size() - 1).getY();
double finalDist = Math.sqrt(Math.abs(Math.pow((lastX - firstX), 2) //get the distance between
+ Math.pow((lastY - firstY), 2))); //the first & last points
total = total + finalDist; //add it to the total
}
return total;
}
public void draw()
{
for (int i = 0; i < shape.size() - 1; i++) //for every point in the list, except for the last
{
double x1 = shape.get(i).getX();
double y1 = shape.get(i).getY();
double x2 = shape.get(i + 1).getX();
double y2 = shape.get(i + 1).getY();
Line line = new Line(x1, y1, x2, y2); //create a new Line "line"
line.draw(); //draw the line
}
double firstX = shape.get(0).getX();
double firstY = shape.get(0).getY();
double lastX = shape.get(shape.size() - 1).getX();
double lastY = shape.get(shape.size() - 1).getY();
Line lastLine = new Line(lastX, lastY, firstX, firstY); //get the first & last points & create a line
lastLine.draw(); //draw this line too
}
}

Point inside triangle 2d

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");
}
}
}

Categories