I really have no idea why the x and y values wont go to the drawLines function
float x, x1, x2;
float y, y1, y2;
float rad; //radius
int lines = 30; //number of lines
int colorNumber = 1;
void setup() {
background(#FFFFFF);
size (800, 600);
rad = 8;
}
void draw() {
}
This creates the three dots or vertices of the mathematical envelope
void mouseClicked() {
float x = mouseX;
float x1 = mouseX;
float x2 = mouseX;
float y = mouseY;
float y1 = mouseY;
float y2 = mouseY;
if (colorNumber == 1) {
fill(#9393ff);
ellipse(x, y, rad, rad);
} else if (colorNumber == 2) {
fill(#FF9393);
ellipse(x1, y1, rad, rad);
} else if (colorNumber == 3) {
fill(#93ff93);
ellipse(x2, y2, rad, rad);
}
}
This is supposed to draw the envelope using the coordinates of the vertices
void drawLines(int numLines) {
for (int i = 0; i < numLines; i = i + 1) {
float x = mouseX;
float x1 = mouseX;
float x2 = mouseX;
float y = mouseY;
float y1 = mouseY;
float y2 = mouseY;
float t = (float) i/(numLines-1);
float startX = x + t * (x1 - x);
float startY = y + t * (y1 - y);
float endX = x1 + t * (x2 - x1);
float endY = y1 + t * (y2 - y1);
line (startX, startY, endX, endY);
}
}
void mouseReleased() {
colorNumber++;
if (colorNumber == 4) {
colorNumber = 1;
}
println(colorNumber);
}
void keyPressed() {
if (keyPressed == true) {
background(#FFFFFF);
}
}
this last stuff just tells the code if you press a key, it will reset the backround
I understand your intention with using mouseX and mouseY to specify the coordinates of one of the 3 points of the envelope on click. The current issue is that all 3 points are being set to the same coordinate with each click. You need to introduce a variable to keep track of which coordinate to set on-click, such that only one pair is set. Then, only once all 3 coordinates are set, drawLines() can be called.
I propose the following:
Introduce 2 variables, one to keep track of which point is being modified; the other an array of PVectors (just to make it cleaner).
int index = 0;
PVector[] coords = new PVector[3];
Modify mouseClicked() to include the following:
void mouseClicked() {
ellipse(mouseX, mouseY, 8, 8);
coords[index] = new PVector(mouseX, mouseY);
index += 1;
if (index == 3) {
drawLines(lines);
}
index %= 3;
}
drawLines() becomes:
void drawLines(int numLines) {
for (int i = 0; i < numLines; i = i + 1) {
x = coords[0].x;
x1 = coords[1].x;
x2 = coords[2].x;
y = coords[0].y;
y1 = coords[1].y;
y2 = coords[2].y;
float t = (float) i / (numLines - 1);
float startX = x + t * (x1 - x);
float startY = y + t * (y1 - y);
float endX = x1 + t * (x2 - x1);
float endY = y1 + t * (y2 - y1);
line(startX, startY, endX, endY);
}
}
Finally, since your drawing on a black background, and the default stroke colour is black, use strokeColour() to change the colour of the lines so that you can see the envelope once its drawn.
Table t1;
import ddf.minim.*;
AudioPlayer player;
Minim minim;
int stickColR=0;
int stickColG=0;
int stickColB=0;
int counter=0;
//--------------
void setup(){
size(1000,600);
smooth();
t1 = new Table(1000,600);
t1.startGame();
//sound player setup
minim= new Minim(this);
player=minim.loadFile("ballsound.mp3");
}
//--------------
void draw(){
strokeWeight(10);
stroke(255,0,0);
fill(26, 218, 35);
rect(0, 0, 1000, 600);
fill(0);
noStroke();
ellipse(0, 0, 100, 100);
ellipse(1000, 0, 100, 100);
ellipse(0, 600, 100, 100);
ellipse(1000, 600, 100, 100);
t1.updatePos(); //calling the function to update the position of the balls
t1.visualize(); // Function responsible for drawing the balls
}
//--------------
void mousePressed(){
t1.mousePressed(mouseX-t1.x,mouseY-t1.y);
}
//--------------
void mouseReleased(){
t1.mouseReleased(mouseX-t1.x,mouseY-t1.y);
}
//=============================
class Table{
boolean GameIsOver=false;
float drag = 0.99;
float bounce = 0.4;
float wallBounce = 0.3;
float pushFactor = 0.4;
float maxPush = 20;
color[] ballColors = new color[]{color (255), color (216,7,17),color(17,242,225), color ( #45B4CE) , color ( #6A6347) , color (#E80909) ,color (#CEA9A9)};
Ball[] balls;
Ball selectedBall;
int x,y,width,height;
//--------------
Table(int w, int h){
width = w;
height = h;
}
//--------------
void startGame(){
buildBalls(5);
}
//--------------
void buildBalls(int count){
balls = new Ball[2*count+1];
int x_coor_red=600;
int y_coor_red=300;
int x_coor_green=626;
int y_coor_green=313;
for(int i=0;i<count;i++)
{
balls[i] = new Ball(x_coor_red, y_coor_red,i+1, this);
x_coor_red+=26;
y_coor_red-=13;
if(i>=3)
{
x_coor_red-=26;
y_coor_red+=26;
}
}
for(int i=0;i<count;i++)
{
balls[count+i] = new Ball( x_coor_green, y_coor_green,i+2, this);
x_coor_green+=26;
y_coor_green+=13;
if(i==1)
{
x_coor_green-=26;
y_coor_green-=20;
}
if(i==2)
{
y_coor_green-=20;
}
if(i==3)
{
x_coor_green-=45;
}
}
balls[2*count] = new Ball( 0.5*(width), 0.5*(height),0, this);
}
//--------------
void updatePos(){
//simulation
for(int i=0;i<balls.length;i++)
balls[i].update();
//collision detection
for(int i=0;i<balls.length;i++)
for(int j=i+1;j<balls.length;j++)
balls[i].collisionDetect(balls[j]);
}
//--------------
void visualize(){
translate(x,y);
noStroke();
//draw stick
if(mousePressed && selectedBall!= null && (mouseX<=26+selectedBall.x || mouseX>26-selectedBall.x) && selectedBall.ballColor==color(255)){
stickColR+=2;
stickColB+=2;
strokeWeight(4);
stroke(stickColR, stickColG, stickColB);
line ( mouseX , mouseY , mouseX + cos (atan2 ( mouseY -selectedBall.y , mouseX - selectedBall.x) )*300 , mouseY + sin( atan2 ( mouseY - selectedBall.y , mouseX -selectedBall.x ))*300);
}
//drawing
for(int i=0;i<balls.length;i++){
balls[i].visualize();
//Balls"disappearing" in corners
if(balls[i].x<50 && (balls[i].y<50 || balls[i].y>550) || balls[i].x>950 &&(balls[i].y<50 || balls[i].y>550)){
player.rewind();
player.play();
if(balls[i].ballColor==color(255))
{
textSize(25);
text("Cue Ball Sunk. GAME OVER",350,560);
}
fill(0);
ellipse(0,0,100,100);
ellipse(1000, 0, 100, 100);
ellipse(0, 600, 100, 100);
ellipse(1000, 600, 100, 100);
balls[i].x=1200;
balls[i].y=0;
counter++;
if (balls[i].ballColor != 255 && counter>=3)
{
textSize(25);
text("YOU WIN", 350,560);
}
}
}
}
//--------------
float kineticEnergy(){
float energy=0;
for(int i=0;i<balls.length;i++)
energy += mag( balls[i].vx, balls[i].vy );
return energy;
}
//--------------
void mousePressed(int mx, int my){
for(int i=0;i<balls.length;i++)
if( dist(balls[i].x,balls[i].y,mx,my) < balls[i].radius) {
selectedBall = balls[i];
break;
}
}
//--------------
void mouseReleased(int mx, int my){
if(selectedBall != null){
float px = (selectedBall.x-mx) * pushFactor;
float py = (selectedBall.y-my) * pushFactor;
float push = mag(px,py);
stickColR=0;
stickColB=0;
if( push > maxPush ){
px = maxPush*px/push;
py = maxPush*py/push;
}
selectedBall.push(px,py);
}
selectedBall = null;
}
}
class Ball{
float x,y,vx,vy,radius,diameter;
int type;
Table table;
color ballColor;
//--------------
Ball(float x, float y, int type, Table t){
this.x = x;
this.y = y;
this.type = type;
diameter = 26;
radius = diameter/2;
table = t;
ballColor = table.ballColors[type];
}
//--------------
void update(){
vx *= table.drag;
vy *= table.drag;
x += vx;
y += vy;
wallBounce();
}
//--------------
void wallBounce(){
if(x<=radius){
vx = -table.wallBounce*vx;
x = radius;
player.rewind();
player.play();
}
if(x>=t1.width-radius){
vx = -table.wallBounce*vx;
x = table.width-radius;
player.rewind();
player.play();
}
if(y<=radius){
vy = -table.wallBounce*vy;
y = radius;
player.rewind();
player.play();
}
if(y>=t1.height-radius){
vy = -table.wallBounce*vy;
y = table.height-radius;
player.rewind();
player.play();
}
}
//--------------
void visualize(){
fill(ballColor);
stroke(0);
strokeWeight(2);
stroke(0);
ellipse(x,y,diameter,diameter);
}
//--------------
void push(float dx, float dy){
vx += dx;
vy += dy;
}
//--------------
void collisionDetect(Ball b){
float distance = dist(x,y,b.x,b.y);
if( distance < diameter && (b.x>50 && (b.y>50 || b.y<550) || b.x<950 &&(b.y>50 || b.y<550))){
float vxSum = 0.5*(vx + b.vx);
float vySum = 0.5*(vy + b.vy);
float forceMagnitude = ((b.x-x)*(vx-vxSum) + (b.y-y)*(vy-vySum));
float xForce = 0.25*(x-b.x)*forceMagnitude/distance;
float yForce = 0.25*(y-b.y)*forceMagnitude/distance;
vx = vx + table.bounce * xForce;
vy = vy + table.bounce * yForce;
b.vx = b.vx - table.bounce * xForce;
b.vy = b.vy - table.bounce * yForce;
b.x = x + (diameter+1)*(b.x-x)/distance;
b.y = y + (diameter+1)*(b.y-y)/distance;
player.rewind();
player.play();
}
}
}
Im making a pool game in processing and I'm almost done but I'm stuck here. I want to add a counter that counts when a ball has been in the corner, then once the counter equals ten, the number of balls, it will display the winning message. I think something is going wrong in that the counter is being reset each time since it's in draw? But I'm not sure where else to initialize it. Btw, right now I just have it >= 3 so that I can quickly see if it's working. Thanks all
due to my low reputation, I have to show you my solution even though I think I haven't fixed all the bugs in your code.
I think your bug stated in the question has little relationship with the counter variable. I ran your code and found that you tried to hide the "disappeared" ball by changing coordinates. It means that "disappeared" balls can still be qualified to the if statement below, and as the result, value of counter will keep increasing.
//Balls"disappearing" in corners
if(balls[i].x<50 && (balls[i].y<50 || balls[i].y>550) || balls[i].x>950 &&(balls[i].y<50 || balls[i].y>550))
So you can add a boolean field to the Ball class
class Ball{
float x,y,vx,vy,radius,diameter;
int type;
Table table;
color ballColor;
// add this variable.
boolean disappeared = false;
// your constructor, wallBounce(), push(), collisionDetect()
void visualize(){
// only draw the ball when it hasn't disappeared.
if(!this.disappeared) {
fill(ballColor);
stroke(0);
strokeWeight(2);
stroke(0);
ellipse(x,y,diameter,diameter);
}
}
}
and then use it to avoid double counting.
// other code in visualize()
if(!balls[i].disappeared) {
counter++;
balls[i].disappeared = true;
}
// other code
Table t1;
import ddf.minim.*;
AudioPlayer player;
Minim minim;
int stickColR=0;
int stickColG=0;
int stickColB=0;
float counter;
boolean isAllIn = false;
//--------------
void setup() {
counter=0;
size(1000, 600);
smooth();
t1 = new Table(1000, 600);
t1.startGame();
//sound player setup
minim= new Minim(this);
player=minim.loadFile("ballsound.mp3");
}
//--------------
void draw() {
strokeWeight(10);
stroke(255, 0, 0);
fill(26, 218, 35);
rect(0, 0, 1000, 600);
fill(0);
noStroke();
ellipse(0, 0, 100, 100);
ellipse(1000, 0, 100, 100);
ellipse(0, 600, 100, 100);
ellipse(1000, 600, 100, 100);
t1.updatePos(); //calling the function to update the position of the balls
t1.visualize(); // Function responsible for drawing the balls
}
//--------------
void mousePressed() {
t1.mousePressed(mouseX-t1.x, mouseY-t1.y);
}
//--------------
void mouseReleased() {
t1.mouseReleased(mouseX-t1.x, mouseY-t1.y);
}
//=============================
class Table {
float drag = 0.99;
float bounce = 0.4;
float wallBounce = 0.3;
float pushFactor = 0.4;
float maxPush = 20;
color[] ballColors = new color[]{color (255), color (216, 7, 17), color(17, 242, 225), color ( #45B4CE), color ( #6A6347), color (#E80909), color (#CEA9A9)};
Ball[] balls;
Ball selectedBall;
int x, y, width, height;
//--------------
Table(int w, int h) {
width = w;
height = h;
}
//--------------
void startGame() {
buildBalls(5);
}
void restart() {
t1 = new Table(1000, 600);
t1.startGame();
}
//--------------
void buildBalls(int count) {
balls = new Ball[2*count+1];
int x_coor_red=600;
int y_coor_red=300;
int x_coor_green=626;
int y_coor_green=313;
for (int i=0; i<count; i++)
{
balls[i] = new Ball(x_coor_red, y_coor_red, i+1, this);
x_coor_red+=26;
y_coor_red-=13;
if (i>=3)
{
x_coor_red-=26;
y_coor_red+=26;
}
}
for (int i=0; i<count; i++)
{
balls[count+i] = new Ball( x_coor_green, y_coor_green, i+2, this);
x_coor_green+=26;
y_coor_green+=13;
if (i==1)
{
x_coor_green-=26;
y_coor_green-=20;
}
if (i==2)
{
y_coor_green-=20;
}
if (i==3)
{
x_coor_green-=45;
}
}
balls[2*count] = new Ball( 0.5*(width), 0.5*(height), 0, this);
}
//--------------
void updatePos() {
//simulation
for (int i=0; i<balls.length; i++)
balls[i].update();
//collision detection
for (int i=0; i<balls.length; i++)
for (int j=i+1; j<balls.length; j++)
balls[i].collisionDetect(balls[j]);
}
//--------------
void visualize() {
translate(x, y);
noStroke();
//draw stick
if (mousePressed && selectedBall!= null && (mouseX<=26+selectedBall.x || mouseX>26-selectedBall.x) && selectedBall.ballColor==color(255)) {
stickColR+=2;
stickColB+=2;
strokeWeight(4);
stroke(stickColR, stickColG, stickColB);
line ( mouseX, mouseY, mouseX + cos (atan2 ( mouseY -selectedBall.y, mouseX - selectedBall.x) )*300, mouseY + sin( atan2 ( mouseY - selectedBall.y, mouseX -selectedBall.x ))*300);
}
//drawing
for (int i=0; i<balls.length; i++) {
balls[i].visualize();
//Balls"disappearing" in corners
if (balls[i].x<50 && (balls[i].y<50 || balls[i].y>550) || balls[i].x>950 &&(balls[i].y<50 || balls[i].y>550)) {
player.rewind();
player.play();
if (balls[i].ballColor==color(255))
{
textSize(25);
text("Cue Ball Sunk. GAME OVER. Press any key to restart.", 170, 560);
if (keyPressed == true) {
t1.restart();
}
}
/*
fill(0);
ellipse(0, 0, 100, 100);
ellipse(1000, 0, 100, 100);
ellipse(0, 600, 100, 100);
ellipse(1000, 600, 100, 100);
balls[i].x=1200;
balls[i].y=0;
*/
if (!balls[i].disappeared) {
counter++;
balls[i].disappeared=true;
}
if ( counter>=3) {
textSize(25);
text("YOU WIN. Press any key to restart.", 300, 560);
if (keyPressed == true) {
t1.restart();
}
}
}
}
}
//--------------
float kineticEnergy() {
float energy=0;
for (int i=0; i<balls.length; i++)
energy += mag( balls[i].vx, balls[i].vy );
return energy;
}
//--------------
void mousePressed(int mx, int my) {
for (int i=0; i<balls.length; i++)
if ( dist(balls[i].x, balls[i].y, mx, my) < balls[i].radius) {
selectedBall = balls[i];
break;
}
}
//--------------
void mouseReleased(int mx, int my) {
if (selectedBall != null) {
float px = (selectedBall.x-mx) * pushFactor;
float py = (selectedBall.y-my) * pushFactor;
float push = mag(px, py);
stickColR=0;
stickColB=0;
if ( push > maxPush ) {
px = maxPush*px/push;
py = maxPush*py/push;
}
selectedBall.push(px, py);
}
selectedBall = null;
}
}
class Ball {
boolean disappeared = false;
float x, y, vx, vy, radius, diameter;
int type;
Table table;
color ballColor;
//--------------
Ball(float x, float y, int type, Table t) {
this.x = x;
this.y = y;
this.type = type;
diameter = 26;
radius = diameter/2;
table = t;
ballColor = table.ballColors[type];
}
//--------------
void update() {
vx *= table.drag;
vy *= table.drag;
x += vx;
y += vy;
wallBounce();
}
//--------------
void wallBounce() {
if (x<=radius) {
vx = -table.wallBounce*vx;
x = radius;
player.rewind();
player.play();
}
if (x>=t1.width-radius) {
vx = -table.wallBounce*vx;
x = table.width-radius;
player.rewind();
player.play();
}
if (y<=radius) {
vy = -table.wallBounce*vy;
y = radius;
player.rewind();
player.play();
}
if (y>=t1.height-radius) {
vy = -table.wallBounce*vy;
y = table.height-radius;
player.rewind();
player.play();
}
}
//--------------
void visualize() {
if (!this.disappeared) {
fill(ballColor);
stroke(0);
strokeWeight(2);
stroke(0);
ellipse(x, y, diameter, diameter);
}
}
//--------------
void push(float dx, float dy) {
vx += dx;
vy += dy;
}
//--------------
void collisionDetect(Ball b) {
float distance = dist(x, y, b.x, b.y);
if ( distance < diameter && (b.x>50 && (b.y>50 || b.y<550) || b.x<950 &&(b.y>50 || b.y<550))) {
float vxSum = 0.5*(vx + b.vx);
float vySum = 0.5*(vy + b.vy);
float forceMagnitude = ((b.x-x)*(vx-vxSum) + (b.y-y)*(vy-vySum));
float xForce = 0.25*(x-b.x)*forceMagnitude/distance;
float yForce = 0.25*(y-b.y)*forceMagnitude/distance;
vx = vx + table.bounce * xForce;
vy = vy + table.bounce * yForce;
b.vx = b.vx - table.bounce * xForce;
b.vy = b.vy - table.bounce * yForce;
b.x = x + (diameter+1)*(b.x-x)/distance;
b.y = y + (diameter+1)*(b.y-y)/distance;
player.rewind();
player.play();
}
}
}
I'm using the lerp() function to move my circle across a line, but it isn't working. The circle always ends up on the line somewhere depending on what my amt parameter is for the lerp() function. If I put 0.5 for the amt then the circle is placed half way down the line, but I can't see it move nor does the circle finish moving down the length of the circle. So can anyone help me make the circle move down the line?
float x1,y1,x2,y2;
float cx,cy;
float x4,y4;
void setup() {
size(600,600);
x1 = 200;
y1 = 150;
x2 = 300;
y2 = 250;
cx = 450;
cy = 200;
}
void draw() {
background(60);
stroke(220);
line(x1,y1,x2,y2);
noFill();
noStroke();
// calculate the point
float k = ((y2-y1) * (cx-x1) - (x2-x1) * (cy-y1))
/ ((y2-y1)*(y2-y1) + (x2-x1)*(x2-x1));
float x4 = cx - k * (y2-y1);
float y4 = cy + k * (x2-x1);
stroke(0);
line(cx,cy,x4,y4); //line connecting circle and point on line
float x = lerp(cx, x4, .1);
float y = lerp(cy, y4, .1);
fill(255, 0, 175);
ellipse(x4,y4, 8,8);
fill(175, 0, 255);
ellipse(x, y, 50, 50);
}
You need to use a variable for the amount value passed into the lerp() function. Then just increase that variable over time to animate:
float amount = 0;
float speed = .001;
void setup() {
size(500, 500);
}
void draw() {
float startX = 0;
float startY = 0;
float endX = width;
float endY = height;
float currentX = lerp(startX, endX, amount);
float currentY = lerp(startY, endY, amount);
background(0);
ellipse(currentX, currentY, 20, 20);
amount += speed;
}
I have a point following the path of a circle, and at a determined time, I want that point to "break" off and travel along the tangent line. How do I find this? I've been told that the derivative is
x = -sin(time)
and
y = -sin(time)
(not sure if I understand the "time" part of what I was told), but I don't see how that is enough to get my point to travel along this line. Any tips? Here is what I have currently.
/*
Rotor draws circle for random period of time, then moves
in a straight direction for a random period of time, beginning a
new circle
*/
Rotor r;
float timer = 0;
boolean freeze = false;
void setup() {
size(1000, 600);
smooth();
noFill();
frameRate(60);
background(255);
timeLimit();
r = new Rotor(100, 100, random(40, 100));
}
void draw() {
timer = timer + frameRate/1000;
if(timer > timeLimit()) {
timer = 0;
timeLimit();
if(freeze == true) {
freeze = false;
} else {
freeze = true;
}
}
if(!freeze) {
r.drawRotor();
} else {
r.holdSteady();
}
}
float timeLimit() {
float timeLimit = random(100);
return timeLimit;
}
Rotor Class:
class Rotor {
color c;
int thickness;
float xPoint;
float yPoint;
float nXPoint;
float nYPoint;
float radius;
float angle = 0;
float centerX;
float centerY;
float pointSpeed = frameRate/100;
Rotor(float cX, float cY, float rad) {
c = color(0);
thickness = 1;
stroke(c);
strokeWeight(thickness);
centerX = cX;
centerY = cY;
radius = rad;
}
void drawRotor() {
angle = angle + pointSpeed;
xPoint = centerX + cos(angle) * radius;
yPoint = centerY + sin(angle) * radius;
ellipse(xPoint, yPoint, thickness, thickness);
strokeWeight(2);
ellipse(centerX, centerY, 5, 5);
}
void holdSteady() {
xPoint = -sin(angle);//need tangent of circle
yPoint = -cos(angle);
ellipse(xPoint, yPoint, 4, 4);
//then set new center x and y
}
void drawNewRotor(float cX, float cy, float rad) {
}
}
You can use tan()
int f =100;
size(300,300);
stroke(0);
translate(width/2, height/2);
for(int i = 0; i< 360; i++){
point(cos(radians(i))*f,sin(radians(i))*f);
point(f,tan(radians(i))*f);
point(tan(radians(i))*f,f);
}