Sphere volume method not working - java

I have tried many different calculations for trying to get my sphere volume method to work.
My Sphere class is extended from Circle, to get the area from circle, as well as implements my Shape3D interface which allows me to use my volume method.
However, I have tried all of these different formulas for my method and nothing gives me back an accurate volume of a sphere. It is always drastically off.
The one that gets the closest is (4*22*radius * radius * radius )/(3*7); but it is still off.
//return (4/3) * super.area() * radius;
//return (Double)((4*22*getRadius()*getRadius()*getRadius() )/(3*7));
//return (4*22*radius * radius * radius )/(3*7);
//return ( (4/3) * (Math.pow(getRadius(), 3) ) / (Math.PI) );
//return (getRadius() * getRadius() * getRadius() ) * (Math.PI) * (4/3);
//return ( super.area() * getRadius() ) * (4/3);
I am going to attach my code for my Shape abstract class, my Circle class, and my Sphere class, as well as my Shape3D interface.
Maybe I have overlooked something obvious. When I set the radius though and get it the radius returns back normal. So I am not sure why every one of these if completely off.
public class Main {
public static void main(String[] args) {
System.out.println(volume());
}
public static double volume() {
double vol;
double x = 4/3;
double y = Math.pow(30.0, 3);
double z = Math.PI;
vol = y * z * x;
return vol;
//return (4/3) * super.area() * radius;
//return (Double)((4*22*getRadius()*getRadius()*getRadius() )/(3*7));
//return (4*22*radius * radius * radius )/(3*7);
//return ( (4/3) * (Math.pow(getRadius(), 3) ) / (Math.PI) );
//return (getRadius() * getRadius() * getRadius() ) * (Math.PI) * (4/3);
//return ( super.area() * getRadius() ) * (4/3);
}// end sphere volume
}

Here is a simple java test program for calculating the volume of a sphere that you can use as reference for what you are doing wrong which is that 4/3 returns an int, 1 rather than a double representation of and therefore messes up your calculation:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// notice the descriptive variable names rather than x, y and z
double radius;
double diameter;
double volume;
System.out.print("Enter the radius of the sphere:");
radius = scanner.nextDouble();
diameter = (radius * 2.0);
volume = (4.0 / 3.0) * Math.PI * Math.pow(radius, 3); // instead of 4/3 in yours
System.out.println("The volume is: " + String.format("%.1f", volume));
}
}
Example Usage:
Enter the radius of the sphere: 5
The volume is: 523.6
To confirm it is working correctly you can use Google's sphere volume calculator and confirm it gives the same value:

Instead of
double x = 4/3;
Try
double x = 4.0/3.0;
or
double x = 4.0/3;
or
double x = 4/3.0;

Related

Overloading Method with user input

I am new to java and I have an assignment to write a circle calculator program that computes the area, circumference and diameter of a circle. The program will accept input number (radius) and that number will be used to get the area, circumference and diameter of a circle. This time you are going to use separate methods for each computation. For example, to get the value of area you need to write method area that has radius parameter and returns double value.
I'm not sure if my code is right, I am getting zero values.
import java.util.Scanner;
class Circle {
static Scanner sc = new Scanner(System.in);
private double radius;
public double getRadius() {
System.out.print("Enter the radius: ");
int radius = sc.nextInt();
return radius;
}
public void setRadius(double radius) {
}
public double diameter() {
double diameter = 2 * radius;
return diameter;
}
public double area() {
double area = Math.PI * (radius * radius);
return area;
}
public double circumference() {
double circumference = 2 * Math.PI * radius;
return circumference;
}
}
public class Methods {
public static void main(String[] args) {
Circle circleTest = new Circle();
System.out.printf("Radius: %.1f %n", circleTest.getRadius());
System.out.printf("Diameter: %.1f %n", circleTest.diameter());
System.out.printf("Area: %.1f %n", circleTest.area());
System.out.printf("Circumference: %.1f %n", circleTest.circumference());
}
}
Inside your getRadius method you are setting a local variable to the value entered by the user:
int radius = sc.nextInt();
When you calculate the diameter, area, circumference you're using an instance variable - for example:
double diameter = 2 * radius;
Since you never set the instance variable its value by default is 0.

Calculate the area of a circle using a method

Why won't this compile?
It seems there is a mistake in return = n1 * (n2*n2); but I cannot see it.
I am trying to calculate the area of a circle with a method
package week2lab;
public class Week2Lab {
public static void main(String[] args)
{
double Pi = 5;
double Radius = 3.141;
double CircleArea = getCircleArea(Pi, Radius);
System.out.println("The Area is " + CircleArea);
}
static double getCircleArea(double n1, double n2)
{
return = n1 * (n2*n2);
}
}
use return n1 * (n2*n2); instead of return = n1 * (n2*n2);
You should not use = sign in return statement
You don't use a = sign after return. Just remove that. And you seem to have swapped the name(s) Pi and Radius in your post. Additionally, Java already has a PI constant1. So you could do something like,
static double getCircleArea(double radius) {
return Math.PI * (radius * radius);
}
1And in that spirit, please use meaningful variable names.

"Error: '.class' expected"

So I'm new to Java, and my most recent piece of code has not worked. I get error: not a statement twice and error: ';' expected once.
If I try radius=double;, it appears with the error: Error: '.class' expected on line 8, where the caret shows under the semi-colon.
I am not sure what is wrong, but here is my code. It isn't long... thank-you in advance.
import java.util.Scanner;
import static java.lang.Math;
public class Formula {
public static void main(String[] args);{
double = radius;
Scanner in = new Scanner(System.in);
System.out.print("Radius of circle (cm) :> ");
double radius = in.nextDouble();
System.out.print("Area of circle :> " + Math.PI * Math.pow(radius,2));
System.out.print("Circumference of circle :> " + 2 * Math.PI * radius);
System.out.print("Surface area the sphere with that radius :> " + 4 * Math.PI * Math.pow(radius,2));
System.out.print("Volume of sphere with that radius :> " + 4/3 * (radius * Math.pow(radius,2)));
}
}
Change
double = radius;
to
double radius = 0;
and remove the ; after the public static void main(String[] args); method definition.
Also, in the statement double radius = in.nextDouble(); you will have to remove the double keyword, since you have already defined a variable with the same name.
You have three problems with your code:
Remove the semi-colon on the declaration of the main method.
public static void main(String[] args)
Your second problem is that you do not have a reference for your double variable. All variables must have references. Consider your code which should be:
double radius = 0;
double is the data type and radius is the reference. In other words, double is the type of variable and radius is the name of the variable.
Your third problem is this line.
double radium = in.nextDouble();
You should change it to:
radius = in.nextDouble();
All variables must be correctly referenced. Also by declaring the variable again, you're shadowing the old one.
It would be better to instead of initializing the variable then initializing it again, delete your line:
double = radius
or if you changed it to what I said above, remove
double radius = 0;
Remove the ';' from your main
public static void main(String[] args);
to
public static void main(String[] args)
Your variable declarations are confused: double = radius; doesn't make sense because double is a type, not a variable (and variable declarations look like type identifier = value; not type = identifier; or identifier = type;), and you declare but never use the radium variable. Should be something like:
Scanner in = new Scanner(System.in);
System.out.print("Radius of circle (cm) :> ");
double radius = in.nextDouble();
System.out.print("Area of circle :> " + Math.PI * Math.pow(radius,2));
System.out.print("Circumference of circle :> " + 2 * Math.PI * radius);
System.out.print("Surface area the sphere with that radius :> " + 4 * Math.PI * Math.pow(radius,2));
System.out.print("Volume of sphere with that radius :> " + 4/3 * (radius * Math.pow(radius,2)));
And you shouldn't have that ; at the end of your main method declaration line.
culprit (i.e. wrong way of declaring a variable):
double = radius;
should be something of this form:
double radius = 0;
However, I see you are using radius again, but this time correctly, to get the value entered by the user from the console, so you can safely delete the culprit statement and it should work.
The code that you have :
import java.util.Scanner;
import static java.lang.Math;
public class Formula
{
public static void main(String[] args);
{
double = radius;
Scanner in = new Scanner(System.in);
System.out.print("Radius of circle (cm) :> ");
double radius = in.nextDouble();
System.out.print("Area of circle :> " + Math.PI * Math.pow(radius,2));
System.out.print("Circumference of circle :> " + 2 * Math.PI * radius);
System.out.print("Surface area the sphere with that radius :> " + 4 * Math.PI * Math.pow(radius,2));
System.out.print("Volume of sphere with that radius :> " + 4/3 * (radius * Math.pow(radius,2)));
}
}
What it should look like :
import java.util.Scanner;
import static java.lang.Math;
public class Formula
{
public static void main(String[] args) {
double radius = 0;
Scanner in = new Scanner(System.in);
System.out.print("Radius of circle (cm) :> ");
radius = in.nextDouble();
System.out.print("Area of circle :> " + Math.PI * Math.pow(radius,2));
System.out.print("Circumference of circle :> " + 2 * Math.PI * radius);
System.out.print("Surface area the sphere with that radius :> " + 4 * Math.PI * Math.pow(radius,2));
System.out.print("Volume of sphere with that radius :> " + 4/3 * (radius * Math.pow(radius,2)));
}
}
You had a semicolon after your method, declaring a double needs to equal something, and you don't need to say double radius = in.nextDouble(); you just need radius = in.nextDouble();

Angle between two 3D vectors

I have a series of vertices (pink) that I want to rotate so that one edge of the pattern of vertices matches with the edge of the triangle (white).
To do this, I first create two vectors to represent the edges: floretAB and triangleAB (green). I then find the cross product of the two to get an axis around which I can rotate the vertices (red).
I then get the angle between the two vectors, and use that, with the rotation axis to create a quaternion. Finally, I rotate all the vertices around the quaternion.
Before rotation
_
What rotation should produce
_
However, although the vertices correctly rotate around the quaternion, the angle is not coming out correct, as illustrated here:
This is the code I'm using to get the angle between the two vectors. I don't understand what I'm doing wrong:
double[] cross = new double[3];
crossProduct(floretAB.mX, floretAB.mY, floretAB.mZ, triangleAB.mX, triangleAB.mY, triangleAB.mZ, cross);
double dot = dotProduct(floretAB.mX, floretAB.mY, floretAB.mZ, triangleAB.mX, triangleAB.mY, triangleAB.mZ);
double crossMag = Math.sqrt(cross[0]*cross[0] + cross[1]*cross[1] + cross[2]*cross[2]);
double angle = Math.atan2(crossMag, dot);
public static double dotProduct(double vector1X,double vector1Y,double vector1Z,double vector2X,double vector2Y,double vector2Z){
return vector1X*vector2X + vector1Y*vector2Y + vector1Z*vector2Z;
}
public static void crossProduct(double vector1X,double vector1Y,double vector1Z,double vector2X,double vector2Y,double vector2Z, double[] outputArray){
outputArray[0] = vector1Y*vector2Z - vector1Z*vector2Y;
outputArray[1] = vector1Z*vector2X - vector1X*vector2Z;
outputArray[2] = vector1X*vector2Y - vector1Y*vector2X;
}
Any help with this would be most appreciated as it is really bugging me.
Thanks, James
Edit: Here is the rest of the code:
// get floret p1,p2 vector
// get triangle p1,p2 vector
Vector3D floretAB = new Vector3D(florets3D[0], florets3D[7]);
// get triangle p1,p2 vector
Vector3D triangleAB = new Vector3D(triangle[0], triangle[1]);
// get rotation axis (cross) and angle (dot)
/*
double[] cross = new double[3];
crossProduct(floretAB.mX, floretAB.mY, floretAB.mZ, triangleAB.mX, triangleAB.mY, triangleAB.mZ, cross);
double dotMag = floretAB.getMagnitude() * triangleAB.getMagnitude();
double dot = dotProduct(floretAB.mX, floretAB.mY, floretAB.mZ, triangleAB.mX, triangleAB.mY, triangleAB.mZ) / dotMag;
double angle = Math.acos(dot);
*/
double[] cross = new double[3];
crossProduct(floretAB.mX, floretAB.mY, floretAB.mZ, triangleAB.mX, triangleAB.mY, triangleAB.mZ, cross);
double dot = dotProduct(floretAB.mX, floretAB.mY, floretAB.mZ, triangleAB.mX, triangleAB.mY, triangleAB.mZ);
double crossMag = Math.sqrt(cross[0]*cross[0] + cross[1]*cross[1] + cross[2]*cross[2]);
double angle = Math.atan2(crossMag, dot);
// rotate floret so p1,p2 vector matches with triangle p1,p2 vector
double[] newVerts = new double[3];
Quaternion quat = new Quaternion(cross[0], cross[1], cross[2], angle);
for(int i = 0;i<numfloretVerts;i++){
Vertex3D vert = florets3D[i];
quat.RotateVector(vert.getmX(), vert.getmY(), vert.getmZ(), newVerts);
vert.setmX(newVerts[0]);
vert.setmY(newVerts[1]);
vert.setmZ(newVerts[2]);
}
_
public class Vector3D {
public double mX;
public double mY;
public double mZ;
public Vertex3D point;
/**
* Constructs a vector from two points. The new vector is normalised
*
* #param point1
* #param point2
*/
public Vector3D(Vertex3D point1, Vertex3D point2){
mX = point2.getmX() - point1.getmX();
mY = point2.getmY() - point1.getmY();
mZ = point2.getmZ() - point1.getmZ();
normalise();
point = point1;
}
/**
* Normalises the vector
*/
public void normalise(){
double magnitude = Math.sqrt(mX*mX + mY*mY + mZ*mZ);
if(magnitude!=0){
mX /= magnitude;
mY /= magnitude;
mZ /= magnitude;
}
}
/**
*
* #return the magnitude of the vector
*/
public double getMagnitude(){
return Math.sqrt(mX*mX + mY*mY + mZ*mZ);
}
}
_
public class Quaternion {
private static final double TOLERANCE = 0.00001f;
double w;
double x;
double y;
double z;
public Quaternion(double axisX, double axisY, double axisZ, double angleInRadians){
setAxisAngle(axisX, axisY, axisZ, angleInRadians);
}
public void Normalise(){
// Don't normalize if we don't have to
double mag2 = w * w + x * x + y * y + z * z;
if (Math.abs(mag2) > TOLERANCE && Math.abs(mag2 - 1.0f) > TOLERANCE) {
double mag = (double) Math.sqrt(mag2);
w /= mag;
x /= mag;
y /= mag;
z /= mag;
}
}
public void getConjugate(double[] outputArray){
outputArray[0] = w;
outputArray[1] = -x;
outputArray[2] = -y;
outputArray[3] = -z;
}
public void Multiply(double[] aq, double[] rq, double[] outputArray){
outputArray[0] = aq[0] * rq[0] - aq[1] * rq[1] - aq[2] * rq[2] - aq[3] * rq[3];
outputArray[1] = aq[0] * rq[1] + aq[1] * rq[0] + aq[2] * rq[3] - aq[3] * rq[2];
outputArray[2] = aq[0] * rq[2] + aq[2] * rq[0] + aq[3] * rq[1] - aq[1] * rq[3];
outputArray[3] = aq[0] * rq[3] + aq[3] * rq[0] + aq[1] * rq[2] - aq[2] * rq[1];
}
private double[] vecQuat = new double[4];
private double[] resQuat = new double[4];
private double[] thisQuat = new double[4];
private double[] conj = new double[4];
/**
* Rotates a vector (or point) around this axis-angle
*
* #param vectorX the x component of the vector (or point)
* #param vectorY the y component of the vector (or point)
* #param vectorZ the z component of the vector (or point)
* #param outputArray the array in which the results will be stored
*/
public void RotateVector(double vectorX, double vectorY, double vectorZ, double[] outputArray){
vecQuat[0] = 0.0f;
vecQuat[1] = vectorX;
vecQuat[2] = vectorY;
vecQuat[3] = vectorZ;
thisQuat[0] = w;
thisQuat[1] = x;
thisQuat[2] = y;
thisQuat[3] = z;
getConjugate(conj);
Multiply(vecQuat,conj,resQuat);
Multiply(thisQuat,resQuat,vecQuat);
outputArray[0] = vecQuat[1];
outputArray[1] = vecQuat[2];
outputArray[2] = vecQuat[3];
}
/**
* set Quaternion by providing axis-angle form
*/
public void setAxisAngle(double axisX, double axisY, double axisZ, double angleInRadians){
w = (double) Math.cos( angleInRadians/2);
x = (double) (axisX * Math.sin( angleInRadians/2 ));
y = (double) (axisY * Math.sin( angleInRadians/2 ));
z = (double) (axisZ * Math.sin( angleInRadians/2 ));
Normalise();
}
}
I think you've overcomplicated your maths.
Given two unit vectors (you did say they were normalised) then the magnitude of the cross product is equal to sin(theta). There shouldn't be any need to invoke the dot product or atan2.
You possibly also need to normalise the cross product vector result too before you create the quaternion - it depends on your implementation of new Quaternion(x, y, z, theta) and whether it requires [x, y, z] to be normalised or not.
I think the problem is that you evaluate the angle in the wrong way.
If I understand correctly what are you trying to achieve, then you need the angle between 2 green lines. You correctly evaluate the dot product between 2 green lines using the definition:
(a, b) = a1*b1 + a2*b2 + a3*b3.
But dot product can also be evaluated like this:
(a, b) = |a|*|b|*cos(theta)
So you can evaluate cos(theta) - the cosine of angle between 2 green lines - like this:
cos(theta) = (a1*b1 + a2*b2 + a3*b3) / (|a|*|b|)
But I would use yet another approach. I would normalize both vectors at first (i.e. converted them to unit-vectors). You can do this by dividing each vector's component by the vector's length (sqrt(x1*x1 + y1*y1 + z1*z1)) Then you will have the following:
(aa, bb) = cos(theta)
where aa is normalized a and bb is normalized b.
I hope this helps.
The stated answers are correct for real numbers but can loose accuracy near certain angles when computed with floating point numbers. For arcos() when the angle is near zero or PI, and for arcsin() near pi/2 and –pi/2, as many a half the significant figures can be lost. A method that is more robust and only suffers a few rounding errors uniformly over the whole range from and including zero to and including PI, assuming the input vectors are unit length is:
public double AngleBetween(Vector3D a, Vector3D b)
{
return 2.0d * Math.atan((a-b).Length/(a+b).Length);
}
Note, this gives the unoriented angle between the two vectors. A reference for this and attributed to Kahan may be found at: http://www.cs.berkeley.edu/~wkahan/MathH110/Cross.pdf

how to use math.pi in java

I am having problems converting this formula V = 4/3 π r^3. I used Math.PI and Math.pow, but I get this error:
';' expected
Also, the diameter variable doesn't work. Is there an error there?
import java.util.Scanner;
import javax.swing.JOptionPane;
public class NumericTypes
{
public static void main (String [] args)
{
double radius;
double volume;
double diameter;
diameter = JOptionPane.showInputDialog("enter the diameter of a sphere.");
radius = diameter / 2;
volume = (4 / 3) Math.PI * Math.pow(radius, 3);
JOptionPane.showMessageDialog("The radius for the sphere is "+ radius
+ "and the volume of the sphere is ");
}
}
You're missing the multiplication operator. Also, you want to do 4/3 in floating point, not integer math.
volume = (4.0 / 3) * Math.PI * Math.pow(radius, 3);
^^ ^
Here is usage of Math.PI to find circumference of circle and Area
First we take Radius as a string in Message Box and convert it into integer
public class circle {
public static void main(String[] args) {
// TODO code application logic here
String rad;
float radius,area,circum;
rad = JOptionPane.showInputDialog("Enter the Radius of circle:");
radius = Integer.parseInt(rad);
area = (float) (Math.PI*radius*radius);
circum = (float) (2*Math.PI*radius);
JOptionPane.showMessageDialog(null, "Area: " + area,"AREA",JOptionPane.INFORMATION_MESSAGE);
JOptionPane.showMessageDialog(null, "circumference: " + circum, "Circumfernce",JOptionPane.INFORMATION_MESSAGE);
}
}
Replace
volume = (4 / 3) Math.PI * Math.pow(radius, 3);
With:
volume = (4 * Math.PI * Math.pow(radius, 3)) / 3;
Your diameter variable won't work because you're trying to store a String into a variable that will only accept a double. In order for it to work you will need to parse it
Ex:
diameter = Double.parseDouble(JOptionPane.showInputDialog("enter the diameter of a sphere.");

Categories