Comparing class attributes - java

I want to write a method that compares the attributes of two objects from the same class. Say I'v got point1 & point2 of the Point class, which have the attributes of:
public class Point{
private double x;
private double y;
private double z;
[...] */constructor and methods*/[...]
}
public static void main (String[] args){
Point point1 = new Point(5, 10, 20);
Point point2 = new Point(0, 5, 10);
}
I want to compare the x, y, and z values of point1 & point2 against each other but I have no idea how to do so. How would I differentiate between the different values in the code block of a method? This is the theoretical method I would write if I could:
public double comparePoints(Point a, Point b){
if (x1 < x2){
System.out.println("Point b has the bigger x-value");
return x2;
}
etc.
}
Any ideas how to do this?

You have already got good answers to your questions, i.e comparing using the comparator interface, using getter\setter to safely access the properties when they are declared private or access the property from each of the objects using obj1.x and obj2.x. It depends on the exact requirement what approach you want to take. The following piece of code that i have updated does a basic comparison of the attributes of two objects.
public class Point {
private double x;
private double y;
private double z;
//Constructor
Point(double l,double m,double n){
this.x = l;
this.y = m;
this.z = n;
}
//main method
public static void main (String[] args){
Point point1 = new Point(5, 10, 20);
Point point2 = new Point(0, 5, 10);
//Object that is created with the greater value
Point point3 = comparePoints(point1,point2);
System.out.println("-----The greater value of property, "
+ "between the two compared objects is as below----");
System.out.println("x ="+point3.x);
System.out.println("y ="+point3.y);
System.out.println("z ="+point3.z);
}
//Compare method declared static, for the satic main method to access
public static Point comparePoints(Point a, Point b){
System.out.println("Values in Object a = "+a.x+""+a.y+""+a.z);
System.out.println("Values in Object a = "+b.x+""+b.y+""+b.z);
System.out.println("Point a has the bigger x-value");
Point h = new Point(0,0,0);
if (a.x < b.x){
h.x = b.x;
}
else{
System.out.println("Point a has the bigger x-value");
h.x = a.x;
}
if (a.y < b.y){
System.out.println("Point b has the bigger y-value");
h.y = b.y;
}
else{
System.out.println("Point a has the bigger y-value");
h.y = a.y;
}
if (a.z < b.z){
System.out.println("Point b has the bigger z-value"+b.z);
h.z = b.z;
}
else{
System.out.println("Point a has the bigger z-value"+a.z);
h.z = a.z;
}
return h;
}
}

if you want to get one of the attributes of on object, you have two choices :
1/ using getter methods :
a.getAttributeX(Point) { ...}
2/ once creating an object Point you would be able to use this:
if(a.x < b.x) then....
PS: It's always safe to use getter methods !

Related

Cubic Bézier formula returning wrong result

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.

ArrayList does not save my Values

following: I create a ArrayList with an Own Object which keeps two int(x,y)
But I only get 0 instead of the number. I don't see why it does not work.
public class Snake {
public class SnakeBody {
public int x;
public int y;
SnakeBody(int x, int y){
x = this.x;
y = this.y;}
}
protected ArrayList<SnakeBody> SnakeBody = new ArrayList<SnakeBody>();
protected PointF Fruit;
protected boolean GameStarted = false;
//Constructor
public Snake(){}
public void startSnake()
{
if(!GameStarted)
{
GameStarted = true;
SnakeBody.add(new SnakeBody(1,14));
SnakeBody.add(new SnakeBody(2,14));
SnakeBody.add(new SnakeBody(3,14));
int itemcount = SnakeBody.size();
Log.d("Snake.java:Game started: ", "" + itemcount);
for(int i=0; i<itemcount; i++){
Log.d("First Snake created: XY->", "" + SnakeBody.get(i).x + ":" + SnakeBody.get(i).y);
}
}
}
That's what I got then as Log.d Output:
Snake.java:Game started:﹕ 3
First Snake created: XY->﹕ 0:0
First Snake created: XY->﹕ 0:0
First Snake created: XY->﹕ 0:0
You want to change
SnakeBody(int x, int y){
x = this.x;
y = this.y;
}
to
SnakeBody(int x, int y){
this.x = x;
this.y = y;
}
What you are actually doing is assigning values of your class to the received parameter, it will never update the position of SnakeBody
By the way, I think it is a bad practice to name the parameter of your constructor the same as the class variable as if you ommit the this keyword, it is not clear what is assigned to what.
Look at your constructor:
SnakeBody(int x, int y){
x = this.x;
y = this.y;}
That's copying the value from your instance field to the parameter, in both cases. In other words, you're overwriting the useful data (the value that the caller passed in) with the value from the otherwise-uninitialized field (which will always be 0). You want it the other way round:
SnakeBody(int x, int y) {
this.x = x;
this.y = y;
}
Note that this has nothing to do with the ArrayList aspect - you could observe the same thing just by writing:
SnakeBody body = new SnakeBody(1, 2);
System.out.println(body.x); // 0
It's always worth trying to pinpoint exactly where the issue is, trying to remove bits of code one at a time until the behaviour changes.
(It's also a good idea to make all fields private, but that's a slightly different matter.)

Method takes another object as a parameter

I am doing homework for java programming. I am asked to write a method that returns a distance between two points. I should use given formula that distance = square root((x2 - x1)*(x2 - x1) +(y2 - y1)*(y2 - y1)).
In the below codes, an object a will be contained current coordinate x1 and y1 and b will be coordinate x2 and y2, passed to move at some where.
How can I write the method in this class without having other classes and other elements such as x2, y2? In the objects there are two values but how can I assign each to x1 and x2, and y1 and y2? I found definition of vector for java but I am not sure it is applicable for this. Does anybody have an idea?
public class MyPoint{
private int x;
private int y;
}
public MyPoint(int x, int y){
this.x = x;
this.y = y;
}
public int distanceTo(MyPoint a, MyPoint b){
MyPoint.x1 = a;
MyPoint.y1 = a;
MyPoint.x2 = b;
MyPoint.y2 = b;
double distance = Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
return distance;
}
}
The distanceTo method should only take one parameter, a MyPoint object, not two parameters:
public double distanceTo(MyPoint other) {
// ...
}
The first object of the comparison will be the current object, the one whose method is being called.
Then in the method body you compare the current object's fields, the this.x and this.y with the x and y values of the object passed in to the method's parameter, other.x and other.y.
Also, the method probably should return a double, not an int as you have it defined.
Regarding,
How can I write the method in this class without having other classes and other elements such as x2, y2?
I'm not sure exactly what you mean by this.
You don't need to declare MyPoint.x1 = a. That isn't really doing anything. Instead you can reference the points such as a.x or b.y.
Additionally you should make sure that your return type is what you want.
EDIT: Hovercraft has essentially said the same as I did but a little nicer.
public class Point
{
int x,y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
public static double distance(Point a, Point b)
{
return Math.sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
public static void main(String[] args)
{
Point a = new Point(0,0);
Point b = new Point(3,5);
System.out.println(distance(a,b));
}
}

Re-using getX() getY() in a mouseclick-event handler

This is a long question. I've tried to make it more concise but I think you need all the info to assist.
Here's a summary:
I'm trying to capture consecutive clicks as endpoints. I'll draw line2D objects between these points. I have a listener that sends x and y values from click events to a helper class. I'll never have more than two points, so the helper class only has firstPoint and secondPoint members. I get the clicks and send the co-ordinates to the helper class using evt.getX() and evt.getY(). The helper creates the points, but firstPoint ends up with the same co-ords as secondPoint. My detail on what's going on can be found below the code blocks.
Here's the code in my mouse click handler:
public class Dashboard extends javax.swing.JFrame {
public static ClickMaster myClicks = new ClickMaster();
public static boolean drawing = false;
private MyPoint firstPoint = new MyPoint();
private MyPoint secondPoint = new MyPoint();
.
.
.
private void MyDrawingPanelMouseClicked(java.awt.event.MouseEvent evt) {
if (firstPoint.getPointType().equals(MyPoint.PointType.NULL)) {
drawing = !drawing;
firstPoint = myClicks.parseClick(evt.getX(), evt.getY(), drawing);
} else if (drawing){
drawing = !drawing;
secondPoint = myClicks.parseClick(evt.getX(), evt.getY(), drawing);
myClicks.parsePoints(firstPoint, secondPoint);
}
}
Here's the helper class that returns points:
public class ClickMaster {
MyPoint anyPoint = new MyPoint();
public ClickMaster() {
anyPoint.setPointType(MyPoint.PointType.NULL);
}
public MyPoint parseClick(double x, double y, boolean firstClick) {
if (firstClick) {
anyPoint.setPointType(MyPoint.PointType.ANCHOR);
} else {
anyPoint.setPointType(MyPoint.PointType.END);
}
anyPoint.setX(x);
anyPoint.setY(y);
return anyPoint;
}
And here's my implementation of Point2D objects, in case it's relevant:
public class MyPoint extends Point2D {
public enum PointType {
ANCHOR, END, SOLO, NULL
};
double x;
double y;
PointType pointType;
public MyPoint(PointType pType, double x, double y) {
this.x = x;
this.y = y;
this.pointType = pType;
}
public MyPoint() {
this.x = 0.0;
this.y = 0.0;
this.pointType = PointType.NULL;
}
+ standard getters/setters as you would expect.
debugging shows that
firstPoint = myClicks.parseClick(firstX, firstY, drawing);
results in a point with the x and y values of the mouse event. This is expected.
Likewise,
secondPoint = myClicks.parseClick(evt.getX(), evt.getY(), drawing);
Results in a point with the x and y values of the second click. Also expected.
However, when I call
myClicks.parsePoints(firstPoint, secondPoint);
I see that firstPoint and secondPoint have the same x,y values.
I'm not sure but I believe it's because both firstPoint and secondPoint are getting their x and y values from the mouse evt. I think I need to put values of type double for x's and y's in to firstPoint and secondPoint as opposed to a reference to the double value returned from the mouse event by getX() and getY().
I just don't know how to make it happen.
Also, if there's a much better way to capture consecutive clicks and translate them to endpoints for shapes, I would welcome the feedback.
Actually, your problem is anyPoint. Since you only have one instance of ClickMaster, and anyPoint is only initialized once, you're returning a reference to the same object no matter how many times you call parseClick. ParseClick needs to create a new MyPoint every time it's called and return that.

How can I move a point and print the new position?

I'm new to Java and I received an assignment that asks me to write a class called PointerTester that has two Points as instance variables. I need to initialize one of these at coordinate (0.0,0.0) and one at (10.0,12.0). Then I need to move each point by +2.0 in x and -3.0 in Y, query the coordinates of the points, and print out the values.
So far I have this:
public class PointerTester{
/*instance variables*/
private double pointOneX;
private double pointOneY;
private double pointTwoX;
private double pointTwoY;
private double deltaX;
private double deltaY;
/*constructor to initialize*/
public PointerTester (){
pointOneX = 0.0;
pointOneY = 0.0;
pointTwoX = 10.0;
pointTwoY = 12.0;
deltaX = 2.0;
deltaY = -3.0;
}
/*constructor to initialize to specific value*/
PointerTester(double pointOneX, double pointOneY, double pointTwoX, double pointTwoY){
this.pointOneX = pointOneX;
this.pointOneY = pointOneY;
this.pointTwoX = pointTwoX;
this.pointTwoY = pointTwoY;
}
/*command to change value*/
public void moveBy(double deltaX, double deltaY){
this.pointOneX = this.pointOneX + deltaX;
this.pointOneY = this.pointOneY + deltaY;
this.pointTwoX = this.pointTwoX + deltaX;
this.pointTwoY = this.pointTwoY + deltaY;
}
/*Queries*/
public double getOneX(){
return pointOneX;
}
public double getOneY(){
return pointOneY;
}
public double getTwoX(){
return pointTwoX;
}
public double getTwoY(){
return pointTwoY;
}
/*print values*/
public static void main(String[] args){
PointerTester pointOne = new PointerTester();
PointerTester pointTwo = new PointerTester();
System.out.println("Point One after move (" + pointOne + ")");
System.out.println("Point Two after move (" + pointTwo + ")");
}
}
I cannot figure out how to correctly output the values or if I am completely wrong in working on this problem.
Edit It seems I needed to use this code that I at first thought was supposed to be separate
public class Point{
public double x;
public double y;
public Point(double x, double y){
this.x = x;
this.y = y;
}
public void setX(double x){
this.x = x;
}
public void setY(double y){
this.y = y;
}
public double getX(){
return x;
}
public double getY(){
return y;
}
}
How do I incorporate this into my code?
I think to get started you should have a separate class called "Point" that encapsulates an X and Y value, and includes a "moveBy" method. It could also implement "toString()" such that "System.out.println" will print something nice for it. [Edit: Or just use java.awt.Point.]
Beyond that, I'll leave that for you to do as your homework.
You might want to use some Point objects.
Point p1 = new Point();
Point p2 = new Point(10,12);
you can then use the setLocation or translate methods found in the point class. Maybe the whole thing would look something like this? Hope this helps.
main(){
//make some points
Point p1 = new Point();
Point p2 = new Point(10,12);
//move our points
p1.translate(2,-3);
p2.translate(2,-3);
//print our points
System.out.println(p1);
System.out.println(p2);
}
You can implement the toString method. There are examples here:
http://www.javapractices.com/topic/TopicAction.do?Id=55
You're trying to print the PointerTester object instead of the values contained within. System.out.println(pointOne.getOneX()) should at least stop throwing exceptions and allow you to print correctly.

Categories