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
}
Related
I've created a very simple form of a Cubic Bézier in Java in order to retrieve the Y value of the point retrieved given the time (t). In my implementation My first (P1) and last (P4) points are always (0, 0) and (1, 1) respectively, and I'm only going to be manipulating P1 and P2. The purpose of this is to create a modifiable curve used to retrieve a value that will be used to multiply and manipulate other values, like a difficulty ramp in video games.
I've tested my implementation using P2=(0.1, 0.1) and P3=(0.9,0.9), so the curve should effectively be a straight line, and whatever my input value (t) is, the output should mimic:
Here is my CubicBezier class:
#AllArgsConstructor
public class CubicBezier {
private static final Point P1 = new Point(0, 0);
private static final Point P4 = new Point(1, 1);
private Point p2;
private Point p3;
public double getValue(double t) {
double dt = 1d - t;
double dt2 = dt*dt;
double t2 = t*t;
Point temp = p2.copy();
return P1.copy()
.scale(dt2 * dt)
.add(temp.scale(3 * dt2 * t))
.add(temp.set(p3).scale(3 * dt * t2))
.add(temp.set(P4).scale(t2 * t))
.getY();
}
}
And my Point class:
#Data
#AllArgsConstructor
public class Point {
private double x;
private double y;
public Point(Point point) {
this.x = point.x;
this.y = point.y;
}
public Point copy() {
return new Point(this);
}
public Point set(Point point) {
this.x = point.x;
this.y = point.y;
return this;
}
public Point add(double scalar) {
this.x += scalar;
this.y += scalar;
return this;
}
public Point add(double x, double y) {
this.x += x;
this.y += y;
return this;
}
public Point add(Point point) {
return add(point.x, point.y);
}
public Point scale(double scalar) {
this.x *= scalar;
this.y *= scalar;
return this;
}
public Point scale(double x, double y) {
this.x *= x;
this.y *= y;
return this;
}
public Point scale(Point point) {
return scale(point.x, point.y);
}
}
My main method:
public static void main(String[] args) {
CubicBezier bezier = new CubicBezier(new Point(0.1d, 0.1d), new Point(0.9d, 0.9d));
double value = 0.4;
System.out.println(value + ": " + bezier.getValue(value));
}
Expected output should be:
0.4: 0.4
However, the output I receive is:
0.4: 0.36640000000000006
And I can't understand why. My getValue method is modelled using the Cubic Bézier explicit form specified on Wikipedia. Am I missing something?
Note: I'm using Lombok to remove some boilerplate. I can specify this boilerplate if necessary.
EDIT:
So it appears that my bezier curve is actually working as it should, and that I've been mistaking t as a value on the x axis, assuming that the y value of the calculated bezier curve will be in relation to the x axis. The functionality I want is that, with the resulting curve, given a value x, return the y value in relation. So in the screenshot above, where the curve is a straight line, x should equal y.
I figured out the answer to my question. There was never anything wrong with my code, the error was a lack of understanding. I had assumed that because P1, p2, p3 and P4 were all points that lay on a straight line between 0 and 1 on both the x and y axes, that no matter where they were positioned on that line, time would reflect progression identically, i.e. x would equal y.
However, because p2 and p3 are closer to P0 and P4 respectively, the progression along the curve is stretched out relative to the time.
In order for a Cubic Bézier curve to have the same progression (y) value as the time (t) value where P1 = (0, 0) and P4 = (1, 1), both inside points must be spread evenly along the curve on both axes. So p2 must be (0.33333, 0.33333) and p3 must be (0.66666, 0.66666).
An example of this problem is shown in this video here. When the points are spread apart, the resulting value is affected.
I have an NxN matrix and I want to find all paths from top left corner to bottom right corner, provided that only down and right moves are allowed.
I built a class Point that holds coordinates within the matrix.
class Point
{
public int x, y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
#Override
public String toString()
{
return "(" + this.x + "," + this.y + ")";
}
}
The algorithm is recursive and checks all possible moves from each point.
public static void findPath(int grid[][], Point start, Point end, ArrayList<Point> currentPath)
{
currentPath.add(start);
if(start.x == end.x && start.y == end.y)
{
System.out.println(currentPath);
return;
}
if(start.x + 1 < grid.length)
{
findPath(grid, new Point(start.x + 1, start.y), end, currentPath);
}
if(start.y + 1 < grid[0].length)
{
findPath(grid, new Point(start.x, start.y + 1), end, currentPath);
}
}
For a simple 2x2 matrix i get the following output:
[(0,0), (1,0), (1,1)]
[(0,0), (1,0), (1,1), (0,1), (1,1)]
The expected output is:
[(0,0), (1,0), (1,1)]
[(0,0), (0,1), (1,1)]
It looks like after points (1,0), (1,1) are popped off the stack, the variable currentPath from the stack frame with the point (0,0), also contains the points (1,0), (1,1) from previous stack frames.
I am mainly interested in an explanation for this behaviour, since there are plenty of resources on the internet on solving the problem. Does it have to do with the fact that currentPath is allocated on the heap and only a pointer to that address is stored on the stack?
Thank you.
There is only one ArrayList instance referenced by the currentPath local variable, so when you pass that variable to recursive calls, you are passing the same instance.
Since you are only adding elements to that ArrayList, any elements previously added will never be removed, so you see the points of both paths in your example.
You should remove from the ArrayList each point that you added once you are done with it, or you can pass a copy of the ArrayList to each recursive call:
public static void findPath(int grid[][], Point000 start, Point000 end, ArrayList<Point000> currentPath)
{
currentPath.add(start);
if(start.x == end.x && start.y == end.y)
{
System.out.println(currentPath);
return;
}
if(start.x + 1 < grid.length)
{
findPath(grid, new Point000(start.x + 1, start.y), end, new ArrayList<>(currentPath));
}
if(start.y + 1 < grid[0].length)
{
findPath(grid, new Point000(start.x, start.y + 1), end, new ArrayList<>(currentPath));
}
}
Now the output will be:
[(0,0), (1,0), (1,1)]
[(0,0), (0,1), (1,1)]
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");
}
}
}
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");
}
}
}
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 :)