finding the other two points of a Perfect Right Triangle - java

I am writing code that is meant to use one given point of a perfect right triangle to find the remaining two. We assume for this exercise that it is a triangle like so: righttriangle
The first bit of code uses the Point2D class to establish the bottom left point like so:
public Triangle(Point2D.Double bottomLeftPoint, double height, double base){
this.base = base;
this.height = height;
this.bottomLeftPoint = bottomLeftPoint;
}
public Point2D.Double getBottomLeftTrianglePoint() {
return this.bottomLeftPoint;
}
I know that mathematically, the top point of the triangle would have the same x value, but would have the y value added by the height. Also the bottom right point would have the same y value but the x value added by the base.
My question is for method purposes, how would I structure that?
Would it be something like:
public Point2D.Double getTopTrianglePoint() {
return this.bottomLeftPoint(x, y + this.height);
}
public Point2D.Double getBottomRightTrianglePoint() {
return this.bottomLeftPoint(x + this.base, y);
}
For further info, I have a separate class that is meant to test the methods with with a test triangle:
public class TriangleTest {
private Triangle triangle01;
public TriangleTest() {
this.triangle01 = new Triangle(new Point2D.Double(1, 2), 5, 3);
}
}
Any help is appreciated. Thanks!

return this.bottomLeftPoint(x, y + this.height);
Break this down, then you'll notice this doesn't make sense. this.bottomLeftPoint is a variable of type Point2D.Double. You then.. try to treat this as a method somehow. It's not. This doesn't work.
You want to create an entirely new Point2D.Double. new Point2.Double(x, y) as per usual; Thus:
return new Point2D.Double(x, y + this.height);
Except, of course, if you try this, the compiler will tell you this doesn't work either; the compiler has no idea what x means. So, what do you intend to use there? Clearly it's the x coordinate of the Point2D.Double object referenced by your this.bottomLeftPoint field. Which has a .getX() method. So:
return new Point2D.Double(bottomLeftPoint.getX(), bottomLeftPoint.getY() + height);

Related

Creating a second object makes functions of class not work anymore

I'm trying to write a class that shows vectors. If I create one vector object everything works as intended. In my example code the object lin1 gets drawn with the help of the draw() function.
If I now create a second vector object, the (unchanged) draw-function doesnt do anything anymore, even though the object itself is unchanged. It's the same the other way around: Is the second object the only one existing, then it can be drawn, but only as long as lin1 doesnt exist.
Does anyone know where my mistake is?
vector lin;
vector lin2;
void setup()
{
size(500,500);
background(255);
cenX = width/2;
cenY = height/2;
noLoop();
}
void draw()
{
coordSys();
lin = new vector(0,0,100,100);
lin2 = new vector(0,0,-200,-200);
lin.draw();
lin2.draw();
lin.getAll();
}
class vector
{
float x1,y1,x2,y2;
float length;
float angle;
float gegenK, anK;
vector(float nx1, float ny1, float nx2, float ny2)
{
translate(cenX,cenY);
x1 = nx1; y1 = -ny1; x2 = nx2; y2 = -ny2;
strokeWeight(2);
// Gegenkathete
gegenK = ny2 - ny1;
// Ankathete
anK = x2 - x1;
// length and angle
length = sqrt(sq(anK) + sq(gegenK));
angle = winkel(gegenK, anK);
}
void draw()
{
stroke(0);
line(x1,y1,x2,y2);
}
}
}
Please use standard naming conventions when writing code. Specifically, your class should be Vector with an upper-case V. Also, please post your code in the form of an MCVE that compiles and runs.
Anyway, the first call in your Vector() constructor is this:
translate(cenX,cenY);
This moves the origin of the window halfway across the window. When you do this once, this simply makes your drawing calls relative to the center of the window. But when you do this twice, it moves the origin to the bottom-right corner of the window, so all of your drawings are moved off the edge of the screen.
To fix your problem, you need to move this line so it only happens once (perhaps at the beginning of the draw() function) instead of every single time you draw a Vector. Another way to approach this would be to use the pushMatrix() and popMatrix() functions to avoid this stacking of window translations.

Object in Constructor Parameters: Create New Instance, or Assign Pointer?

If a class contains an object as an instance variable, and one of the constructors includes an object of the same type as a parameter, is it best practice to assign the argument to the instance variable, or to create a new object from the argument, and assign THE NEW OBJECT to the instance variable.
Here's an example from an exercise I'm working through:
public class MyCircle {
private MyPoint center; //contains variables int x and int y
private int radius;
//Non-controversial Constructor:
public MyCircle(int x, int y, int radius ) {
//creates new center using a valid MyPoint constructor
this.center = new MyPoint(x, y);
this.radius = radius;
}
//OPTION A
public MyCircle( MyPoint center, int radius ) {
this.center = center;
this.radius = radius;
}
//OPTION B
public MyCircle( MyPoint center, int radius ){
this.center = new MyPoint( center.getX(), center.getY() );
this.radius = radius;
}
}
Initially, I typed option A, but I thought that this could create buggy behavior if this.center referenced an existing object that could be modified indirectly unintentionally. The alternative way of thinking about it, I guess, is that this creates an avenue for creating multiple objects that share a center, and moving a single center would intentionally move all circles that share that center.
Since Java has no pointers (at least not for developers) that option will be discarded and is not the way to go..
Now this:
public MyCircle( MyPoint center, int radius ) {
this.center = center;
this.radius = radius; }
Is in my opinion better, you can just assign the center and don't need to make a risky copy of the class MyPoint... And I say risky because if you want to do that you should at least check the non-null condition of that parameter....
You can for sure think... what if center is null in option A, you are right, that can happen, then you can take care of it by either throwing an illegalparameterexception, or just assigning that object to a default value. ..
But as I said before is my opinion..
I think it depends on your program. If you want the circle to have a reference to the MyPoint object, then you must pass it. Otherwise, why not pass in the actually x and y values themselves.
For example, option B can be written as:
public MyCircle(int x, int y, int radius) {
// rest
}
both options are fine, but as you told, an object may change in the time, the option A is ok when you want to modify the center in more than one object at the same time, for example in an List of Circles, but if you want to have unique and independient center points, option B is correct. So you why don't you have both constructors and use one or another depending many cases in your app, use whatever you want you consider better, keep both, it is my advice.
Hope it helps to you.

Recursive methods Java

Recursion always has been something I have a hard time with. I have a test tomorrow and he said there will be some Recursion on the test so I want to be prepared.
The problem I am trying to do says this:
Given a class Rectangle with instance variables width and height, provide a recursive getArea() method. Construct a rectangle whose width is one less than the original and call its getArea method.
So I know that in recursion you end up calling the method inside itself with a simplified rendition. Like, I know somewhere in getArea(int n) I will have to call getArea(n - 1). I am just not sure what to do with width and height.
So I have this:
public int getArea()
{
if (width == 1) {
// Base case here. Not sure what to do for this.
return 1; // Maybe? I'm not sure.
} else {
Rectangle smallerRect = new Rectangle (width - 1);
int smallerArea = smallerRect.getArea();
return smallerArea + height + width;
}
}
Can anyone help me better understand recursion or maybe how to go about thinking through a recursive function? Thanks.
You've got the recursion itself right, with a base case and a recursive case, and a correct reduction of the parameter in the recursive call (except that, as the commenters have noted, you also need to specify the height of the new rectangle). It's only the geometry that needs fixing: height doesn't change during the recursion; what is the area of the base case rectangle, which has got width 1 and height height? And if you are told the area of the rectangle with width width - 1 and height height, how much extra area do you get by adding a strip of width 1 and height height?
For later use: while mathematically correct, this is a terrible way to compute the area of a rectangle, so please don't do this outside of exam/homework situations :-)
Something like this perhaps? It's basically just multiplying width by height with recursion...
public int getArea() {
return getArea(width);
}
private int getArea(int x) {
return x == 0 ? 0 : height + getArea(x-1);
}
public int getArea()
{
if (width == 1) {
// Base case
return height; // Area = width(1)*height
} else {
Rectangle smallerRect = new Rectangle (width - 1, height);
int smallerArea = smallerRect.getArea();
return smallerArea + height;
}
}

Writing class method for test class

public class CirclTest{
public static void main(String[] args){
Circle first=new Circle('R',3.0);
Circle first=new Circle('R',3.0);
Circle second=new Circle();
System.out.println("first's radius is " + first.getRadius());
System.out.println("first's area is " + first.getArea());
System.out.println("second's area is " + second.getArea());
if(first.hasLargerAreaThan(20)){
System.out.println("first's area is larger than 20. ");
}else{
System.out.println("first's area is smaller than 20. ");
}
}
}
So i am supposed to write a circle class.This is what i have done.
public class Circle{
private double radius=0.0;
private double area=0.0;
private char colour=' ';
public Circle(char colour,double radius){
this.colour=colour;
this.radius=radius;
}
public Circle(){
radius=0;
colour='B';
}
public char getColour(){
return colour;
}
public double getRadius(){
return radius;
}
public double getArea(){
return area;
}
}
I am actually confused on how to write a class.Like i know i need to initialize the variables by private etc.And i need to build a constructor but somehow this code above does not work.the test method is correct.But i have to use it to implement my class.
You're declaring the variable
Circle first
twice. If you want to reassign its value, just do
first=new Circle('R',3.0);
And inside the if statement you're calling
first.hasLargerAreaThan(20)
when I don't see such a method defined in your class.
Can you please what you mean by the code does not work? If you are referring to area not getting calculated correct and is always 0, that is happening because you have a default value for the same as 0 and are never calculating it. You might want to put calculation logic in getArea() method.
First, you're going to want to use a testing framework to assert the validity of your code, if that's what is required. Look into JUnit.
A sample assertion of if the area was larger than some value would be written like this.
#Test
public void assertArea_calculatedProperly() {
//given that the radius is 5,
Circle c = new Circle('R', 5);
//when I get the area...
double result = c.getArea();
//then I expect it to be around 78.53981634.
assertTrue(result < 78.6);
assertTrue(result > 78.5);
}
Second, your getArea isn't actually getting the area. There's nothing in your code to retrieve, then calculate the area. You're not even using Math.PI. I would recommend that you implement that - but use the unit test as a valid way to assert that you're going to get an appropriate response back.

Simplifying Java method with variable amount of arguments

Working in java, I was wanting to simplify a draw function (polygon creator) that I am working with. Typically, when you create a polygon, you do this:
Polygon mypoly = new Polygon();
mypoly.addPoint(x1, y1);
mypoly.addPoint(x2, y2);
mypoly.addPoint(x3, y3);
Draw.fillPolygon(g, mypoly, Color.blue);
I would like to use an image mapper to automatically give me the coordinates, so I could just copy paste them into my own function.
myCommand(x1, y1, x2, y2, x3, y3);
Each of these would go into the polygon command on the top. The problem that I am facing though is that when mypoly is created, how would it know how many points to add and where to put them?
I am trying to get myCommand to automatically add points as I add arguments, and each point to correspond with the x,y of the original polygon creation method.
Sounds like you need to make use of the builder pattern. In pseudocode:
PolygonBuilder pb = new PolygonBuilder();
pb.addPoint(1,1);
pb.addPoint(1,2);
// etc...
Polygon p = pb.newPolygon();
so the idea is that you provide the builder with a set of points, and it'll generate you the appropriate polygon. Builders are often designed with a fluent interface. Note that the builder can act like a factory and return you appropriate subclasses of Polygon (square, triangle, pentagle etc. if you so wish).
Note that you could instead provide a method that takes a variable number of arguments, using the Java varargs mechanism. e.g.
public void addPoints(Integer... args) {
// and iterate here
}
You may wish to create a Point object to define an x/y coordinate together. Otherwise the above will have to check for an even number of arguments, and those arguments won't be tied together.
You can use varargs and create the polygon dynamically by using the constructor that gets arrays of xs and ys
(Code not tested)
public Polygon createPolygon(int... points) {
if (0 != points.length % 2) {
throw new IllegalArgumentException("Must have even number of points");
}
int numOfPoints = points.length / 2;
int xs = new int[numOfPoints];
int ys = new int[numOfPoints];
for (int i=0; i < numOfPoints;i++) {
xs[i] = points[i*2];
yx[i] = points[i*2 + 1];
}
return new Polygon(xs, ys, numOfPOints);
}
Then you can invoke the method with any number of points
Polygon p = createPolygon(x1,y1,x2,y2,x3,y3);
To extend Brian Agnew's answer, it might also be worth adding a Point class which the addPoints method could take in. It could make it slightly easier to add/remove points from your polygon.
public final class Point<X,Y>{
private final X x;
private final Y y;
public Point(X x, Y y){
this.x=x;
this.y=y;
}
public X getX(){return x;}
public Y getY(){return y;}
}
Then you could have a:
public void addPoints(Point<Integer,Integer>... points){
for(Point<Integer,Integer> point:points)
//your logic
}
I think you could use a method that received a varargs (...)
You need a wrapper for each point:
class Point {
int x;
int y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
The method could be:
myCommand(Point ... points)
For call
myCommand(new Point(0,0), new Point(1,1), new Point(0,1));
And for draw:
Polygon mypoly = new Polygon();
for(Point p : points)
mypoly.addPoint(p.x,p.y);
Draw.fillPolygon(g,mypoly,Color.blue);

Categories

Resources