Please explain this unexpected output of this JAVA program - java

In the following program I was jus t trying to create a simple class for as Circle circ and then tried to inherit a Cylinder from it cylind. I defined several methods to find the perimeter, area and volume of these geometrical objects but I am constantly getting wrong answer. I had spent several painstaking our hour to find the error but I am unable to find it. I am a beginner so I think there might be something I may have missed. Please help.
package com.company;
class circ {
int radius;
public circ(int radius) {
this.radius = radius;
}
}
class cylind extends circ{
int height;
double area = (2*Math.PI * radius * ( radius + height ));
double volume = (Math.PI * radius *radius * height );
public cylind(int radius, int height) {
super(radius);
this.height = height;
}
public void area() {
System.out.println("Total Surface Area = " + this.area);
}
public void volume(){
System.out.println("Volume = " + this.volume);
}
}
class Trial_and_error_2 {
public static void main(String[] args) {
cylind b =new cylind(10,45);
System.out.println(b.radius);
System.out.println(b.height);
System.out.println(2*Math.PI * b.radius * ( b.radius + b.height ));
System.out.println(Math.PI * b.radius *b.radius * b.height );
b.area();
b.volume();
}
}
Output: I have used ----> to explain the output and the problem.
10 ---> Radius
45 ---> height
3455.7519189487725 ---> Surface area calculated in the main block
14137.16694115407 ---> Volume calculated in the main block
Total Surface Area = 628.3185307179587 ---> Wrong values of Surface area printed by the method of class THIS IS THE PROBLEM.
Volume = 0.0 ---> Wrong values of volume printed by the method of class THIS IS THE PROBLEM.

Instance variables "area" and "volume" are initialized BEFORE the constructor is called. That's why you get volume = 0, because height is 0 when that happens.

Your field calculations will be executed before the constructor.
Solution:
Just move calculations to constructor:
public Cylinder(int radius, int height) {
super(radius);
this.height = height;
area = 2*Math.PI * radius * (radius + height);
volume = Math.PI * radius *radius * height;
}
Also, I will recommend using full class names with a first capital.

Related

how to add numbers to clock from 1 to 12, i just create circle

import java.awt.Color;
import acm.graphics.GOval;
import acm.program.GraphicsProgram;
public class Clock extends GraphicsProgram {
private static final long serialVersionUID = 1L;
public void run() {
GOval tofig = createFilledCircle(getWidth()/2, getHeight()/2, 200, Color.black);
add(tofig);
GOval lala = createFilledCircle(getWidth()/2, getHeight()/2, 180, Color.white);
add(lala);
}
private GOval createFilledCircle(double x, double y, double r, Color color) {
GOval circle = new GOval(x - r, y - r, 2 * r, 2 * r);
circle.setFilled(true);
circle.setColor(color);
return circle;
}
// Ignore this;
public static void main(String[] args) {
new Clock().start();
}
}
Here's the code for the trigonometry part of what you're trying to do that you and I have kinda worked on together:
public class DrawCircle {
static final double twopi = Math.PI * 2;
static final double fudge = 0.000001;
private static void drawHourLabels(double center_x, double center_y, double radius) {
int steps = 12;
for (double angle = 0.0; angle < (twopi - fudge); angle += twopi/steps) {
double x_offset = Math.sin(angle) * radius;
double y_offset = Math.cos(angle) * radius;
double x = center_x + x_offset;
double y = center_y + y_offset;
// Here you'd do the actual drawing of each hour label at the coordinates x,y. We'll just print them for now.
System.out.println(String.format("%f %f", x, y));
}
}
public static void main(String... args) {
// drawHourLabels(getWidth()/2, getHeight()/2, 220); // <-- you'd do something like this in your "run" method.
// Draw clock labels around circle with center at 400x200 of radius 220
drawHourLabels(400, 600, 220);
}
}
The 'fudge' value is used because floating point arithmetic isn't perfectly precise. By the time we've added 12 floating point values together to get to 2 * Math.PI, we might be a little over or under. We want to make sure we don't process the 12:00 position again at the end of the loop because we computed a value just a little smaller than 2 * Math.PI. So we add a "fudge factor" that's really small, but guaranteed to be bigger than any floating point inaccuracy we've accumulated.
Take a look at this simple example from me.
/**
* Draw text elements from 1 to 12 inside a circle
* #return a group of text elements from 1 to 12
*/
public strictfp static Group drawText() {
//a list for storing text numbers
List<Text> numbersInClock = new ArrayList<>();
//create a group of shapes
Group group = new Group();
//set it to x,y positions
group.setLayoutX(150);
group.setLayoutY(150);
//numbers corresponding to angle calculations
int[] numbers = {3,4,5,6,7,8,9,10,11,12,1,2};
double[] angles = {0, 0.166666666667, 0.333333333334,0.5, 0.666666666667, 0.833333333334, 1, 1.166666666667, 1.33333333334, 1.5, 1.666666666667, 1.83333333334};
int i = 0;
for (double angle : angles) {
//Calculated formula for x,y positions of each number within a circle
//(x,y) = (rcos(angle),rsin(angle))
int r = 90; // length of radius, a bit shorter to put it inside a circle
//calculate x and y positions based on formula for numbers within a circle
double x = r * Math.cos(angle*Math.PI);
double y = r * Math.sin(angle*Math.PI);
//create a text element consiting a coressponding number
Text text = new Text(x, y, String.valueOf(numbers[i++]));
//add it to a list
numbersInClock.add(text);
}
//add all text elements to a group
group.getChildren().addAll(numbersInClock);
//return a group
return group;
}
Full code can be acquired from here: https://github.com/MomirSarac/JavaFX-Circle-Clock-Image
You can use sin and cos to know where to set your text.
Sine and Cosine are two math operators that take in an angle in radians and give out number beetween -1 and 1 to know how to multiply to get coordinates
you can learn more here

Projectile Motion of Arrow: Altered trajectory based on User's Aim

I am making a game which needs an "arrow" to be shot from a stationary location (a set coordinate). The arrow's trajectory is based on the location that the user Clicks in the GUI. This is essentially an Aiming feature. I cant get the arrow to follow a working path, any equations ie used have led to weird, glitchy, and buggy results.
public class ReShoot implements ActionListener
{
public void actionPerformed(ActionEvent e){
ArrowShoot shoot = new ArrowShoot();
shoot.ReShoot();
}
}
public class ArrowShoot implements ActionListener
{
public Timer T = new Timer(5, this);
Arrow A = new Arrow();
public void ReShoot(){
T.start();
arrow_x=0;
arrow_y=200;
A.setBounds(0,200,10,10);
}
// MAIN: y=-16t^2 + Vy * t + h
//Vy = v * sin(a)
//Vx = v * cos(a)
//a = arctan( (200-mouse_y)/v
//v = Mouse_x - Arrow_x
//t = x / Vx
public void actionPerformed(ActionEvent e)
{//arrow_y = 0.0025 * Math.pow((mouse_x-arrow_x), 2)+ mouse_y;
Container container_arrow = getContentPane();
container_arrow.setLayout(null);
container_arrow.add(A);
A.setBounds(0,200,10,10);
arrow_x++;
double v = mouse_x/2; //height change
double a = 50* Math.atan((200-mouse_y) / (v));
double Vy = v * Math.sin(a);
double Vx = v * Math.cos(a);
double t = arrow_x/Vx;
double h = 200;
arrow_y = (16) * Math.pow(t, 2) + (Vy * t) + h;
int x = (int)Math.round(arrow_x);
int y = (int)Math.round(arrow_y);
A.setBounds(x, y,10,10);
if (arrow_y>=500)
T.stop();
}
I am pretty sure im doing this all wrong, and there has to be a more effective method to accomplish this task.
It doesn't look like you are calculating the trajectory path correctly. In actionPerformed, you are incrementing the x coordinate of the arrow, and then calculating the corresponding y. This will not work at all, since even though you can calculate y as a function of x, x is itself a function of t (time). Hence you have to calculate x at time t instead of assuming that x will always increase by 1 at the next invocation.
Given that you can calculate the angle, you can calculate the position of x and y as a function of time and the angle using the following formulas:
So your algorithm will essentially be:
time++; //time variable that you maintain
arrow_x = ... //calculate using (1)
arrow_y = ... //calculate using (2)

Problems with setters and getters in java program dealing with circles

I have been assigned the following task for an introductory java course:
You should write a class that represents a circle object and includes the following:
Private class variables that store the radius and centre coordinates of the object.
Constructors to create circle objects with nothing supplied, with just a radius value supplied and with a radius and centre coordinates supplied.
Public instance methods that allow the radius and centre coordinates to be set and retrieved (often known as set/get methods).
Public instance methods that return the circumference and area of the circle.
A public class method that tests if two circle objects overlap or not
Here is my code:
import java.lang.Math;
public class Circle {
private double xCentre, yCentre, Radius;
// constructors
public Circle() {
xCentre = 0.0;
yCentre = 0.0;
Radius = 1.0;
}
public Circle(double R) {
xCentre = 0.0;
yCentre = 0.0;
Radius = R;
}
public Circle(double x, double y, double R) {
xCentre = x;
yCentre = y;
Radius = R;
}
//getters
public double getX() {
return xCentre;
}
public double getY() {
return yCentre;
}
public double getRadius() {
return Radius;
}
//setters
public void setX(double NewX) {
xCentre = NewX;
}
public void setY(double NewY) {
yCentre = NewY;
}
public void setRadius(double NewR) {
Radius = NewR;
}
//calculate circumference and area
public double Circumference() {
return 2*Math.PI*Radius;
}
public double Area() {
return Math.PI*Radius*Radius;
}
//determine overlap
public static double Overlap(Circle c1, Circle c2) {
double xDelta = c1.getX() - c2.getX();
double yDelta = c1.getY() - c2.getY();
double separation = Math.sqrt(xDelta*xDelta + yDelta*yDelta);
double radii = c1.getRadius() + c2.getRadius();
return separation - radii;
}
}
}
and
import java.io.Console;
public class cp6 {
public static void main(String args[]){
//Set up the Console
Console myConsole = System.console();
//Declare cirlce
Circle first = new Circle(2.0,4.0,6.0);
myConsole.printf("Circumference of first circle is ", first.Circumference(), "\n");
myConsole.printf("Area of first circle is ", first.Circumference(), "/n");
first.setRadius(2);
first.setX(2);
first.setY(2);
myConsole.printf("New X of first circle is ", first.getX(), "/n");
myConsole.printf("New Y of first circle is ", first.getY(), "/n");
myConsole.printf("New Radius of first circle is ", first.getRadius(), "/n");
Circle second = new Circle(-1.0,3.0,5.0);
Circle third = new Circle(1,1,1);
if (Circle.Overlap(second, third) <= 0) {
myConsole.printf("Second and third circles overlap");
}
else {
myConsole.printf("Second and third circles do not overlap");
}
myConsole.printf("New Y of first circle is ", first.getY());
Calculate and print out distance between them using the class method
myConsole.printf("Distance between first and second is : %.5g\n", Circle.Overlap(first, second));
}
}
The second program just has to demonstrate each aspect addressed in the brief I pasted at the top and I've only a rough idea of how to do this so if what I'm doing seems stupid to any of you please offer suggestions of what else I can do.
Your problem is that you're using the Console.printf() method incorrectly.
The first parameter to this method should be a format, and it has to have placeholders inside it for the other parameters. Read up on it in The Java Platform documentation. In fact, you should familiarize yourself with the Java platform documentation. You need to use it often to make sure you're calling methods correctly or what methods are available in a given class.
So, your printout lines should actually have been:
myConsole.printf("Circumference of first circle is %.2f%n", first.Circumference());
myConsole.printf("Area of first circle is %.2f%n", first.Area());
...etc.
The format %.2f means "The corresponding parameter is a floating-point number. Display it with a precision of 2 digits after the decimal point". The %n replaces your "\n" - the whole "template" of the print should be just in the format string. And in this type of format, one should use %n instead of \n.
I'm not sure why you opted for using the system console rather than the usual System.out.println(). If you choose to go with System.out, there is also a printf() method there that works exactly as Console.printf() - the first parameter is a format, the others are embedded in it.
One last comment: there are conventions when writing Java code:
Indent your code properly
Class names' first letter is always uppercase.
Non-constant fields and local variable names' first letter is always lowercase.
Method names also start with a lowercase letter.

why is my setter and getter methods not working?

I have been looking at my source code and can't figure out what is wrong with it.
The problem I think is with the Circle class. When I call the mutators and accessors from
the DriverCircle class it's giving me the wrong output. For getDiameter it's just printing out 0s.
public class Circle{
private double radius;
private double pi;
private double diameter;
private double circumference;
private double area;
public Circle(){
pi = Math.PI;
radius = 0;
}
public Circle(double radius){
this.radius = radius;
}
public void setDiameter(){
diameter = (2 * radius);
}
public double getDiameter(){
//diameter = 2 * radius;
return diameter;
}
public void setCircumference(){
circumference = (2 * pi * radius);
}
public double getCircumference(){
//circumference = 2 * pi * radius;
return circumference;
}
public double getArea(){
//area = pi * Math.pow(radius, 2);
return area;
}
public void setArea(){
area = (pi * Math.pow(radius, 2));
}
public void setRadius(double radius){
this.radius = radius;
}
public double getRadius(){
return radius;
}
public String toString(){
return "The radius is " + radius;
}
}
(The tester)...
import java.util.Scanner;
public class CircleDriver {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Please enter the radius: ");
Circle[] circles = new Circle[10];
Circle objectCircle = new Circle();
objectCircle.setRadius(input.nextDouble());
circles[1] = new Circle();
circles[2] = new Circle(2.0);
circles[3] = new Circle(3.5);
circles[4] = new Circle(5.0);
circles[5] = new Circle(0.0);
circles[6] = new Circle(15);
circles[7] = new Circle(25);
circles[8] = new Circle(-7);
circles[9] = new Circle(-10.0);
System.out.println("Initial call to toString():");
for (Circle c : circles)
{System.out.println("\t" + c);}
System.out.println("Call to getRadius (should be same as above):");
for (Circle r : circles)
{if (r != null)
{System.out.println("\t" + r.getRadius());}}
System.out.println("Call to getDiameter (should be twice the value shown above):");
for (Circle d : circles)
{if (d != null)
{System.out.println("\t" + d.getDiameter());}}
System.out.println("Calls to getCircumference:");
System.out.println("\tShould be 2 * PI: " + circles[1].getCircumference());
System.out.println("\tShould be 0.0: " + circles[5].getCircumference());
System.out.println("\nCall to getArea:");
System.out.println("\tShould be PI: " + circles[1].getArea());
System.out.println("\tShould be 0.0: " + circles[5].getArea());
System.out.println("Testing out the setRadius method:");
for (int i = 0; i < circles.length / 2; i++)
{if (circles[i] != null)
{circles[i].setRadius(i);}}
System.out.println("Call to toString after setting the first half of the objects:");
for (Circle c : circles)
{System.out.println("\t" + c);}
}
}
Your setter methods should have parameters and use the parameters to set fields. Else they are not in fact setter methods. Your current setter methods should all be discarded, except perhaps setRadius(...), and most of the calculations be done in the respective getter methods.
i.e., not
public void setCircumference(){
circumference = (2 * pi * radius);
}
public double getCircumference(){
//circumference = 2 * pi * radius;
return circumference;
}
but rather
public double getCircumference(){
return 2 * Math.PI * radius;
}
pi isn't initialized when you provide a value in constructor. Further, storing pi as an instance member is a bit weird. Just user Math.PI in your calculations.
You never call setDiameter(). Your constructor sets the value of the radius, but it doesn't do anything about setting the diameter variable!
You may just want to rewrite getDiameter():
public double getDiameter() {
return 2.0 * radius;
}
You constructed a Circle object, which sets the radius, but you never set the diameter. Should probably call setDiameter() from the constructor.
Better yet, delete the setDiameter() method as it's completely unnecessary. Simply make getDiameter() return 2*radius.
I see two problems.
First, and foremost, you don't set the value of pi if you use the double constructor. You should also use the no-args constructor as well as set the value of your radius:
public Circle(double radius){
this(); // calls the no-args constructor
this.radius = radius;
}
Second, there's no explicit call to setDiameter(). Funnily enough, that method is a misnomer - it should be calculated whenever the radius is nonzero. setArea is the same way - you're not passing anything in to that method call. Here's what I would recommend:
Rename setDiameter to calculateDiameter to make its intention clear. The reason for the rename is to have this class follow JavaBean conventions with respect to set and get.
In public Circle(double radius), call calculateDiameter() immediately afterwards.
Whenever setRadius() is called, either immediately follow it with a call to calculateDiameter or violate JavaBean conventions and call it immediately after the value is set.
It's strongly encouraged to do the same thing for getArea, but I'll leave that portion as an exercise to the reader.
In code, a brief example:
public Circle(double radius){
this(); // calls the no-args constructor
this.radius = radius;
calculateDiameter();
}
public void setRadius(double r) {
radius = r;
calculateDiameter();
}
Just setting the radius does not update every function that uses radius; you have to call those functions explicitly or else they remain at Java's default of 0.
I would also do any error checking at the Circle(radius) method; that way no negative numbers make it into the set of radii.

Outputting data from within an object (JAVA)

I'm trying to output some data from within an object to the console. Seems to be working, but below the data I'm getting a strange message.
Below is the code:
import java.text.DecimalFormat;
/**
* The Circle class calculates area, diameter, and circumference
*/
public class Circle {
DecimalFormat fmt = new DecimalFormat("#0.00");
// Fields
private double radius; // Holds the circle radius
private final double PI = 3.14159; // The formula for PI
/**
* Start Constructors
*/
public Circle(double rad) {
radius = rad;
System.out.println("The circle's radius is " + (fmt.format(radius)));
System.out.println("The circle's area is " + (fmt.format(PI * radius * radius)));
System.out.println("The circle's diameter is " + (fmt.format(radius * 2)));
System.out.println("The circle's circumference is " + (fmt.format(2 * PI * radius)));
}
}
The console output is:
The circle's radius is 2.00
The circle's area is 12.57
The circle's diameter is 4.00
The circle's circumference is 12.57
Circle#5115a298
What is the circle message?
Give your Circle class a decent toString() method override. You're seeing the return from Object's default version of this method.
#Override
public String toString() {
/* return a String that shows the "state" of this object */
}
You must have a System.out somewhere else that only has a Circle object as output. Then Hovercraft Full Of Eels' answer applies.
Btw: Math.PI already gives you Pi!

Categories

Resources