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;
}
}
Related
I'm trying to visualize Mandelbrot's set with processing, and it's the first time I do something like this. My approach is pretty simple.
I have a function Z, which is literally just the set's main function (f(z)=z^2+c) and i do a loop for each pixel of the screen, every time i repeat the process of using Z() and using the result as the new z parameter in the function Z()
For some reason what shows up on the screen is only a diagonal line, and i have no idea of why that is.
Here's the full code:
void draw() {
int max_iterations = 100, infinity_treshold = 16;
for (int y = 0; y < 360; y++) {
for (int x = 0; x < 480; x++) {
float z = 0; // the result of the function, (y)
float real = map(x,0,480,-2,2); // map "scales" the coordinate as if the pixel 0 was -2 and the pixel 480 was 2
float imaginary = map(y,0,360,-2,2); // same thing with the height
int func_iterations = 0; // how many times the process of the equation has been excecuted
while (func_iterations < max_iterations) {
z = Z(z, real+imaginary);
if (abs(z) > infinity_treshold) break;
func_iterations++;
}
if (func_iterations == max_iterations) rect(x,y,1,1);
}
}
noLoop();
}
private float Z(float z, float c) {
return pow(z,2)+c;
}
The formula z = z^2 +c is meant to operate with Complex numbers. I recommend to use PVector to represent a complex number. e.g.:
private PVector Z(PVector z, PVector c) {
return new PVector(z.x * z.x - z.y * z.y + c.x, 2.0 * z.x * z.y + c.y);
}
See the example:
void setup() {
size(400, 400);
}
void draw() {
background(255);
int max_iterations = 100;
float infinity_treshold = 16.0;
for (int y = 0; y < width; y++) {
for (int x = 0; x < height; x++) {
float real = map(x, 0, width, -2.5, 1.5);
float imaginary = map(y, 0, height, -2, 2);
PVector c = new PVector(real, imaginary);
PVector z = new PVector(0, 0);
int func_iterations = 0;
while (func_iterations < max_iterations) {
z = Z(z, c);
if (z.magSq() > infinity_treshold)
break;
func_iterations++;
}
if (func_iterations == max_iterations) {
point(x, y);
}
}
}
noLoop();
}
private PVector Z(PVector z, PVector c) {
return new PVector(z.x * z.x - z.y * z.y + c.x, 2.0 * z.x * z.y + c.y);
}
See also
wikipedia - Mandelbrot set
Mandelbrot.java
You've declared z as float so it's a real number, it should be complex. I'm not familiar with processing, does it even have a complex number data type?
Another problem is at Z(z, real+imaginary) Real and imaginary are both floats, so real numbers, so their sum is a real number. You need to construct a complex number from the real and imaginary parts.
I needed a for loop to increase randomly between a given range (1 to 5).
I've tried the following set of codes but it does not seem to work. This code is written for Processing which is based on Java. My intention was to create a canvas with random points of different color from the background to get paper like texture.
float x = 0;
float y = 0;
float xRandom = x + random(1, 5);
float yRandom = y + random(1, 5);
void setup() {
size(800, 800);
}
void draw() {
background(#e8dacf);
for(float x; x <= width; xRandom){
for (float y ; y <= height; yRandom){
fill(#f0e2d7);
stroke(#f0e2d7);
point(x, y);
}
}
If you want to step forward by a random value, then you have to increment the control variables x and y randomly:
for (float x=0; x <= width; x += random(1, 5)){
for (float y=0; y <= height; y += random(1, 5)){
fill(#f0e2d7);
stroke(#f0e2d7);
point(x, y);
}
}
Note, with this distribution, the dots are aligned to columns, because the x coordinates stay the same while the inner loop iterates.
For a completely random distribution, you have to compute the random coordinates in a single loop. e.g:
int noPts = width * height / 9;
for (int i = 0; i < noPts; ++i ){
fill(#f0e2d7);
stroke(#f0e2d7);
point(random(1, width-1), random(1, height-1));
}
Of course some may have to same coordinate, but that shouldn't be noticeable with this amount of points.
I new android. Trying to implement bouncing ball each other. Like this
My BouncingBallView class look like:
private ArrayList<Ball> balls;
public BouncingBallView(Context context) {
super(context);
this.balls = new ArrayList<>();
for(int i=0; i<2; i++)
this.balls.add(addBall());
}
public Ball addBall(){
Ball ball;
// Init the ball at a random location (inside the box) and moveAngle
Random rand = new Random();
int radius = 60;
int x = rand.nextInt(500 - radius * 2 - 20) + radius + 10;
int y = rand.nextInt(800- radius * 2 - 20) + radius + 10;
int speed = 10;
int angleInDegree = rand.nextInt(360);
ball = new Ball(x, y, radius, speed, angleInDegree);
return ball;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for(int i=0; i < balls.size(); i++)
balls.get(i).draw(canvas);
for(int i=0; i < balls.size(); i++){
balls.get(i).intersect(canvas);
// Update the ball's state with proper collision response if collided.
balls.get(i).update();
}
for(int i=0; i<balls.size(); i++){
balls.get(i).collide(balls);
}
invalidate();
}
And class Ball has method collide();
public void collide(ArrayList<Ball> balls){
//Log.d("TEst", "LOG");
// Calculate difference between centres
float distX = balls.get(0).getBallX() - balls.get(1).getBallX();
float distY = balls.get(0).getBallY() - balls.get(1).getBallY();
// Get distance with Pythagora
double dist = Math.sqrt((distX * distX) + (distY * distY));
float r = ballRadius + ballRadius;
if ((float) dist <= r) {
Log.d("Collide", "Detected");
this.ballSpeedX = -this.ballSpeedX;
this.ballSpeedY = -this.ballSpeedY++;
}
/*for(int i=0; i < balls.size(); i++) {
for(int j=1; j<balls.size(); j++) {
// Calculate difference between centres
float distX = balls.get(i).getBallX() - balls.get(j).getBallX();
float distY = balls.get(i).getBallY() - balls.get(j).getBallY();
// Get distance with Pythagora
double dist = Math.sqrt((distX * distX) + (distY * distY));
*//*double distance = Math.sqrt(((balls.get(0).getBallX() - balls.get(1).getBallX()) * (balls.get(0).getBallX() - balls.get(1).getBallX())) + ((balls.get(0).getBallY()
- balls.get(1).getBallY()) * (balls.get(0).getBallY() - balls.get(1).getBallY())));*//*
float r = ballRadius + ballRadius;
if ((float) dist <= r) {
Log.d("Collide", "Detected");
this.ballSpeedX = -this.ballSpeedX;
this.ballSpeedY = -this.ballSpeedY++;
}
}
}*/
}
Here, I'm using Pythagoras' theorem, a^2 + b^2 = c^2, to figure out the distance between the two circles' centers. How to calculate if ball count > 2. I try to in loop but it works very bad(frozen ball).
Full code you can find github
Now work like in this video my bouncing ball video
Thx for help ;)
P.s Sorry so poor English.
You can have a counter for balls in each stage, when a ball is destroyed(if you destroy them) you can change the count and you can check (the counter) in the collide method.
But i don't thing that you need to check this condition, if a collision happens then OK else nothing should happen to this method.
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){
I am calculating Geometric median of some (x,y) points in java. To calculate Geometric median, first i am calculating centroid of all the points, then this centroid is used to calculate Geometric median. My code works fine, but sometimes it goes to an infinite loop (i think.). The problem is with my while condition. This while condition should be change according to input points, but i don't know how. Below I am putting the complete code.
import java.util.ArrayList;
public class GeometricMedian {
private static ArrayList<Point> points = new ArrayList<Point>();
private class Point {
private double x;
private double y;
Point(double a, double b) {
x = a;
y = b;
}
}
public static void main(String[] args) {
GeometricMedian gm = new GeometricMedian();
gm.addPoints();
Point centroid = gm.getCentroid();
Point geoMedian = gm.getGeoMedian(centroid);
System.out.println("GeometricMedian= {" + (float) geoMedian.x + ", "
+ (float) geoMedian.y + "}");
}
public void addPoints() {
points.add(new Point(0, 1));
points.add(new Point(2, 5));
points.add(new Point(3, 1));
points.add(new Point(4, 0));
}
public Point getCentroid() {
double cx = 0.0D;
double cy = 0.0D;
for (int i = 0; i < points.size(); i++) {
Point pt = points.get(i);
cx += pt.x;
cy += pt.y;
}
return new Point(cx / points.size(), cy / points.size());
}
public Point getGeoMedian(Point start) {
double cx = 0;
double cy = 0;
double centroidx = start.x;
double centroidy = start.y;
do {
double totalWeight = 0;
for (int i = 0; i < points.size(); i++) {
Point pt = points.get(i);
double weight = 1 / distance(pt.x, pt.y, centroidx, centroidy);
cx += pt.x * weight;
cy += pt.y * weight;
totalWeight += weight;
}
cx /= totalWeight;
cy /= totalWeight;
} while (Math.abs(cx - centroidx) > 0.5
|| Math.abs(cy - centroidy) > 0.5);// Probably this condition
// needs to change
return new Point(cx, cy);
}
private static double distance(double x1, double y1, double x2, double y2) {
x1 -= x2;
y1 -= y2;
return Math.sqrt(x1 * x1 + y1 * y1);
}
}
Please help me to fix the bug, also if there exitis any better way to calculate Geometric median of some 2D points, write here. Thank you.
I don't see why you need two loops. You only need the loop over all the points. What is the reason for the other one, in your view?
One way to solve this is to iterate certain number of times. This similar to K-Means method where it either converges to a specific threshold or stops after a predefined number of iterations.