Java - making Triangle class - java

I need to make a Class named "TriangleShape" which impliments java.awt.Shape.
Now another Class "TriangleComponent" should have an object of TriangleShape class and it should draw a triangle, with the given length of sides.
I managed to create it, but i've read that the triangle should be drawn in the following way:
TriangleShape t = new TriangleShape(30,40,50);
g2.draw(t); //This is the Graphics2D object that I use in paintComponent
The following is the code that I created, but it uses Line2D to create a triangle.
It is the TriangleShape class, assume that I have implimented all the methods of the Shape Class.
public class TriangleShape implements java.awt.Shape{
private double a, b, c;
private int x,y;
private Point2D loc;
public TriangleShape() {
this.a=0;
this.b=0;
this.c=0;
}
public TriangleShape(double a, double b, double c) {
//if supplied dimensions form a valid Triangle
if ( this.isValid(a,b,c) ) {
this.a = a;
this.b = b;
this.c = c;
}
//Otherwise make it zero sized triangle
else{
this.a=0;
this.b=0;
this.c=0;
}
}
public void resize(double a, double b, double c) {
if ( this.isValid(a,b,c) ) {
this.a = a;
this.b = b;
this.c = c;
}
//else let size remain unchanged
}
public TriangleShape getRandomTriangle() {
TriangleShape t = new TriangleShape(5,8,9);
return t;
}
public double area(){
double area, s;
s = (a+b+c)/2;
area = Math.sqrt(s *(s-a) * (s-b) * (s-c));
return area;
}
private boolean isValid(double a, double b, double c) {
double s = (a+b+c)/2;
if ( ((s-a) * (s-b) * (s-c)) <= 0 )
return false;
else
return true;
}
public double perimeter() {
double p;
p = a+b+c;
return p;
}
public double getA(){
return a;
}
public double getB(){
return b;
}
public double getC(){
return c;
}
public void setLocation(Point2D location){
loc = location;
}
public Point2D getLocation(){
return loc;
}
public double getX(){
return loc.getX();
}
public double getY(){
return loc.getY();
}
And the TriangleComponent class:
public class TriangleComponent extends JComponent{
TriangleShape t;
double alpha, beta, gamma;
double a,b,c;
double X,Y;
#Override
protected void paintComponent(Graphics g) {
//super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
t = new TriangleShape(100,100,190);
t.setLocation(new Point2D.Double(100,500));
a = t.getA();
b = t.getB();
c = t.getC();
X = t.getX();
Y = t.getY();
///////////////Drawing Base line.....
g2.draw(new Line2D.Double(X,Y,(X+c),Y)); //line c...
g2.draw(new Line2D.Double((X+c), Y, ((X+c)+a*Math.cos(Math.PI+getBeta())), (Y+a*Math.sin(Math.PI+getBeta())))); //line a...
//JOIning the last end points
g2.draw(new Line2D.Double(X, Y, ((X+c)+a*Math.cos(Math.PI+getBeta())), (Y+a*Math.sin(Math.PI+getBeta()))));
System.out.println("X1 = "+X+" Y1 = "+Y);
System.out.println("X2 = "+(X+c)+" Y2 = "+Y);
System.out.println("X3 = "+((X+c)+a*Math.cos(Math.PI+getBeta()))+" Y3 = "+ (Y+a*Math.sin(Math.PI+getBeta())));
//System.out.println("Alpha = "+getAlpha());
System.out.println("Gamma = "+(getGamma()*180)/Math.PI);
}
public double getAlpha(){
double temp = Math.acos(((Math.pow(c, 2)+Math.pow(b, 2))-Math.pow(a, 2))/(2*b*c));
System.out.println("Alpha = "+temp+" Degrees");
return temp;
}
public double getBeta(){
double temp = Math.acos(((Math.pow(c, 2)+Math.pow(a, 2))-Math.pow(b, 2))/(2*a*c));
System.out.println("Beta = "+temp+" Degrees");
return (temp);// * Math.PI)/180;
}
public double getGamma(){
double temp = Math.acos(((Math.pow(a, 2)+Math.pow(b, 2))-Math.pow(c, 2))/(2*b*a));
System.out.println("Gamma = "+temp+" Degrees");
return (temp);// * Math.PI)/180;
}
}
This works, but I need a way to draw the triangle without relying on Graphics2D or drawing it directly with the paintComponent method. Is there a way to do this?

According to the JavaDoc of the Graphics2D class Shapes are rendered according to the following principle:
Shape operations
If the operation is a draw(Shape) operation, then the createStrokedShape method on the current Stroke attribute in the Graphics2D context is used to construct a new Shape object that contains the outline of the specified Shape.
The Shape is transformed from user space to device space using the current Transform in the Graphics2D context.
The outline of the Shape is extracted using the getPathIterator method of Shape, which returns a PathIterator object that iterates along the boundary of the Shape.
If the Graphics2D object cannot handle the curved segments that the PathIterator object returns then it can call the alternate getPathIterator method of Shape, which flattens the Shape.
The current Paint in the Graphics2D context is queried for a PaintContext, which specifies the colors to render in device space.
In short, this means that the Graphics2D.draw(Shape) method will call your TraingleShape.getPathIterator(AffineTransform) method and use the returned PathIterator object in order to find which points to draw lines between.
As such, you will likely be required to implement your own PathIterator implementation that corresponds to your TriangleShape implementation.
The above solution may however be more complex then it needs to be. An alternative would be to look into the Path2D class which allows you to easily specify arbitrary shapes using simple operations such as lineTo(x,y). Since this class implements the Shape interface you could allow your TriangleShape class to extend this class, or just delegate to it. Here is an example of using the GeneralPath class, which works in a similar way to Path2D:
http://www.roseindia.net/java/example/java/swing/graphics2D/general-path.shtml
It does however depend on your particular assignment whether this would be an acceptable solution or not.

Related

How to sort list of shapes by their area in Java

I have created a list of Objects and added elements such as Circle and Square in it. I have added a method in the sqaure and circle classes which checks the instance of the object and compares the area.
public class Circle extends Shape implements Comparable <Object>{
public int compareTo(Object otherObject) {
double difference=0.0;
int retValue= 3;
if(otherObject instanceof Circle){
Circle circle= (Circle)otherObject;
difference= this.area()- circle.area(); //calculate the difference of areas
}
if(otherObject instanceof Square){
Square square= (Square)otherObject; //Casting the object to Sqaure
difference= this.area()- square.area();//Calculate difference of Areaareas
}
if(difference == 0.0)retValue = 0; //return 0 if area is equal
if(difference < Shape.TOLERANCE)retValue = -1; //return -1 if area of the circle is less than the otherObject
if(difference > Shape.TOLERANCE)retValue = 1; //return 1 if area of the circle is more than the otherObject
return retValue;
}
}
My class where I want to sort this looks like this:-
List<Object> objectList = new ArrayList<Object>();
when, I am trying Collections.sort(objectList), it is giving me an me error
no suitable method found for sort(List<Object>)
Any suggestions. Also I have declared my class like
Apples vs. Oranges, or in your case Circles vs. Squares.
You need to make them share a common aspect, which means that you need to make them implement a Shape2D interface with a double getArea() method.
You can then write a Comparator<Shape2D> and call sort(myShapeList, myAreaComparator).
Update
Given the extra code now shown in question, you already have the common base class Shape, which appears to have an abstract double area() method, implemented by both Circle and Square.
You then change Shape to be Comparable<Shape> (not Object), and the compareTo() method, which now takes a Shape as parameter, can call area() without any casting.
It doesn't make sense for a Circle to be comparable to Object.
If you want to sort circles and squares by their area,
use a Comparator instead.
It will also make sense to:
Use a List<Shape> rather than a List<Object>
A Comparator<Shape> can do the job, using Shape.area for the ordering
Use Double.compare to compare the areas, instead of manual if-else
Something like this:
public void demo() {
List<Shape> shapes = new ArrayList<>();
shapes.add(new Circle(2));
shapes.add(new Square(2));
shapes.add(new Square(1));
shapes.add(new Circle(1));
Collections.sort(shapes, new Comparator<Shape>() {
#Override
public int compare(Shape o1, Shape o2) {
return Double.compare(o1.area(), o2.area());
}
});
System.out.println(shapes);
}
Where the implementation of Shape, Circle, Square can be simple like this:
abstract class Shape {
abstract double area();
}
class Circle extends Shape {
private final double radius;
Circle(double radius) {
this.radius = radius;
}
#Override
double area() {
return radius * radius * Math.PI;
}
#Override
public String toString() {
return "Circle(" + radius + ")";
}
}
class Square extends Shape {
private final double side;
Square(double side) {
this.side = side;
}
#Override
double area() {
return side * side;
}
#Override
public String toString() {
return "Square(" + side + ")";
}
}

New to Java: SuperClass and SubClass

I am fairly new to Java and I am learning about Inheritance. I am trying to create a subclass called BetterRectangle under the superclass Rec1.
Rec 1 gets the x and y coordinates (location) and also gets the width and height (size) of the rectangle. BetterRectangle calculates the perimeter and area of the rectangle.
I get errors in the main method. It cannot find any of the symbols (i.e. cannot find rec1.getHeight(20) symbol).
public class Rec1 {
private double x;
private double y;
private double width;
private double height;
public void setLocation(double xCord, double yCord) {
x = xCord;
y = yCord;
}
public void setSize(double h, double w) {
height = h;
width = w;
}
public double getHeight(double h) {
return height;
}
public double getWidth(double w) {
return width;
}
}
public class BetterRectangle extends Rectangle {
public BetterRectangle(int x, int y, int width, int height) {
super(x, y, width, height);
super.setLocation(x, y);
super.setSize(width, height);
}
public double calcPerimeter() {
return super.getHeight() * 2 + super.getWidth() * 2;
}
public double calcArea() {
return super.getHeight() * super.getWidth();
}
}
Look closely:
Rectangle Rec1 = new Rectangle();
Rec1.getHeight(20);
The type of Rec1 is Rectangle. But the Rectangle class doesn't have a getHeight method. Maybe you wanted this:
Rec1 rec1 = new Rectangle();
rec1.getHeight(20);
Notice that I renamed the variable to rec1, and changed its type.
class BetterRectangle is extending Rectangle in your sample code. So here BetterRectangle would be child and Rectangle would be parent. Now BetterRectangle uses super keyword to access getHeight,getWidth etc...functions. since these functions are not present in Rectangle class it is giving compilation Error.
Instead of extending Rectangle class extend Rec1 class in BetterRectangle and then run the main Class Rectangle. This should work.
Look carefully here
Rectangle BetterRectangle = new Rectangle();
Rectangle Rec1 = new Rectangle();
You are declaring variables of type Rectangle instead of your own classes. I can't see your import statements but you are likely creating types of java.awt.rectangle. You're mixing up variable types and variable names. When creating instances of your own classes it should look like this:
Rec1 mySimpleRec = new Rec1();
BetterRectangle myBetterRec = new BetterRectangle()
When declaring things put them in this order "Type variableName = new Type()" or "Class variableName = new Class()".

Calculating distance between two points in 3D

My assignment is to create main class in which I initialize the value of any point to be at (0,0,0) and to be able to access and mutate all three values (x,y,z) individually. To do this I have used getters and setters. My next task is to create a method within my main class (which I shall call "distanceTo") that calculates the distance between two points.
How do I go about creating the method "distanceTo" that calculates the distance between two points by taking in the x,y,z coordinates ? I assume my answer will have something to do with sqrt((x1-x2)^2+(y1-y2)^2+(z1-z2)^2) but I do not know how I can write that in my method in my main class if my points are not defined until my second test point class
So far I only have two points, but I am looking for a more general answer (so that if I created three points, p1 p2 and p3, I could calculate the distance between p1 and p2 or the distance between p2 and p3 or the distance between p1 and p3.
My main class:
package divingrightin;
public class Point3d {
private double xCoord;
private double yCoord;
private double zCoord;
public Point3d(double x, double y, double z){
xCoord = x;
yCoord = y;
zCoord = z;
}
public Point3d(){
this (0,0,0);
}
public double getxCoord() {
return xCoord;
}
public void setxCoord(double xCoord) {
this.xCoord = xCoord;
}
public double getyCoord() {
return yCoord;
}
public void setyCoord(double yCoord) {
this.yCoord = yCoord;
}
public double getzCoord() {
return zCoord;
}
public void setzCoord(double zCoord) {
this.zCoord = zCoord;
}
//public double distanceTo(double xCoord, double yCoord, double zCoord ){
}
My class with the test points:
package divingrightin;
public class TestPoints {
public static void main(String[] args) {
Point3d firstPoint = new Point3d();
firstPoint.setxCoord(2.2);
firstPoint.setyCoord(1);
firstPoint.setzCoord(5);
//System.out.println(firstPoint.getxCoord());
Point3d secondPoint = new Point3d();
secondPoint.setxCoord(3.5);
secondPoint.setyCoord(22);
secondPoint.setzCoord(20);
}
}
As #Dude pointed out in the comments, you should write a method:
public double distanceTo(Point3d p) {
return Math.sqrt(Math.pow(x - p.getxCoord(), 2) + Math.pow(y - p.getyCoord(), 2) + Math.pow(z - p.getzCoord(), 2));
}
Then if you want to get the distance between 2 points you just call:
myPoint.distanceTo(myOtherPoint);
//or if you want to get the distance to some x, y, z coords
myPoint.distanceTo(new Point3d(x,y,z);
You could even make the method static and give it 2 points to compare:
public static double getDistance(Point3d p1, Point3d p2) {
return Math.sqrt(Math.pow(p1.getxCoord() - p2.getxCoord(), 2) + ...
}
P.S. my first answer :)
public double distanceTo(Point3d other) {
return Math.sqrt(Math.pow(this.xCoord-other.getxCoord(), 2)
+ Math.pow(this.yCoord-other.getyCoord(), 2)
+ Math.pow(this.zCoord-other.getzCoord(), 2));
}
Add this to your Point3d class. When you need to calculate the distance in the TestPoints class, you do something like
double distance = firstPoint.distanceTo(secondPoint);
You have two possible approaches, according to what you want to achieve.
You can put your "distanceTo" method inside the class Point3D:
public class Point3d {
...
public double distanceTo(Point3d ) {
return Math.sqrt( Math.pow(this.x - that.x, 2) + Math.pow(this.y - that.y, 2) + Math.pow(this.z - that.z, 2));
}
In this case, you are always using the first point as the first argument, and any other point as the one you want to compute the distance from.
Alternatively, you can have a generic distanceTo method that lives somewhere(such as in your Program class, where you have your main method), that takes two points and compute the distance between those:
public class Program {
static public void main(String[] args) {}
public double distanceTo(Point3d p1, Point3d p2) {
return Math.sqrt( Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2) + Math.pow(p1.z - p2.z, 2));
}
}
Which one is better? Depends on how you use them in the common case :)
Just use the getters
float distance = Math.sqrt(Math.pow(secondPoint.getXCoord() - firstPoint.getXCoord()), 2) + ...)
Two ideas.
Either add a:
public double distanceTo(Point3d otherPoint) {
// return distance by using this.getxCoord(), this.getyCoord(), etc.
// and otherPoint.getxCoord(), otherPoint.getyCoord()
}
method to your Point3d class.
Then, at the end of your main method, you can do:
System.out.println(firstPoint.distanceTo(secondPoint));
System.out.println(tenthPoint.distanceTo(ninthPoint));
Or, add a static method to your main TestPoints class:
public static double distanceBetween(Point3d point1, Point3d point2) {
// return distance by using point1.getxCoord(), etc. and point2.getxCoord()
}
Then, at the end of your main method, you can do:
System.out.println(distanceBetween(firstPoint, secondPoint));
System.out.println(distanceBetween(tenthPoint, ninthPoint));

Java why is implementing an interface necessary?

I've just started Java, and are going through examples online at:
http://docs.oracle.com/javase/tutorial/java/IandI/usinginterface.html
Then I got to implementing an interface, while I understand the concept behind it, but it seems weird to me, as in the interface declaration you only defines it, and in the class that implements this interface you'll still have to write it's functions. So why use it at all?
I tried the sample code, and then change the code to remove the interface, and they both work the same. So my question is when will implementing interface be used? It looks unnecessary to me. Thanks in advance!
Sample Code online:
public class RectanglePlus
implements Relatable {
public int width = 0;
public int height = 0;
public Point origin;
// four constructors
public RectanglePlus() {
origin = new Point(0, 0);
}
public RectanglePlus(Point p) {
origin = p;
}
public RectanglePlus(int w, int h) {
origin = new Point(0, 0);
width = w;
height = h;
}
public RectanglePlus(Point p, int w, int h) {
origin = p;
width = w;
height = h;
}
// a method for moving the rectangle
public void move(int x, int y) {
origin.x = x;
origin.y = y;
}
// a method for computing
// the area of the rectangle
public int getArea() {
return width * height;
}
// a method required to implement
// the Relatable interface
public int isLargerThan(Relatable other) {
RectanglePlus otherRect
= (RectanglePlus)other;
if (this.getArea() < otherRect.getArea())
return -1;
else if (this.getArea() > otherRect.getArea())
return 1;
else
return 0;
}
}
Code that I changed to, taken out the interface, it still works the same
public class RectanglePlus {
public int width = 0;
public int height = 0;
public Point origin;
// four constructors
public RectanglePlus() {
origin = new Point(0, 0);
}
public RectanglePlus(Point p) {
origin = p;
}
public RectanglePlus(int w, int h) {
origin = new Point(0, 0);
width = w;
height = h;
}
public RectanglePlus(Point p, int w, int h) {
origin = p;
width = w;
height = h;
}
// a method for moving the rectangle
public void move(int x, int y) {
origin.x = x;
origin.y = y;
}
// a method for computing
// the area of the rectangle
public int getArea() {
return width * height;
}
// a method required to implement
// the Relatable interface
public int isLargerThan(RectanglePlus otherRect) {
if (this.getArea() < otherRect.getArea())
return -1;
else if (this.getArea() > otherRect.getArea())
return 1;
else
return 0;
}
public static void main( String[] args )
{
RectanglePlus newRect = new RectanglePlus(20, 30);
RectanglePlus somerect = new RectanglePlus(50, 100);
System.out.println("Area of newRect is " + newRect.getArea());
System.out.println("Area of somerect is " + somerect.getArea());
if((newRect.isLargerThan(somerect))==1)
{
System.out.println("newRect is bigger");
}
else
{
System.out.println("somerect is bigger");
}
}
}
Two reasons:
If you will have more than one implementation of the interface. Say you have Shape and subtypes is Rectangle, Oval, etc. If you want to write code that can do something with shapes in general, you need an interface which all of the subtypes implement - the interface is the set of methods you know that any Shape will have.
If you are writing an API - you are writing a library which someone else will use. You provide other people with interfaces - this is the stuff that it's okay for them to call. You will implement the interface, and the implementation class may have more methods - and you would like to be able to change those methods later, but your users should be able to pick up the new version of your library and use it with their old code. By separating the interface from the implementation, you give the public something they can use, but preserve for yourself something you can change without hurting existing users.
This is to facilitate type/interface reuse. You can pass a sub-type's object where a parent type object is expected. You can refer to http://www.oodesign.com/liskov-s-substitution-principle.html.
This basically allows you to deal in an abstract way. Your program can handle objects of different Classes as long as they implement certain behavior (or implement an interface or extend from a class)
If you implements Relatable it allows you to find the largest object in a pair of objects, for any objects that are instantiated from a class that implements Relatable. Otherwise you only can find the largest object in a pair of objects that are instantiated from the same class.

Java error - "invalid method declaration; return type required"

We are learning how to use multiple classes in Java now, and there is a project asking about creating a class Circle which will contain a radius and a diameter, then reference it from a main class to find the diameter. This code continues to receive an error (mentioned in the title)
public class Circle
{
public CircleR(double r)
{
radius = r;
}
public diameter()
{
double d = radius * 2;
return d;
}
}
Thanks for any help, -AJ
Update 1:
Okay, but I shouldn't have to declare the third line public CircleR(double r) as a double, right? In the book I am learning from, the example doesn't do that.
public class Circle
{
//This part is called the constructor and lets us specify the radius of a
//particular circle.
public Circle(double r)
{
radius = r;
}
//This is a method. It performs some action (in this case it calculates the
//area of the circle and returns it.
public double area( ) //area method
{
double a = Math.PI * radius * radius;
return a;
}
public double circumference( ) //circumference method
{
double c = 2 * Math.PI * radius;
return c;
}
public double radius; //This is a State Variable…also called Instance
//Field and Data Member. It is available to code
// in ALL the methods in this class.
}
As you can see, the code public Circle(double r).... how is that different from what I did in mine with public CircleR(double r)? For whatever reason, no error is given in the code from the book, however mine says there is an error there.
As you can see, the code public Circle(double r).... how is that
different from what I did in mine with public CircleR(double r)? For
whatever reason, no error is given in the code from the book, however
mine says there is an error there.
When defining constructors of a class, they should have the same name as its class.
Thus the following code
public class Circle
{
//This part is called the constructor and lets us specify the radius of a
//particular circle.
public Circle(double r)
{
radius = r;
}
....
}
is correct while your code
public class Circle
{
private double radius;
public CircleR(double r)
{
radius = r;
}
public diameter()
{
double d = radius * 2;
return d;
}
}
is wrong because your constructor has different name from its class. You could either follow the same code from the book and change your constructor from
public CircleR(double r)
to
public Circle(double r)
or (if you really wanted to name your constructor as CircleR) rename your class to CircleR.
So your new class should be
public class CircleR
{
private double radius;
public CircleR(double r)
{
radius = r;
}
public double diameter()
{
double d = radius * 2;
return d;
}
}
I also added the return type double in your method as pointed out by Froyo and John B.
Refer to this article about constructors.
HTH.
Every method (other than a constructor) must have a return type.
public double diameter(){...
You forgot to declare double as a return type
public double diameter()
{
double d = radius * 2;
return d;
}
I had a similar issue when adding a class to the main method. Turns out it wasn't an issue, it was me not checking my spelling. So, as a noob, I learned that mis-spelling can and will mess things up. These posts helped me "see" my mistake and all is good now.

Categories

Resources