Calculating the Value of Pi in Processing - java

Processing is an environment that makes use of Java. I am trying to to use the Monte Carlo method to calculate the value of Pi. I am trying to create a dartboard (a circle within a square), and return "Yes" whenever the randomly selected point is selected within the circle.
Processing uses a coordinate system where the top left corner is the origin, rightwards is the positive x-axis, and downwards is the positive y-axis.
Here's my code:
float circleX;
float circleY;
float r;
void setup() {
size(360, 360);
circleX = 50;
circleY = 50;
frameRate(0.5);
}
void draw() {
background(50);
fill(255);
stroke(255);
fill(100);
ellipse(180, 180, 360, 360);
ellipse(circleX, circleY, 10, 10);
circleX = random(360);
circleY = random(360);
r = (circleX-180)*(circleX-180) + (180-circleY)*(180-circleY);
if (r < 32400) {
print("Yes! ");
}
}
However, on many instances, points inside the circle do not return "Yes," and points outside the circle do return "Yes." Any ideas on what is wrong?

You have to swap the lines generating the random coordinates and drawing it:
// Generate new random coordinates
circleX = random(360);
circleY = random(360);
// Draw circle at those coordinates
ellipse(circleX, circleY, 10, 10);
// Check whether the coordinates are withing the big circle
r = (circleX-180)*(circleX-180) + (180-circleY)*(180-circleY);
The way you do it, the circle is drawn before you generate new coordinates, which you then check.

Related

draw images with random rotation java + processing

I'm drawing arrows using Java and I can draw them straight but now I need to have the arrows pointing in different directions.
In my current code, I draw a triangle and then a square.
Is there a way to group the two after they've been drawn and then rotate them at a random angle?
Right now I'm only able to rotate the triangle and square separately, causing some messy thing.
void setup() {
size(400, 400);
}
void draw() {
float r = random(24, 64);
background(255);
drawArrow(r);
//drawPlus(r);
saveFrame("dataArrow/plus####.png");
if (frameCount == 100) {
exit();
}
}
void drawArrow(float r){
float base = r * 2;
float xStart = random(1, width-base - 1);
float xEnd = xStart + base;
float k = 0.5 * base;
float y = random(k, width-k);
float middleBase = base/2 + xStart;
float rectSide = 0.5 * base;
float rectX1 = middleBase - rectSide/2;
float rectX2 = middleBase + rectSide/2;
fill(0);
triangle(xStart, y, xEnd, y, middleBase, y - k);
rect(rectX1, y, rectSide, rectSide);
}
not sure if this exactly what you mean but here is how to move things around
push and pop matrix allows you to organize things that should have the same translations
https://processing.org/reference/pushMatrix_.html
https://processing.org/reference/rotate_.html
https://processing.org/reference/translate_.html
basic example
pushMatrix();//start of new translation and rotation things
translate(xAmount,yAmount);//this moves the origin
rotate(angle);//this rotates around origin
//drawing around the point of rotation 0,0 here
//drawing...
popMatrix();//reset all translations and rotations to before

How to predict where a rectangle will go before being rotated (Processing)

I hope I'm asking this concisely enough. I'm wanting to run a script that will predict where a rectangle will end up when doing a rotation, before the rotation actually starts. So, if you're given a rectangle which is located on coordinates (40, 40) and you want the angle to change by 20 degrees, how would you predict or estimate the x y values of where that rectangle would end up? I'm wanting to do this estimation first, then store it in an array, and then compare it when the real rotation happens. For the prediction, I'd have thought it would be something like this...
void setup(){
size(825, 825);
background(255);
smooth();
PShape Shape = createShape(GROUP);
PShape rectangle = createShape(RECT, 40, 40, 120, 230); // with 40 and 40 being the x and y
// extra point just to show where the x and y of the rectangle are //
strokeWeight(5);
stroke(0, 255, 0);
PShape point = createShape(POINT, 40, 40);
Shape.addChild(rectangle);
Shape.addChild(point);
int rectangleX = 40;
int rectangleY = 40;
int translationModifierX = 200;
int translationModifierY = 200;
// so this here would be the theoretical estimate on what the new x and y coordinates would be for the translation, before moving onto the rotation. This one's easy to predict, of course. //
int newX = rectangleX + translationModifierX;
int newY = rectangleY + translationModifierY;
// And here is where I'd be trying to estimate what the new x and y coordinates would be after rotated. //
float rotatedX = newX*cos(20) - newY*sin(20);
float rotatedY = newX*sin(20) + newY*cos(20);
println("Final X Coordinate Prediction:", rotatedX);
println("Final Y Coordinate Prediction:", rotatedY);
pushMatrix();
Shape.translate(newX, newY);
Shape.rotate(radians(20));
popMatrix();
shape(Shape);
}
This printed prediction, though, is not that close to where the x y actually ends up. It actually ends up around 263, 292, but the print puts the x value as ~-121, and its y value at ~317. What I'm really needing to do is get this prediction's x and y coordinates to be the same as it would be when I run rectangle.rotate(radians(20)). I just want to be able to see where this rectangle would go before it actually goes there. I feel like it's a math problem. I'm obviously new, so I'd appreciate any assistance.
You need to use the relative (rectangleX/rectangleY), not the absolute (newX/newY) coordinates.
float rotatedX = newX + rectangleX*cos(radians(20)) - rectangleY*sin(radians(20));
float rotatedY = newY + rectangleX*sin(radians(20)) + rectangleY*cos(radians(20));

How to make a ball go in a specific direction according to where it's clicked?

Table t1= new Table(300, 300);
float power=0;
float dx=0;
float dy=0;
void setup()
{
size(1000, 600);
frameRate(10);
}
void draw()
{
strokeWeight(1);
stroke(0, 0, 0);
strokeWeight(10);
stroke(255, 0, 0);
fill(26, 218, 35);
rect(0, 0, 1000, 600);
noStroke();
fill(0);
ellipse(0, 0, 80, 80);
ellipse(1000, 0, 80, 80);
ellipse(0, 600, 80, 80);
ellipse(1000, 600, 80, 80);
strokeWeight(1);
stroke(0, 0, 0);
fill(255);
ellipse(t1.cue_ball.center.x, t1.cue_ball.center.y, 20, 20);
dx=friction(dx);
dy=friction(dy);
if (mousePressed)
{
power+=5;
}
if (t1.cue_ball.center.x+30>1000 || t1.cue_ball.center.x-30<0)
{
dx*=-1;
}
if (t1.cue_ball.center.y+30 >=600 || t1.cue_ball.center.y -30<=0)
{
dy*=-1;
}
t1.cue_ball.center.x +=dx;
t1.cue_ball.center.y +=dy;
}
void mouseReleased()
{
dx=power*2;
dy=power*2;
}
float friction (float c)
{
c*=0.9;
return c;
}
class Ball
{
float rad;
Point center;
Point contact_point;
color col;
Ball ( float a, float b)
{
center = new Point (a+=dx, b+=dy);
//contact_point= new Point(
}
}
class Table
{
Ball [] b_arr;
Stick st;
Ball cue_ball;
Table ( float a, float b )
{
cue_ball= new Ball( a, b);
}
}
class Point
{
float x;
float y;
Point(float a, float b)
{
x=a;
y=b;
}
}
class Stick
{
Point start_p;
Point end_p;
color col;
int length;
}
So we want to add something so that when the ball is clicked, it will move accordingly. For example, if it is clicked in the top left, it will move diagonally right down. If clicked bottom left, it will move diagonally right up. Also, is there a way to correspond this to the angle? So a larger angle between the click point and the center will make a steeper diagonal.
Added lines of code I'm not sure where needs to be added:
t1.cue_ball.center.x+=dx;
t1.cue_ball.center.y+=dy;
dx=t1.cue_ball.center.x-mouseX;
dy=t1.cue_ball.center.y-mouseY;
float n= sqrt(pow(dx,2)+pow(dy,2));
dx*=power/n;
dy*=power/n;
If you have or know how to compute the angle between the x-axis and the cue (I'm assuming this is billiards), then to make the ball go in that direction, if I understand your code correctly, you could just set the dx and dy of the ball that you strike according to
dx = power*cos(angle)
dy = power*sin(angle)
You might have to take the negative angle instead, depending on the coordinate system (if going up is positive or negative in the y-direction), and precisely what angle you compute. The easiest is probably to just plug it in and see what happens!
EDIT:
Not related to your question, but as a matter of style, it might be a good idea to move your logic for moving and drawing the ball to the Ball class. So that every tick, you draw the balls on the screen by calling an appropriate draw() method for each instance of the Ball class. Then it would be much easier to move several balls at once.
EDIT2:
I just realized you can actually solve the problem without trigonometry, if you know the point where you click. Let's say cx,cy is the point where you click, and x,y is the center of the ball, then your dx and dy for the ball can be computed as:
dx = x-cx
dy = y-cy
n = sqrt(dx^2 + dy^2)
dx *= power/n
dy *= power/n
Explanation:
The outgoing velocity for the ball should be in the same direction as the click relative to the ball. So we already have the relative lengths of dx and dy, and to get the right power we just need to normalize and multiply by the power.

Processing Tower Defence Game - Towers attacking Enemies

I will keep this short, I am making a Tower Defence game as a mini project while I have some spare time and I am trying to figure out how I can implement the towers to be able to shoot the enimies when they come into range using dist but I just don't know how to implement a method that uses the enimies position and the towers position. I have an ArrayList of CreepSprites and Towers
CreepSprite[] CreepSprites;
ArrayList<Tower> AllTowers = new ArrayList<Tower>();
ArrayList<Creep> AllCreeps = new ArrayList<Creep>();
If someone could give me some guidence as to how I would go about making the towers able to shoot the Creeps that would be great, even if it doesn't get rid of them, just able to shoot at them would be great.
Cheers
#GoneUp's answer is in the right direction. In Processing you have a class called PVector which provides a distance method as well: dist()
PVector towerPos = new PVector(100, 100);
PVector enemyPos = new PVector(300, 300);
float towerAttackRadius = 200;
void setup() {
size(400, 400);
rectMode(CENTER);
strokeWeight(3);
}
void draw() {
background(255);
//draw tower
noFill();
//check range
if(towerPos.dist(enemyPos) < towerAttackRadius){
//tower engaged, draw in green
stroke(0,192,0);
}else{
//tower in idle mode, draw in blue
stroke(0, 0, 192);
}
//visualise tower attack radius
//(towerAttackRadius * 2 -> radius * 2 = diameter (width/height))
ellipse(towerPos.x, towerPos.y, towerAttackRadius * 2, towerAttackRadius * 2);
//visualise tower
rect(towerPos.x, towerPos.y, 30, 30);
//draw enemy
stroke(192, 0, 0);
rect(enemyPos.x, enemyPos.y, 10, 10);
//instructions
fill(0);
text("click and drag to move enemy",10,15);
}
void mouseDragged() {
enemyPos.set(mouseX, mouseY);
}
I warmly recommend Daniel Shiffman's Nature of Code chapter on Vectors.
It's a little bit of linear algebra, but it's super useful, especially for games so worth getting the hang of it early.
For example, to shoot a bullet, you will need to workout the direction towards.
You can do that by using vector subtraction.
Additionally, you probably want to control how fast the bullet moves on screen towards that direction. That can also be done by normalising the vector: keeping it's direction, but reducing it's size to 1.0:
After that point it's easy to scale (multiply) the vector to any size you want.
If you know the tower's position, you simply need to add this scaled velocity to compute where the bullet should be drawn each frame.
PVector already has a function that does both: setMag().
(set mag is short for set magnitude (or vector length))
It also provides a heading() function which is handy to workout the angle.
Here's a basic proof of concept:
PVector towerPos = new PVector(100, 100);
PVector enemyPos = new PVector(300, 300);
float towerAttackRadius = 300;
ArrayList<Bullet> bullets = new ArrayList<Bullet>();
void setup() {
size(400, 400);
rectMode(CENTER);
strokeWeight(3);
}
void draw() {
background(255);
//check if an enemy is within range using dist()
//if the distance is smaller than the radius, attack!
if(towerPos.dist(enemyPos) < towerAttackRadius){
//hacky frame based counter: please use a millis() based timer instead
//shoot every 30 frames
if(frameCount % 30 == 0){
shoot();
}
}
//update bullets
for(Bullet b : bullets) {
b.update();
}
//draw tower
noFill();
stroke(0, 0, 192);
//visualise tower attack radius
//(towerAttackRadius * 2 -> radius * 2 = diameter (width/height))
ellipse(towerPos.x, towerPos.y, towerAttackRadius * 2, towerAttackRadius * 2);
//visualise tower
rect(towerPos.x, towerPos.y, 30, 30);
//draw enemy
stroke(192, 0, 0);
rect(enemyPos.x, enemyPos.y, 10, 10);
//instructions
fill(0);
text("click and drag to move enemy",10,15);
}
void mouseDragged() {
enemyPos.set(mouseX, mouseY);
}
void shoot(){
//make a new Bullet pointing from the tower to the enemy
Bullet b = new Bullet(towerPos.x,towerPos.y,enemyPos.x,enemyPos.y);
//add it to the list of bullets (for updates)
bullets.add(b);
println(b);
}
class Bullet {
//where does the bullet shoot from (and it's current position)
PVector position = new PVector();
//where does the bullet shooting towards
PVector target = new PVector();
//how fast does the bullet move on screen
float speed = 1.2;
//how large goes the bullet appear on screen
float size = 10;
//bullet velocity
PVector velocity;
Bullet(float startX,float startY, float endX, float endY) {
position.set(startX,startY);
target.set(endX,endY);
//compute the difference vector (start to end) = direction
velocity = PVector.sub(target,position);
//normalize the vector = same direction but magnitude of 1 -> makes it easy to scale
//velocity.normalize();
//scale by the speed to move on screen)
//normalize + multiple = resize the vector -> same direction, different length
//velocity.mult(speed);
//or do both normalize and multiple using setMag()
velocity.setMag(speed);
}
void update() {
//update position based on velocity (simply add velocity to current position)
position.add(velocity);
//render
//compute rotation angle from velocity (implementation is 2D only btw)
float angle = velocity.heading();
pushMatrix();
translate(position.x,position.y);
rotate(angle);
stroke(0);
line(0,0,size,0);
popMatrix();
}
String toString(){
return position+"->"+target;
}
}
You can actually play with a preview bellow:
var towerPos,enemyPos;
var towerAttackRadius = 300;
var bullets = [];
function setup() {
createCanvas(400, 400);
rectMode(CENTER);
strokeWeight(3);
towerPos = createVector(100, 100);
enemyPos = createVector(300, 300);
}
function draw() {
background(255);
//check if an enemy is within range using dist()
//if the distance is smaller than the radius, attack!
if(towerPos.dist(enemyPos) < towerAttackRadius){
//hacky frame based counter: please use a millis() based timer instead
//shoot every 30 frames
if(frameCount % 30 === 0){
shoot();
}
}
//update bullets
for(var i = 0; i < bullets.length; i++) {
bullets[i].update();
}
//draw tower
noFill();
stroke(0, 0, 192);
//visualise tower attack radius
//(towerAttackRadius * 2 -> radius * 2 = diameter (width/height))
ellipse(towerPos.x, towerPos.y, towerAttackRadius * 2, towerAttackRadius * 2);
//visualise tower
rect(towerPos.x, towerPos.y, 30, 30);
//draw enemy
stroke(192, 0, 0);
rect(enemyPos.x, enemyPos.y, 10, 10);
//instructions
noStroke();
fill(0);
text("click and drag to move enemy",10,15);
}
function mouseDragged() {
enemyPos.set(mouseX, mouseY);
}
function shoot(){
//make a new Bullet pointing from the tower to the enemy
var b = new Bullet(towerPos.x,towerPos.y,enemyPos.x,enemyPos.y);
//add it to the list of bullets (for updates)
bullets.push(b);
}
function Bullet(startX,startY,endX,endY) {
//where does the bullet shoot from (and it's current position)
this.position = createVector(startX,startY);
//where does the bullet shooting towards
this.target = createVector(endX,endY);
//how fast does the bullet move on screen
this.speed = 1.2;
//how large goes the bullet appear on screen
this.size = 10;
//compute the difference vector (start to end) = direction
this.velocity = p5.Vector.sub(this.target,this.position);
//normalize the vector = same direction but magnitude of 1 -> makes it easy to scale
this.velocity.normalize();
//scale by the speed to move on screen)
//normalize + multiple = resize the vector -> same direction, different length
this.velocity.mult(this.speed);
this.update = function() {
//update position based on velocity (simply add velocity to current position)
this.position.add(this.velocity);
//render
//compute rotation angle from velocity (implementation is 2D only btw)
var angle = this.velocity.heading();
push();
translate(this.position.x,this.position.y);
rotate(angle);
stroke(0);
line(0,0,this.size,0);
pop();
}
}
//http://stackoverflow.com/questions/39698472/processing-tower-defence-game-towers-attacking-enemies
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.3/p5.min.js"></script>
Have fun with PVectors ! :)
One important note:
the above code is a proof of concept and not optimized.
On the long run with a lot of towers and enemies it will slow down.
Once you get the math/code right, you can start doing a few improvements:
manage bullets/instances (e.g. re-use bullets that are off screen
rather than creating new instances all the time)
use the squared distance via magSq() instead and the squared radius to speed up calculations
You could use the Point2D class to represent the x,y coordinates of your figures. The class got a pre-implemented distance method wich can be checked against a radius.

Rotate Rectangle in Java

I need to create rectangles that are rotated around their center (so they don't need to be parallel to the axes of the coordinate system). So basicelly each rectangle can be defined by center-X, center-Y, width, height and angle. What I want to do then is to perform calculations on whether certain points are contained in these rectangles or not (so no drawing will be involved). I guess I cant use the Rectangle2D class because these rectangles will always be parallel to the x and y-axis of the coordinate system. Is the only way to get this functionality by writing my own rectangle class or is there anything existing (similar to Rectangle2D) I can use?
Rotate all the points you want to test and use contains(Point) method of the Rectangle2D as Mihai did.
But if you really want to rotate the rectangles you can do it like this (this is the integer version but probably you can do it with Rectangle2D aswell :)).
public class TestRotate {
public static void main(String... args) {
Rectangle r = new Rectangle(50, 50, 100, 100);
Point check = new Point(100, 151); // clearly outside
System.out.println("first: " + r.contains(check));
AffineTransform at = AffineTransform.getRotateInstance(
Math.PI/4, r.getCenterX(), r.getCenterY());
Polygon p = new Polygon();
PathIterator i = r.getPathIterator(at);
while (!i.isDone()) {
double[] xy = new double[2];
i.currentSegment(xy);
p.addPoint((int) xy[0], (int) xy[1]);
System.out.println(Arrays.toString(xy));
i.next();
}
// should now be inside :)
System.out.println("second: " + p.contains(check));
}
}
You can use Rectangle2D to check for containment, if instead of rotating your rectangle by an angle, say, counterclockwise, you rotate each of the points you need to check by the same angle clockwise, relative to the center of the rectangle. Something like
double dx = point.x - rectangleCenter.x;
double dy = point.y - rectangleCenter.y;
double newX = rectangleCenter.x - dx*Math.cos(angle) + dy*Math.sin(angle);
double newY = rectangleCenter.x - dx*Math.sin(angle) - dy*Math.cos(angle);

Categories