I am in the process of learning Java. Below is the program that I've been trying to compile, but cannot figure out why 'x' in line 38 provides the following error: 'cannot find symbol'. Any help would be greatly appreciated.
import java.util.Scanner;
class metropolis_HW2_7 {
static int count = 0;
public static void main(String[] args) {
double a = 0.;
double b = Math.PI;
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println(" Number of bins?");
int nbin = sc.nextInt();
if (nbin < 1)
System.exit(0);
double[] bin = new double[nbin];
System.out.println(" Number of histories to run?");
int N = sc.nextInt();
double dx = (b - a) / nbin;
for (int i = 0; i < N; i++) {
if (count == 0) {
double squiggle1 = Math.PI * Math.random();
double squiggle2 = Math.PI * Math.random();
double y_1 = 2 * squiggle1 + Math.sin(squiggle1);
double y_2 = 2 * squiggle2 + Math.sin(squiggle2);
if (y_2 < y_1) {
squiggle1 = squiggle2;
double x = squiggle2;
} else {
squiggle1 = squiggle1;
double x = squiggle2 / squiggle1;
}
count++;
} else {
double squiggle1;
double x = Sample(squiggle1);
}
int binNumber = (int) ((x - a) / dx);
bin[binNumber] += 1.;
}
double x = a - dx / 2.;
for (int i = 0; i < nbin; i++) {
x += dx;
bin[i] /= N * dx;
System.out.printf(" Bin %1$5d Sample for x = %2$7.5f is %3$7.5f vs %4$7.5f Ratio (%5$f) \n", i, x, bin[i], PDF(x), bin[i] / PDF(x));
}
}
}
static double Sample(double squiggle1) {
double squiggle2 = Math.PI * Math.random();
double y_1 = 2 * squiggle1 + Math.sin(squiggle1);
double y_2 = 2 * squiggle2 + Math.sin(squiggle2);
if (y_2 < y_1) {
squiggle1 = squiggle2;
return squiggle2;
} else {
squiggle1 = squiggle1;
return squiggle2 / squiggle1;
}
count++;
}
static double PDF(double x) {
return (2 * x + Math.sin(x)) / (Math.pow(Math.PI, 2) + 2);
}
}
Variables only exist inside the scope (between { and }) they're declared in. You have three different variables called x, and none of them exist when the line int binNumber=(int)((x-a)/dx); is executed.
Declare a variable outside the if statements, and then assign it inside it, something like this: (I've removed most of your code to make this example clearer; obvious you still need it)
double x;
if (count==0) {
if (y_2<y_1) {
x=squiggle2;
} else {
x=squiggle2/squiggle1;
}
} else {
x=Sample(squiggle1);
}
int binNumber=(int)((x-a)/dx);
Declare double x variable globally.You are declared in else part thats why it could not find the variable.
Scope variable Example:
int a = 80; // Create a global variable "a"
void setup() {
size(640, 360);
background(0);
stroke(255);
noLoop();
}
void draw() {
// Draw a line using the global variable "a"
line(a, 0, a, height);
// Create a new variable "a" local to the for() statement
for (int a = 120; a < 200; a += 2) {
line(a, 0, a, height);
}
// Create a new variable "a" local to the draw() function
int a = 300;
// Draw a line using the new local variable "a"
line(a, 0, a, height);
// Make a call to the custom function drawAnotherLine()
drawAnotherLine();
// Make a call to the custom function setYetAnotherLine()
drawYetAnotherLine();
}
void drawAnotherLine() {
// Create a new variable "a" local to this method
int a = 320;
// Draw a line using the local variable "a"
line(a, 0, a, height);
}
void drawYetAnotherLine() {
// Because no new local variable "a" is set,
// this line draws using the original global
// variable "a", which is set to the value 80.
line(a+2, 0, a+2, height);
}
The variable x is not declared in the scope in which it is used at that line. You are defining and assigning the double x inside two different if-blocks. Try declaring the variable in a broader scope (say, before the if-block, then assign it locally. Then it will be accessible in all 3 places.
Here's a simple example to explain what I mean:
void method()
{
if (2 > 1)
double x = 2;
else
double x = 3;
System.out.println(x); //ERROR, because x is out of scope
}
So change it to
void method()
{
double x = 0;
if (2 > 1)
x = 2;
else
x = 3;
System.out.println(x); //No error; x is referenced in the same scope in which it is declared
}
Related
public class Triangle {
double area;
int height;
int length;
public static void main(String [] args) {
int x = 0;
Triangle [ ] ta = new Triangle[4];
while ( x < 4 ) {
ta[x] = new Triangle();
ta[x].height = (x + 1) * 2;
ta[x].length = x + 4;
ta[x].setArea();
System.out.print("triangle "+x+", area");
System.out.println(" = " + ta[x].area);
x = x + 1;
}
int y = x;
x = 27;
Triangle t5 = ta[2];
ta[2].area = 343;
System.out.print("y = " + y);
System.out.println(", t5 area = "+ t5.area);
}
void setArea() {
ta[x].area = (height * length) / 2;
}
}
$javac Triangle.java
Triangle.java:25: error: cannot find symbol
ta[x].area = (height * length) / 2;
^
symbol: variable ta
location: class Triangle
Triangle.java:25: error: cannot find symbol
ta[x].area = (height * length) / 2;
^
symbol: variable x
location: class Triangle
2 errors
Of course I soon find that I need to take "ta[x]." thing off the setArea method, that's clear, but now I'm wondering why I cannot put a previously-declared Triangle array before that area function.
Is it because within the method, all things are local and you can't use variables which aren't declared in that method even if you've already declared them in other parts of code? Thank you guys.
x ta are local variable their scope are limited their respective function outside the scope you can not reference it.
Just pass the reference.
public class Triangle {
double area;
int height;
int length;
public static void main(String [] args) {
int x = 0;
Triangle [ ] ta = new Triangle[4];
while ( x < 4 ) {
ta[x] = new Triangle();
ta[x].height = (x + 1) * 2;
ta[x].length = x + 4;
ta[x].setArea(ta[x]);
System.out.print("triangle "+x+", area");
System.out.println(" = " + ta[x].area);
x = x + 1;
}
int y = x;
x = 27;
Triangle t5 = ta[2];
ta[2].area = 343;
System.out.print("y = " + y);
System.out.println(", t5 area = "+ t5.area);
}
void setArea(Triangle t) {
t.area = (height * length) / 2;
}
}
ta,x variable scope limited to Main() funtion
The question you have asked is related to the concept of scope of a variable in java.
Any variable declared inside {}, can be accessible inside those{} only. Outside the {},variables are not accessible.
In your code area is instance variable of class Triangle having length and height as instance variables.
So to calculate area you can directly use length and height. like
area=length*height
To calculate the area of perticular object call it through that object or you can pass triangle object as mentioned in previous post posted by user207421
You have couple of the problems in the snippet. Let me show you:
It's better to use immutable objects whenever it's possible. Imagine if someone will use your Triangle and forget to invoke setArea();
One of OOP's principles is encapsulation, so you should avoid access to the class's variables directly (only with getters);
In general, you should store minimum information. E.g. setArea() should be moved directly to the Triangle class. Moreover, it's pretty simple to calculate and it's better to do it
And finally look at division operation; before doing / you have to cast the result to the double. If you do (int + int) / int - the result will always be an integer.
Please check my solution:
// class is final (this is not mandatory)
public final class Triangle {
// variables are final (in general this is good approach)
// variables are private (access only via getters)
private final int width;
private final int height;
public Triangle(int width, int height) {
this.width = width;
this.height = height;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
// 2.0 is very important, here we cast (width * height) to double before division
public double getArea() {
return (width * height) / 2.0;
}
}
public class Main {
public static void main(String... args) {
Triangle[] triangles = createTriangles(4);
print(triangles);
}
private static Triangle[] createTriangles(int total) {
Triangle[] triangles = new Triangle[total];
// for loops letters like i,j,k are more common (x is mostly to 2D)
for (int i = 0; i < triangles.length; i++) {
int width = i + 4;
int height = (i + 1) * 2;
triangles[i] = new Triangle(width, height);
}
return triangles;
}
private static void print(Triangle... triangles) {
if (triangles != null)
for (int i = 0; i < triangles.length; i++)
System.out.format(Locale.ENGLISH, "triangle %d, area = %.2f",
i, triangles[i].getArea());
}
}
The setArea() mehtod is part of the class triangle,so there is no issue in calculating area of a trisngle.
public class Triangle {
double area;
int height;
int length;
public double setArea(){
return area=(length*height)/2;
}
public static void main(String[] args) {
int x=0;
Triangle [ ] ta = new Triangle[4];
while ( x < 4 ) {
ta[x] = new Triangle();
ta[x].height = (x + 1) * 2;
ta[x].length = x + 4;
ta[x].setArea();
System.out.print("triangle "+x+", area");
System.out.println(" = " + ta[x].area);
x = x + 1;
}
int y = x;
x = 27;
Triangle t5 = ta[2];
ta[2].area = 343;
System.out.print("y = " + y);
System.out.println(", t5 area = "+ t5.area);
}
}
I have a class called SimplePolygon that creates a polygon with coordinates provided by the user. I am trying to define a method to compute the area of the polygon. It's an assignment and course instructor wants us to use the following formula to compute the area.
I can use either formula. I chose the right one.
My code gives me the wrong area. I don't know what's wrong.
public class SimplePolygon implements Polygon {
protected int n; // number of vertices of the polygon
protected Point2D.Double[] vertices; // vertices[0..n-1] around the polygon
public double area() throws NonSimplePolygonException {
try
{
if(isSimple()==false)
throw new NonSimplePolygonException();
else
{
double sum = 0;
for(int i = 0; i < vertices.length - 1; i++)
if(i == 0)
sum += vertices[i].x * (vertices[i+1].y - vertices[vertices.length - 1].y);
else
sum += vertices[i].x * (vertices[i+1].y - vertices[i-1].y);
double area = 0.5 * Math.abs(sum);
return area;
}
}
catch(NonSimplePolygonException e)
{
System.out.println("The Polygon is not simple.");
}
return 0.0;
}
The following is a tester code. The polygon is a rectangle with area 2, but the output is 2.5
Point2D.Double a = new Point2D.Double(1,1);
Point2D.Double b = new Point2D.Double(3,1);
Point2D.Double c = new Point2D.Double(3,2);
Point2D.Double d = new Point2D.Double(1,2);
SimplePolygon poly = new SimplePolygon(4);
poly.vertices[0] = a;
poly.vertices[1] = b;
poly.vertices[2] = c;
poly.vertices[3] = d;
System.out.println(poly.area());
Now that you've fixed the trivial boundary case, you're missing another boundary and your loop is wrong. Corrected code with debug:
public double area()
{
double sum = 0;
for (int i = 0; i < vertices.length ; i++)
{
if (i == 0)
{
System.out.println(vertices[i].x + "x" + (vertices[i + 1].y + "-" + vertices[vertices.length - 1].y));
sum += vertices[i].x * (vertices[i + 1].y - vertices[vertices.length - 1].y);
}
else if (i == vertices.length - 1)
{
System.out.println(vertices[i].x + "x" + (vertices[0].y + "-" + vertices[i - 1].y));
sum += vertices[i].x * (vertices[0].y - vertices[i - 1].y);
}
else
{
System.out.println(vertices[i].x + "x" + (vertices[i + 1].y + "-" + vertices[i - 1].y));
sum += vertices[i].x * (vertices[i + 1].y - vertices[i - 1].y);
}
}
double area = 0.5 * Math.abs(sum);
return area;
}
There is one missing term from the sum: vertices[n-1].x * (vertices[0].y - vertices[n-2].y).
Before the edit of the question there was also a problem with the first term:
Furthermore, if i==0 the term should be vertices[i].x * (vertices[i+1].y - vertices[n-1].y).
Assuming that n is equal to vertices.length.
The simplest way to code the loop is probably:
n = vertices.length;
sum =0;
for (int i = 0; i < n; i++) {
sum += vertices[i].x * (vertices[(i + 1) % n].y - vertices[(i + n - 1) % n].y);
}
I found another way,
Add first element again into polygon array
So that we can avoid "Out of bound" case as well as many If conditions.
Here is my solution:
public class PolygonArea {
public static void main(String[] args) {
PolygonArea p = new PolygonArea();
System.out.println(p.calculateArea());
}
Point[] points = new Point[5];
public double calculateArea() {
points[0] = new Point("A", 4, 10);
points[1] = new Point("B", 9, 7);
points[2] = new Point("C", 11, 2);
points[3] = new Point("D", 2, 2);
/** Add first entry again to polygon */
points[4] = new Point("A", 4, 10);
double sum = 0.0;
for (int i = 0; i < points.length - 1; ++i) {
sum += (points[i].X * points[i + 1].Y) - (points[i + 1].X * points[i].Y);
}
return Math.abs(sum / 2);
}
class Point {
final String _ID;
final int X;
final int Y;
public Point(String id, int x, int y) {
_ID = id;
X = x;
Y = y;
}
}
}
In my class, we are given the task as follows:
For this assignment you will attempt to make a program for computing the overlapping area of a set of shapes, implementing Monte Carlo integration, as discussed in class.
Make AreaEstimator.java, a program that estimates the area of overlap of an arbitrary number of circles and triangles using randomized estimation. The program's arguments will be the number of randomly-generated points to be used in this trial, followed by the coordinates of the points that define the shapes. For example,
java AreaEstimator 1000000 circle 2.0 2.0 1.0 triangle 1.0 1.0 2.5 3.0 2.0 -3.0 circle 2.5 1.0 3.0
would generate one million random points to estimate the overlap of a triangle whose vertices are ( 1.0, 1.0 ), ( 2.5, 3.0 ), ( 2.0, -3.0 ), with two circles whose centers are at ( 2.0, 2.0 ) and ( 2.5, 1.0 ), and whose radii are 1.0 and 3.0, respectively.
Here is my code for the Circle class:
public class Circle {
private double xcenter;
private double ycenter;
private double radius;
private double xcmax;
private double xcmin;
private double ycmax;
private double ycmin;
public Circle ( double xcenter, double ycenter, double radius){
if(radius <= 0){
throw new IllegalArgumentException();
}
this.xcenter = xcenter;
this.ycenter = ycenter;
this.radius = radius;
}
public void maxAndMinCircle (){ //find the minimun and maximum for the plane according to this circle
xcmax = (this.xcenter + this.radius);
ycmax = (this.ycenter + this.radius);
xcmin = (this.xcenter - this.radius);
ycmin = (this.ycenter - this.radius);
}
public double getXCMax (){
return xcmax;
}
public double getYCMax () {
return ycmax;
}
public double getXCMin() {
return xcmin;
}
public double getYCMin(){
return ycmin;
}
public boolean outsideCircle(double randX, double randY){ // find if the random point passed thru is in this circle
double distance = Math.sqrt((randX-this.xcenter)*(randX-this.xcenter) + (randY-this.ycenter) * (randY - this.ycenter));
return distance >= radius;
}}
The Triangle Class:
public class Triangle {
private double cornerx1;
private double cornery1;
private double cornerx2;
private double cornery2;
private double cornerx3;
private double cornery3;
private double xtmax;
private double xtmin;
private double ytmax;
private double ytmin;
private Double[] corners;
public Triangle (double cornerx1, double cornery1, double cornerx2, double cornery2, double cornerx3, double cornery3){
corners = new Double [6];
corners[0] = cornerx1;
corners[1] = cornery1;
corners[2] = cornerx2;
corners[3] = cornery2;
corners[4] = cornerx3;
corners[5] = cornery3;
}
public void maxAndMinTriangle (){ // find the minimum and maximum of the plane according to this triangle
xtmax = corners[0];
for(int i=1;i < corners.length;i += 2){
if(corners[i] > xtmax){
xtmax = corners[i];
}
}
xtmin = corners[0];
for(int i=1;i < corners.length;i += 2){
if(corners[i] < xtmin){
xtmin = corners[i];
}
}
ytmax = corners[1];
for(int i=1;i < corners.length;i += 2){
if(corners[i] > ytmax){
ytmax = corners[i];
}
}
ytmin = corners[1];
for(int i=1;i < corners.length;i += 2){
if(corners[i] < ytmin){
ytmin = corners[i];
}
}
}
public double getXTMax (){
return xtmax;
}
public double getYTMax () {
return ytmax;
}
public double getXTMin() {
return xtmin;
}
public double getYTMin(){
return ytmin;
}
//public static boolean isLeft (double x1, double y1, double x2, double y2, double x3, double y3){
//return ( 0 <= ( ( x2 - x1 ) * ( y - y1) )- (( y2 - y1) * ( x - x1)));
//}
public boolean isLeft1 (double randX, double randY){ // find if this point is to the left of the first line
return ( 0 <= ( ( corners[2] - corners[0] ) * ( randY - corners[1]) )- (( corners[3] - corners[1]) * ( randX - corners[0])));
}
public boolean isLeft2 (double randX, double randY){ // find if this point is to the left of the second line
return ( 0 <= ( ( corners[4] - corners[0]) * ( randY - corners[1]) )- (( corners[5] - corners[1]) * ( randX - corners[0])));
}
public boolean isLeft3 (double randX, double randY){ // find if this point is to the left of the third line
return ( 0 <= ( ( corners[4] - corners[2] ) * ( randY - corners[3]) )- (( corners[5] - corners[3]) * ( randX - corners[2])));
}
public boolean outsideTriangle ( double randX, double randY ){ // find if this point is inside of the triangle
int counter = 0;
if (isLeft1(randX,randY)){
counter++;
}
if (isLeft2(randX,randY)){
counter++;
}
if (isLeft3(randX,randY)){
counter++;
}
return counter == 2; // must be to the left of exactly 2 of the lines
}}
And then the AreaEstimator class:
public class AreaEstimator{
public static double[] maxAndMinValues (Circle[] circles,Triangle[] triangles){
// find maximum and minimum values according to all of the triangles and circles
double xmax = -100;
double ymax = -100;
double xmin = 100;
double ymin = 100;
for (int l=0; l < circles.length; l++){
if (xmax < circles[l].getXCMax()){
xmax = circles[l].getXCMax();
}
if (ymax < circles[l].getYCMax()){
ymax = circles[l].getYCMax();
}
if (xmin > circles[l].getXCMin()){
xmin = circles[l].getXCMin();
}
if (ymin > circles[l].getYCMin()){
ymin = circles[l].getYCMin();
}
}
for ( int m = 0; m < triangles.length; m++){
if(xmax < triangles[m].getXTMax()){
xmax = triangles[m].getXTMax();
}
if(ymax < triangles[m].getYTMax()){
ymax = triangles[m].getYTMax();
}
if(xmin > triangles[m].getXTMin()){
xmin = triangles[m].getXTMin();
}
if(ymin > triangles[m].getYTMin()){
ymin = triangles[m].getYTMin();
}
}
double[] result = new double [4];
result[0] = xmax;
result[1] = ymax;
result[2] = xmin;
result[3] = ymin;
return result;
}
public static void main (String[] args) {
double numThrows = Integer.parseInt(args[0]); // initialize amount of throws
if (numThrows <= 0){
throw new IllegalArgumentException();
}
int countCircles = 0; // find the amount of circles given
for ( int i = 1; i<args.length; i++){
if(args[i].equals("circle")){
countCircles++;
}
}
Circle[] circles = new Circle [countCircles];
for ( int i = 1; i<args.length; i++){
if (args[i].equals("circle")){
for ( int k = 0; k< countCircles; k++){
double xcenter = Double.parseDouble(args[i+1]);
double ycenter = Double.parseDouble(args[i+2]);
double radius = Double.parseDouble(args[i+3]);
circles[k] = new Circle (xcenter, ycenter, radius); //values associated with this circle
circles[k].maxAndMinCircle();//max and min value of the circle itself
}
}
}
int countTriangles = 0; // find the amount of the triangles given
for ( int i = 1; i < args.length; i++){
if(args[i].equals("triangle")){
countTriangles++;
}
}
Triangle[] triangles = new Triangle [countTriangles];
for ( int i = 1; i<args.length; i++){
if (args[i].equals("triangle")){
for ( int p = 0; p< countTriangles; p++){
double cornerx1 = Double.parseDouble(args[i+1]);
double cornery1 = Double.parseDouble(args[i+2]);
double cornerx2 = Double.parseDouble(args[i+3]);
double cornery2 = Double.parseDouble(args[i+4]);
double cornerx3 = Double.parseDouble(args[i+5]);
double cornery3 = Double.parseDouble(args[i+6]);
triangles[p] = new Triangle (cornerx1, cornery1, cornerx2, cornery2, cornerx3, cornery3);
//values associated with this triangle
triangles[p].maxAndMinTriangle(); //max and min value of the triangle itself
}
}
}
boolean dartsInOverlap = true;
double countInOverlap = 0; // initialize amount of darts in the overlapping shape
double[]result = maxAndMinValues(circles,triangles);
for(int i= 0;i < numThrows;i++){
double randX= (Math.random() * (result[0]-result[2]) + result[2]) ; // generate a random x value
double randY= (Math.random() * (result[1]-result[3])+ result[3]); // generate a random y value
for ( int h = 0; h < circles.length && dartsInOverlap; h++){
if (circles[h].outsideCircle(randX, randY)){
dartsInOverlap = false; // if the point is outside of the circle, it returns false
}
}
for ( int q = 0; q < triangles.length && dartsInOverlap; q++){
if (triangles[q].outsideTriangle(randX, randY)){
dartsInOverlap = false; // if the point is outside of the triangle, it returns false
}
}
if (dartsInOverlap){
countInOverlap++; // counts up the amount of points in the overlapping shape
}
dartsInOverlap = true;
}
System.out.println("This many darts were in the overlap between the shapes:" + countInOverlap);
// counts up the amount of points in the overlapping shape
System.out.println("The estimated overlapped areas is" + (result[0]-result[2])*(result[1]-result[3]) *(countInOverlap/numThrows));
//finds estimated area
}}
My code has worked for a few test cases, if in the command line there is only a circle and triangle entered, or only a sole circle. A triangle by itself or any other combination will give me answers far from the desired area estimation. I have looked and reviewed my code, and it all seems logical. So, where in my code could the problem persist? Any help would be appreciated.
There is at least a typo in maxAndMinTriangle. You wrote a 1 where you need a 0
xtmax = corners[0];
for(int i=1;i < corners.length;i += 2){
...
xtmin = corners[0];
for(int i=1;i < corners.length;i += 2){
it should be
xtmax = corners[0];
for(int i=0;i < corners.length;i += 2){
...
xtmin = corners[0];
for(int i=0;i < corners.length;i += 2){
The Mandelbrot set has been a favorite of mine for many years. I've successfully created it in Pascal years ago and more recently on a TI-83 graphing calculator (Java renders it juuuuust a bit faster).
Since complex numbers are involved, I took a version from a text that extends RecursiveAction using a BufferedImage and ForkJoinPool (without understanding the those concepts and the overall implementation) and, using routines I developed a few months ago, modified (the heck out of) the code that does the point-plotting so that it looks more like complex numbers are involved.
Original:
public class MandelbrotTask extends RecursiveAction {
...
public void render() {
...
for (int x = xStart; x <= xEnd; x++) {
for (int y = yStart; y <= yEnd; y++) {
double r = x * zoomFactor / image.getWidth() - zoomFactor / 2 + offsetX;
double i = y * zoomFactor / image.getHeight() - zoomFactor / 2 + offsetY;
double zr = 0, zi = 0;
int iter;
for (iter = 0; iter < maxIter; iter++) {
double nzr = zr * zr - zi * zi + r;
double nzi = 2 * zr * zi + i;
if (nzr * nzr + nzi * nzi > escapeRadius * escapeRadius)
break;
zr = nzr;
zi = nzi;
}
image.setRGB(x, y, Color.HSBtoRGB(0.5f * iter / maxIter, 1.0f, 1.0f));
}
}
My revised, somewhat-cleaner code:
for (int x = xStart; x <= xEnd; x++) {
for (int y = yStart; y <= yEnd; y++) {
z1 = new ComplexNumber(x * dx - zoomFactor / 2 + offsetX,
y * dy - zoomFactor / 2 + offsetY);
z0 = new ComplexNumber(0,0);
int iter;
for (iter = 0; iter < maxIter; iter++) {
nz = cAdd(cMult(z0,z0),z1);
if (cAbs(nz) > escapeRadius )
break;
z0 = nz;
}
image.setRGB(x, y, Color.HSBtoRGB(0.5f * iter / maxIter, 1.0f, 1.0f));
}
}
My only question is how to get rid of "new" on the two lines defining z1 and z0. It seems like I'm wasting a ton of memory since the two objects get "newed" a total of 1,000,000+ times during the almost 25,000 executions of the above block of code, though there's no problem as is.
I know I need new at least once inside the method, but if I put the statements (shown below) outside the loop (and either inside or outside render()), if I omit new from those two lines defining z1 and z0 in the block of code above, I get the error
"cannot find symbol: method ComplexNumber(double,double) location: class MandelbrotTask."
z1 = new ComplexNumber();
z0 = new ComplexNumber();
---- edit 10:21 12/26/13
Here is the part of the ComplexNumber class that is invovled. The constructor call ComplexNumber() sets real and imag-inary parts to 0.
class ComplexNumber {
public double real;
public double imag;
public ComplexNumber() {
real = 0.0;
imag = 0.0;
}
public ComplexNumber(double r, double i) {
this.real = r;
this.imag = i;
}
public static ComplexNumber cAdd(ComplexNumber a, ComplexNumber b) {
return new ComplexNumber(a.real + b.real, a.imag + b.imag);
}
public static ComplexNumber cMult(ComplexNumber a, ComplexNumber b) {
return new ComplexNumber(a.real * b.real - a.imag * b.imag, a.real * b.imag + a.imag * b.real);
}
public static double sqr(double x) {
return x * x;
}
public static double cAbs(ComplexNumber z) {
return Math.sqrt(sqr(z.real) + sqr(z.imag));
}
}
Got a few upvotes, so I am converting my comment to an answer. If you want to avoid reinstantiating over and over again inside the loop, your only way out is to create setter methods for your ComplexNumber class:
public void setReal(double real) { this.real = real; }
public void setImaginary(double im) { this.im = im; }
public void setTo(double real, double im) { setReal(real); setImaginary(im); }
I am assuming your class has fields called real and im.
Moreover, if you can't modify the class itself, you should extend it by creating a wrapper class of the form class MyComplexNumber extends ComplexNumber, and then implement the setter methods for MyComplexNumber.
Types are good but I don't see a need for them here if your problem is memory.
Try creating methods inside ComplexNumber such as
public void init(){
//clear and reset all variables inside ComplexNumber
...
}
and
public void set(param1, param2...){
//set required variables
...
}
Then use set() and init() respectively inside your loop instead of creating a new instance each time. This works if you don't need references to the objects created inside the loop.
I should have pointed out in advance that the following code--with no new, no setters--accomplishes the task:
z1.real = x * dx - zoomFactor / 2 + offsetX;
z1.imag = y * dy - zoomFactor / 2 + offsetY;
z0.real = 0;
z0.imag = 0;
I was just hoping for something along the lines of my original revised code, one line per complex number.
====================
Here's me extending ComplexNumber class into a RealNumber class (which seems a bit backward, but...):
class RealNumber extends ComplexNumber
{ // RealNumber IS-A subclass ...
RealNumber() {}
RealNumber(double r) {
super.imag = 0; // ... THIS kind of subclass ...
super.real = r; // ... of ComplexNumber!
}
}
============================
Hey, #Chthonic, this worked:
public void setReal(double real) { this.real = real; }
public void setImaginary(double imag) { this.imag = imag; }
public void makeComplex(double real, double imag) { setReal(real); setImaginary(imag); }
...
z1 = new ComplexNumber();
z0 = new ComplexNumber(); // before loop
...
z1.makeComplex(x * dx - zoomFactor / 2 + offsetX,y * dy - zoomFactor / 2 + offsetY);
z0.makeComplex(0, 0);
THANKS for the idea. I'm not certain I got exactly why my original z1 = new Complex... didn't work, but I'll think about the replies.
(I just realized that I "learned" something that I already "knew". Happens all the time.)
I am trying to write a program like bouncingBall. but i generated N obstacles in the screen. Each time the ball touch the obstacle, the obstacle disappears and shows up at another random place. i am trying to use 2 dimension array to store the random-gernerated obstacles' point (x,y).
Right now if I input N>50, it gives me outofbound.
But what i want is to store point from (0,0) to (50,50)..what should I do achieve this with 2-dimentional array?
Thanks!
import java.util.ArrayList;
public class BouncingBall {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Usage: java BouncingBall N");
System.exit(0);
}
int N = Integer.parseInt(args[0]);
if (N > 2500) {
System.out.println("Usage: java BouncingBall N<=2500");
System.exit(0);
}
double[][] myArray = new double[50][50];
// set the scale of the coordinate system
StdDraw.setXscale(-1.0, 1.0);
StdDraw.setYscale(-1.0, 1.0);
// initial values
double rx = 0.480, ry = 0.860; // position
double vx = 0.015, vy = 0.023; // velocity
double radius = 0.02; // radius
double x;
double y;
double a[] = new double[2];
StdDraw.setPenColor(StdDraw.WHITE);
StdDraw.filledSquare(0, 0, 1.0);
StdDraw.setPenColor(StdDraw.BLACK);
for(int i=0; i <= N; i++){
x = 2.0*(double)Math.random()-1.0;
y = 2.0*(double)Math.random()-1.0;
for (int t=0;t <50;t++){
for (int j=0;j <50;j++){
myArray[t][j]= x;
myArray[j][t]= y;
}
}
StdDraw.filledSquare(x, y, 0.02);
}
// main animation loop
while (true) {
// bounce off wall according to law of elastic collision
if (Math.abs(rx + vx) > 1.0 - radius) vx = -vx;
if (Math.abs(ry + vy) > 1.0 - radius) vy = -vy;
// clear the background
StdDraw.setPenColor(StdDraw.WHITE);
StdDraw.filledSquare(0, 0, 1.0);
StdDraw.clear();
StdDraw.setPenColor(StdDraw.BLACK);
for(int t=0; t <= N; t++){
for (int j=0;j <50;j++){
x = myArray[t][j];
y = myArray[j][t];
}
if ((Math.abs(rx + vx) > x - radius)||(Math.abs(ry + vy) > y - radius))
{ //if the ball touch the square
vx = -vx;
vy = -vy;
if (args.length == 2 && args[1].equals("-d")){
x = 2.0*(double)Math.random()-1.0; //new random x
y = 2.0*(double)Math.random()-1.0; //new random y
}else{
;
}
StdDraw.filledSquare(x, y, 0.02);
}
else{
StdDraw.filledSquare(x, y, 0.02); //if not touched, keep it.
}
}
rx = rx + vx;
ry = ry + vy;
StdDraw.filledCircle(rx, ry, radius);
// display and pause for 20 ms
StdDraw.show(20);
}
}
}
Imagine that the user inputs -1 for N, then x and y won't get a value because the loops bodies won't run.
Simple workaround: assign a default value to x and y (0 for example)
double x = 0;
double y = 0;
You need to initialize both x and y:
double x = 0;
double y = 0;
Your ArrayIndexOutOfBoundsException is occurring because you only define the array to be 50x50
double[][] myArray = new double[50][50];
yet access an index greater than that using t:
x = myArray[t][j];
you have to initialize your local variables, local variables dont get default values
int double x=0.0;
int double y=0.0;
would solve the compiler error.
if N>50
for (int t=0;t <50;t++){
for (int j=0;j <50;j++){
myArray[t][j]= x; // ArrayIndexOutOfBound Exection occurs here
myArray[j][t]= y;
}
}