Error; cannot run a push matrix more than 32 times, then "target VM failed to initialize" - processing

I keep getting a "cannot run pushMatrix more than 32 times" in the middle of running this sketch. I'm aware that this can be an issue of having pushMatrix(); calls without a matching popMatrix(); but I don't see it in my code. Any help appreciated.
For the record; I'm aware this code is not very pretty and could be refactored extensively. I'm still new to programming and this is just an ongoing project I've been working on since the day I started coding.
Thanks again for any help.
float x, y, d, r, g, b, t;
float c = random(0, mouseY+75);
float easing = 0.03;
int diameter= 40;
int timer= -3000;
int direction = 1;
float speed = .7;
float angle = 0.0;
float offset;
float scalar = 60;
boolean button = false;
void setup() {
size(1000, 400);
smooth();
strokeWeight(5);
}
void draw() {
background(204);
int currentTime = millis();
textSize(16);
fill (125);
text ("Flying Circles", 20, 20);
if ((currentTime < 5000) && (mousePressed==false)){
r = noise(frameCount * 0.01) * 255; //clockwise spin
g = frameCount % 255;
b = 255 - noise(1 + frameCount * 0.025) * 255;
rectMode(CENTER);
background(204);
pushMatrix();
translate(mouseX, mouseY);
pushMatrix();
rotate(-angle);
ellipse(0,0, 150, 150);
ellipse(0,0, 125, 125);
rect(0,0, 80, 80);
popMatrix();
pushMatrix();
rotate(angle);
rect(0, 0, 80, 80);
rect(0, 0, 60, 60);
popMatrix();
pushMatrix();
rotate(-angle);
fill(r,g,b);
rect(-270, 0, 80, 80);
rect(270, 0, 80, 80);
rect(0, 0, 40, 40);
angle += 0.1;
popMatrix();
popMatrix();
}else{
drawCounterspin();
}
}
void keyPressed() {
button = !button;
}
void drawFighter(){
float targetX = mouseX;
float d = random(0, 150);
x += (targetX - x) * easing*1.5;
fill(mouseY, mouseY/2, mouseY/3);
ellipse(x-300, mouseY, 100, 100);
fill(d, d*1.2, d*1.5);
ellipse(x, mouseY, 80, 80);
fill(mouseY, mouseY/2, mouseY/3);
ellipse(x+300, mouseY, 100, 100);
line(x+40, mouseY,x+250, mouseY);
line(x-40, mouseY,x-250, mouseY);
fill(d, d, d);
ellipse(x, mouseY+100, 80, 80);
fill(d, d, d);
ellipse(x, mouseY+200, 60,60);
line(x+30,mouseY+30, width, mouseY*2);
line(x-30,mouseY+30, 0, mouseY*2);
}
void drawOilbounce() {
x = width/2;
y += speed * direction;
if ((y > height/2+diameter) || (y < 0)) {
direction = -direction;
scalar = -scalar;
}
float spinspeed = speed * .1;
float spinx = x+ cos(angle) * scalar;
float spiny = y+ sin(angle) * scalar;
angle += spinspeed;
scalar += spinspeed;
scalar = constrain(scalar, 30, 300);
fill(r,g,b);
ellipse(spinx, spiny, 30, 30);
fill(r*.95, g*.85, b*.75);
ellipse(x, y, diameter, diameter);
fill(r*.85, g*.75, b*.65);
ellipse(x, y*1.2, y*.02*diameter, diameter);
fill(r*.75, g*.65, b*.55);
ellipse(x, y*1.5, y*.05*diameter, diameter);
}
void drawCounterspin(){
pushMatrix();
rectMode(CENTER);
mouseX = constrain (mouseX, 250, width-250);
mouseY = constrain (mouseY, 48, height-48);
fill(mouseY, 80, 100);
if (mouseButton == LEFT) {
translate(mouseX, mouseY);
scale(sin(angle));
rotate(angle);
ellipse(0,0, 150, 150);
ellipse(0,0, 125, 125);
fill(mouseY, mouseX/2, mouseX);
rect(0, 0, 80, 80);
fill(mouseY/2, mouseX/3, mouseX);
rect(250, 0, 80, 80);
fill(mouseY, mouseX, mouseX/2);
rect(-250, 0, 80, 80);
angle += 0.05;
popMatrix();
}
}

Getting rid of the two calls (push and pop) inside the function drawCounterspin() seams to solve the problem without side effects. But I don't really know why... I have sen this behaviour before using push/popMatrix inside functions. If needed, isolate the call in draw, and not in the function, like:
pushMatrix();
drawCounterspin();
popMatrix();
Worked for me before.

Related

make a translated object collide with something [duplicate]

This question already has answers here:
Ball to Ball Collision - Detection and Handling
(15 answers)
Closed 2 years ago.
//Spielfeld Größe
int sizeX = 800;
int sizeY = 600;
//Robo Startposition
float roboX = sizeX/2;
float roboY = sizeY/2;
//Robo Speed
float speed = 0.03;
//Robo Acceleration
float accel = 0.05;
float x1;
float y1;
void setup() {
size(800, 600);
frameRate(60);
background(200);
}
void draw() {
background(200);
println("x " +x1);
println("y " +y1);
robo();
x1=screenX(roboX,roboX);
y1=screenY(roboY,roboY);
stopRobot();
object();
}
//Beschleunigung zurücksetzen
void mouseReleased() {
accel = 0.05;
}
void robo() {
rectMode(CENTER);
//RoboMovement
if(mousePressed){
float zielX = mouseX;
float moveX = zielX - roboX;
roboX += moveX * speed*accel;
float zielY = mouseY;
float moveY = zielY - roboY;
roboY += moveY * speed*accel;
//Beschleunigung am Anfang
if(accel< 1) {
accel += 0.05;
}
}
pushMatrix();
translate(roboX, roboY);
rotate(atan2(mouseY-roboY, mouseX-roboX));
rotate(radians(90));
//Hitbox
fill(0, 0);
stroke(160);
ellipse(0, 0, 78, 78);
noStroke();
//Track Connectors
fill(129, 29, 29);
rect(18, 12, 10, 8);
rect(18, -12, 10, 8);
rect(-18, 12, 10, 8);
rect(-18, -12, 10, 8);
//Robo Body
fill(63, 82, 21);
rect(0, 0, 13, 30);
ellipse(7, 15, 20, 20);
ellipse(-7, 15, 20, 20);
ellipse(7, -15, 20, 20);
ellipse(-7, -15, 20, 20);
rect(9, 0, 16, 23);
rect(0, 17, 20, 15);
rect(-9, 0, 16, 23);
rect(0, -17, 20, 15);
//Robo Body Details
fill(120);
ellipse(0, 0, 25, 25);
fill(60);
rect(0, -18, 6, 36);
rect(0, -36, 10, 5);
ellipse(0, 0, 20, 20);
fill(255, 0, 20);
ellipse(10, 18, 5, 5);
//Robo Tracks
//Right
fill(80);
rect(25, 0, 12, 34);
ellipse(24, 20, 10, 10);
ellipse(26, 20, 10, 10);
ellipse(24, -20, 10, 10);
ellipse(26, -20, 10, 10);
//Left
rect(-25, 0, 12, 34);
ellipse(-24, 20, 10, 10);
ellipse(-26, 20, 10, 10);
ellipse(-24, -20, 10, 10);
ellipse(-26, -20, 10, 10);
//Track Details
fill(140);
for (int i = -21; i< 22; i += 6) {
rect(25, i, 12, 2);
rect(-25, i, 12, 2);
}
popMatrix();
}
float [] [] bobject= new float [][] {{250, 250}, {500, 500}, {100, 100}};
void object() {
fill(255);
stroke(0);
circle(bobject[0][0], bobject[0][1], 20);
circle(bobject[1][0], bobject[1][1], 20);
circle(bobject[2][0], bobject[2][1], 20);
}
void stopRobot() {
if(dist(x1,y1,bobject[0][0],bobject[0][1])<=45){
speed=0;
if(mouseX<bobject[0][0]){
speed=0.03;}
if(mouseY>bobject[0][1]){
speed=0.03;}
}
if ( x1<=0+45) {
speed=0;
if (mouseX>=0) {
speed=0.03;
}
}
if ( x1>=width-45) {
speed=0;
if (mouseX<=width-45) {
speed=0.03;
}
}
if ( y1<=0+47) {
speed=0;
if (mouseY>=0+47) {
speed=0.03;
}
}
if ( y1>=height-45) {
speed=0;
if (mouseY<=height-45) {
speed=0.03;
}
}
}
This is the code, basically the idea is, that if the robot collides with the wall/objects it stops, independently from the position of the small circles.
Somehow i cant paste in the code so heres a link to the file
https://drive.google.com/drive/folders/1AvXQ2-stM-ubR38XSVG0zOaKvXHJTkC7?usp=sharing
If anybody could help me, that would be nice
The code was a Lil messy but I managed to make what you need, the first thing you need to do is to init the radius of the tank as a global variable so you can check your collision with it later. Secondly, its better to change your circles array by adding a 3rd value to store the radius, this way you can check the collision for multiple sized circles. Then I implemented a simple check collision method which checks for a given position (x,y) if the tank will collide with any of the circles. Lastly what you need to do is to store the tank position right before moving it, then check if the new position actually collides with any circle, if it does, you will need to stop the tank and put it back to the previous place. I hope my explanations made sense, here is the final code:
//Spielfeld Größe
int sizeX = 800;
int sizeY = 600;
//Robo Startposition
float roboX = sizeX/2;
float roboY = sizeY/2;
//Robo Speed
float speed = 0.03;
float robotRadius = 78;
//Robo Acceleration
float accel = 0.05;
float x1;
float y1;
void setup() {
size(800, 600);
frameRate(60);
background(200);
}
void draw() {
background(200);
println("x " +x1);
println("y " +y1);
robo();
x1=screenX(roboX,roboX);
y1=screenY(roboY,roboY);
object();
}
//Beschleunigung zurücksetzen
void mouseReleased() {
accel = 0.05;
}
void robo() {
rectMode(CENTER);
//RoboMovement
if(mousePressed){
//save robot position before moving it
float saveX = roboX;
float saveY = roboY;
float zielX = mouseX;
float moveX = zielX - roboX;
roboX += moveX * speed*accel;
float zielY = mouseY;
float moveY = zielY - roboY;
roboY += moveY * speed*accel;
//check if its colliding after moving it
if(checkCollision(roboX,roboY))
{
//in case the tank collide, put the robot baack and make acc = 0
accel = 0;
roboX = saveX;
roboY = saveY;
}
//Beschleunigung am Anfang
if(accel< 1) {
accel += 0.05;
}
}
pushMatrix();
translate(roboX, roboY);
rotate(atan2(mouseY-roboY, mouseX-roboX));
rotate(radians(90));
//Hitbox
fill(0, 0);
stroke(160);
ellipse(0, 0, robotRadius, robotRadius);
noStroke();
//Track Connectors
fill(129, 29, 29);
rect(18, 12, 10, 8);
rect(18, -12, 10, 8);
rect(-18, 12, 10, 8);
rect(-18, -12, 10, 8);
//Robo Body
fill(63, 82, 21);
rect(0, 0, 13, 30);
ellipse(7, 15, 20, 20);
ellipse(-7, 15, 20, 20);
ellipse(7, -15, 20, 20);
ellipse(-7, -15, 20, 20);
rect(9, 0, 16, 23);
rect(0, 17, 20, 15);
rect(-9, 0, 16, 23);
rect(0, -17, 20, 15);
//Robo Body Details
fill(120);
ellipse(0, 0, 25, 25);
fill(60);
rect(0, -18, 6, 36);
rect(0, -36, 10, 5);
ellipse(0, 0, 20, 20);
fill(255, 0, 20);
ellipse(10, 18, 5, 5);
//Robo Tracks
//Right
fill(80);
rect(25, 0, 12, 34);
ellipse(24, 20, 10, 10);
ellipse(26, 20, 10, 10);
ellipse(24, -20, 10, 10);
ellipse(26, -20, 10, 10);
//Left
rect(-25, 0, 12, 34);
ellipse(-24, 20, 10, 10);
ellipse(-26, 20, 10, 10);
ellipse(-24, -20, 10, 10);
ellipse(-26, -20, 10, 10);
//Track Details
fill(140);
for (int i = -21; i< 22; i += 6) {
rect(25, i, 12, 2);
rect(-25, i, 12, 2);
}
popMatrix();
}
//added a 3rd value to the circles array to store the radius
float [][] bobject= new float [][] {{250, 250, 20}, {500, 500, 20}, {100, 100, 20}};
void object() {
fill(255);
stroke(0);
for(int i=0; i<bobject.length; i++)
{
circle(bobject[i][0], bobject[i][1], bobject[i][2]);
}
}
//deleted stopRobot method
//created a method to check weather a specific place has a collision with a circle
boolean checkCollision(float x, float y)
{
//for every circle in the array, check weather the distance between it and the given tank position is lower than both radius sumed ( which means they collide )
for(int i=0; i<bobject.length; i++)
{
if(dist(x,y,bobject[i][0],bobject[i][1])< (robotRadius + bobject[i][2])/2)
return true;
}
return false;
}
feel free to ask in comment if you don't understand any part

Forcing a sphere to spin

I am working on an animation of a simplified solar system and want to apply rotation to the Sun. It seems to be a simple task, but somehow it won't work. I try to write my program using object-oriented paradigm, so each planet, moon and the Sun is an object of the CelestialBody class.
I tried to put the rotate(angle) line in an following excerpt from the CelestialBody class, as follows:
if(Type == 4){
emissive(255, 255, 255);
pointLight(255, 255, 255, 0, 0, 0); //for the normal behaviour of the sun light
lightFalloff(0, 0, 0.00020); //light falls off right behind the surface of the sun
ambientLight(255, 255, 255, 0, 0, 0); //ambientLight in the center of the sun
rotate(angle);
}
Sadly, it does nothing. How to fix this and make the sun rotate, for example along the x-axis?
Here's my code:
Main file:
import peasy.*; //<>//
PImage bg;
float angle = 0;
CelestialBody planet1;
CelestialBody planet2;
CelestialBody planet3;
CelestialBody planet4;
CelestialBody planet5;
CelestialBody sun;
PImage sunTexture;
PImage rocketTexture;
PShape rocket;
PeasyCam cam;
void setup() {
fullScreen(P3D);
bg = loadImage("background.jpg");
sunTexture = loadImage("sun.jpg");
cam = new PeasyCam(this, 1200);
rocket = loadShape("rocket.obj");
noStroke();
sun = new CelestialBody(70, 0, 0, 255, 200, 50, 4);//4 - type: sun
sun.planet.setTexture(sunTexture);
//noStroke();
//emissive(0, 0, 0);
planet1 = new CelestialBody(16, 150, 0.01, 150, 50, 255, 1);
planet1.spawnMoon(2);
planet2 = new CelestialBody(25, 300, 0.014, 50, 100, 255, 1);
planet2.spawnMoon(3);
planet3 = new CelestialBody(35, 450, -0.015, 255, 100, 40, 2);
planet3.spawnMoon(1);
planet4 = new CelestialBody(50, 650, 0.011, 50, 200, 255, 1);
planet4.spawnMoon(2);
planet5 = new CelestialBody(65, 900, -0.014, 0, 100, 0, 1);
planet5.planet = rocket;
planet5.planet.scale(0.9);
}
void makeOrbit(int a, int r){
for(int i=0; i<a; i++){
stroke(255, 10);
ellipse(height/2,width/2,r,r);
r-=180;
}
noStroke();
}
void draw() {
background(bg);
//lights();
noFill();
//translate(width/2, height/2);
stroke(#FFFFFF);
//ellipse(0,0,300,300);
//ellipse(0,0,600,600);
//ellipse(0,0,900,900);
//ellipse(0,0,planet4.distance,planet4.distance
// int z = 100;
//for (int i = 0; i<2; i++){
// z = -z;
// pointLight(255, 255, 255, -100, -100, z);
// pointLight(255, 255, 255, 100, -100, z);
// pointLight(255, 255, 255, 100, 100, z);
// pointLight(255, 255, 255, -100, 100, z);
//}
//emissive(255, 255, 255);
//pointLight(255, 255, 255, 0, 0, 0); //for the normal behaviour of the sun light
//lightFalloff(0, 0, 0.00025); //light falls off right behind the surface of the sun
//ambientLight(255, 255, 255, 0, 0, 0); //ambientLight in the center of the sun
sun.show();
planet1.show();
planet1.orbit();
planet2.show();
planet2.orbit();
planet3.show();
planet3.orbit();
planet4.show();
planet4.orbit();
planet5.show();
planet5.orbit();
}
CelestialBody class:
class CelestialBody {
float radius;
float angle = random(TWO_PI);
float distance;
float orbitSpeed;
PShape planet;
CelestialBody[] moons;
int red;
int green;
int blue;
PVector v;
//PShape globe;
int Type;
CelestialBody(float _radius, float _distance, float _orbitSpeed, int _red, int _green, int _blue, int type) {
v = PVector.random3D();
radius = _radius;
distance = _distance;
v.mult(distance);
orbitSpeed = _orbitSpeed;
red = _red;
green = _green;
blue = _blue;
//stroke(red, green, blue);
fill(red, green, blue);
if(type == 1 || type == 4){
planet = createShape(SPHERE, _radius);
}
else if(type == 2){
planet = createShape(BOX, _radius);
}
Type = type;
}
void orbit() {
angle += orbitSpeed;
if (moons != null) {
for (int i = 0; i < moons.length; i++) {
moons[i].orbit();
}
}
}
void spawnMoon(int total){
moons = new CelestialBody[total];
for(int i = 0; i < moons.length; i++){
float r = radius / random(2,5);
float d = random((radius + r), (radius + r)*2);
float o = random(0.01, 0.05);
moons[i] = new CelestialBody(r, d, o, (int)random(0, 256), (int)random(0, 256), (int)random(0, 256), 1);
}
}
void show() {
pushMatrix();
PVector v2 = new PVector(1,0,1);
PVector p = v.cross(v2);
rotate(angle,p.x, p.y, p.z);
translate(v.x, v.y, v.z);
if(Type == 4){
emissive(255, 255, 255);
pointLight(255, 255, 255, 0, 0, 0); //for the normal behaviour of the sun light
lightFalloff(0, 0, 0.00020); //light falls off right behind the surface of the sun
ambientLight(255, 255, 255, 0, 0, 0); //ambientLight in the center of the sun
}
//shape(globe);
shape(planet);
if (moons != null) {
for (int i = 0; i < moons.length; i++) {
moons[i].show();
}
}
noStroke();
popMatrix();
}
}

p5.js not drawing a 3d box

I am creating a simulator using P5.js. Within the simulator, I need a green box, however it does not seem to be appearing. The code is below:
var outputs = [];
function setup() {
createCanvas(600, 400, WEBGL);
background(200);
for (var i = 0; i < 1; i++) {
drop = new Water(width / 2, height / 2, 0, 1);
outputs[i] = drop;
}
}
function draw() {
push();
translate(200, 150, 0);
stroke(0, 100, 0);
fill(0, 255, 0);
box(150, 150, 150);
pop();
for (var i = 0; i < outputs.length; i++) {
outputs[i].update();
}
background(200);
}
Here is the water class:
function Water(x_, y_, z_, yVel_) {
this.r = random(0.25, 1);
this.xOff = random(-(this.r / 10), (this.r / 10));
this.zOff = random(-(this.r / 10), (this.r / 10));
this.x = x_ + this.xOff;
this.y = y_;
this.z = z_ + this.zOff;
this.yVel = yVel_;
this.pos = createVector(this.x, this.y, this.z);
this.show = function() {
push();
translate(this.pos.x, this.pos.y, this.pos.z);
noStroke();
fill(0, 0, 255);
sphere(this.r * 2);
pop();
}
this.update = function() {
this.vel = createVector(random(-(this.r / 10), (this.r / 10)),
this.yVel, random(-(this.r / 10),
(this.r / 10)));
this.pos.add(this.vel);
this.show();
}
}
This is a web based simulation, with another module which appears to be working fine.
Any help would be greatly appreciated. Thanks in advance!
Removing the parts that require the Water class, and moving the background function call to the top of draw, it seems to work just fine.
So, the problem is
Either that you forgot to put background on top
Or something's wrong with the Water class.
Here's your code with the mentioned problems fixed.
var outputs = [];
function setup() {
createCanvas(600, 400, WEBGL);
}
function draw() {
background(200);
push();
translate(200, 150, 0);
stroke(0, 100, 0);
fill(0, 255, 0);
box(150, 150, 150);
pop();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.1/p5.min.js"></script>
Its not rendering because you're background is over your scene
function draw() {
background(200);
push();
translate(200, 150, 0);
stroke(0, 100, 0);
fill(0, 255, 0);
box(150, 150, 150);
pop();
for (var i = 0; i < outputs.length; i++) {
outputs[i].update();
}
}
What your doing is drawing the box and the drops and you cover it all up with your background
if you don't have a background you will see how p5.js renders animation
p5.js not moving it, its just looping through draw every frame and the background covers up the previous frame

How to animate a 3D curve between two points on a map?

I am trying to do a twitter visualization.
I using curves to connect two points on the map.
Here is the code which I am using for it. It has been taken from an example by Chrisir from the processing forums.
void setup()
{
size( 800, 800, P3D );
} // setup
void draw()
{
// myCurveTest() ;
PVector firstpoint = new PVector (120, 320, -30);
PVector secondpoint = new PVector (320, 220, -30);
myCurve (firstpoint, secondpoint ) ;
firstpoint = new PVector (420, 220, 30);
secondpoint = new PVector (620, 120, -30);
myCurve (firstpoint, secondpoint ) ;
}
void myCurve (
PVector firstpoint,
PVector secondpoint) {
PVector beginningcontrolpoint = new PVector (120, firstpoint.y+1200, -30);
PVector endingcontrolpoint = new PVector (720, secondpoint.y+1200, -30);
myPointPVector(beginningcontrolpoint, color(255, 0, 0));
myPointPVector(firstpoint, color(0, 0, 255));
myPointPVector(secondpoint, color(0, 0, 255));
myPointPVector(endingcontrolpoint, color(255, 0, 0));
stroke (255);
noFill();
curve(
beginningcontrolpoint.x, beginningcontrolpoint.y, beginningcontrolpoint.z,
firstpoint.x, firstpoint.y, firstpoint.z,
secondpoint.x, secondpoint.y, secondpoint.z,
endingcontrolpoint.x, endingcontrolpoint.y, endingcontrolpoint.z);
}
void myPointPVector (PVector test, color col1) {
MyBox(test.x, test.y, test.z,
test.x+3, test.y, test.z,
9,
col1);
}
void MyBox(float x1, float y1, float z1, float x2, float y2, float z2, float weight, color strokeColour)
// was called drawLine; programmed by James Carruthers
// see http://processing.org/discourse/yabb2/YaBB.pl?num=1262458611/0#9
{
PVector p1 = new PVector(x1, y1, z1);
PVector p2 = new PVector(x2, y2, z2);
PVector v1 = new PVector(x2-x1, y2-y1, z2-z1);
float rho = sqrt(pow(v1.x, 2)+pow(v1.y, 2)+pow(v1.z, 2));
float phi = acos(v1.z/rho);
float the = atan2(v1.y, v1.x);
v1.mult(0.5);
pushMatrix();
translate(x1, y1, z1);
translate(v1.x, v1.y, v1.z);
rotateZ(the);
rotateY(phi);
noStroke();
fill(strokeColour);
box(weight, weight, p1.dist(p2)*1.2);
popMatrix();
}
I want to animated this 3D curve so that I can see them being drawn on the map. Can anyone help me out with this. I have tried everything from framecount to advanced animation libraried in processing but no luck yet :(
Thanks.
You may just calculate a parabola point by point, draw it using curveVertex and orbit it in 3D using translate and rotate, here an example (using 1.5.1/P3D/fontMode(SCREEN)):
float initial_x = -200;
float x = initial_x;
float y;
float y_offset;
float r = 200;// change this to change the height of the parabola
ArrayList<PVector> pts = new ArrayList<PVector>();
float mx = 70, my = -15, tmx, tmy;
boolean animating = false;
PFont f;
void setup() {
size( 800, 400, P3D);
background(255);
smooth();
f = createFont("Arial", 15);
textMode(SCREEN);
}
void draw() {
//lights();
background(255);
fill(100);
textFont(f, 15);
text("drag to orbit", width - 10 - textWidth("drag to orbit"), height -30);
text("any key to redraw parabola", width - 10 - textWidth("any key to redraw parabola"), height -10);
//rotate 3d
translate(width/4, height/2);
rotateY(radians(mx));
rotateZ(radians(my));
// to mark origin and help view 3d
noFill();
stroke(100);
box(20);
pushMatrix();
translate(100, 5, -100);
stroke(200);
fill(0, 20);
box(600, 2, 600);
popMatrix();
//store y offset
if (x == initial_x) {
y_offset = (sq(x)+2*x)/r;
}
// stop parabola
if ( x == initial_x || x < -initial_x + 2) {
x+=2;
animating = true;
// add to curve storage
pts.add(new PVector(x, y));
}
else {
animating = false;
}
//calc y
y = (sq(x)+2*x)/r - y_offset;
stroke(50, 30, 7);
noFill();
strokeWeight(1);
//draw at origin
translate(-initial_x, 0);
//draw curve
beginShape();
for (PVector p:pts) {
curveVertex(p.x, p.y);
}
endShape();
//draw a ball
if (!animating) {
translate(pts.get(frameCount%pts.size()).x, pts.get(frameCount%pts.size()).y);
noStroke();
fill(220, 190, 35);
sphere(4);
}
}
void mousePressed() {
tmx = mouseX;
tmy = mouseY;
}
void mouseDragged() {
mx = tmx - mouseX;
my = tmy - mouseY;
}
void keyPressed() {
x = -200;
pts.clear();
}
You're drawing the curves using the curve() command (http://processing.org/reference/curve_.html) which draws a Catmull-Rom spline. In your code, you're only drawing a single spline section (the one between the two control points), so what you're really interested in is "how can I draw only part of a Catmull-Rom spline section". I don't have the answer for that one, but if you change your curve(control1, first, second, control2) call into a bezier(first,c1,c2,second) call (where you will now have to come up with the code for the control points c1 and c2) instead, then you can use de Casteljau's algorithm to cut up a curve into two segments anywhere along it. If you slide up the where-to-cut-it point every frame, and then only draw the first segment that you get from the split operation, it'll look like a curve that draws itself from the start to the end point. See http://pomax.github.io/bezierinfo/#splitting for the description on how to do this (bonus: the source code is even in Processing)
Make use of the curvePoint() method. Here is a resolution to a similar problem:
http://forum.processing.org/one/topic/animation-with-curve.html.

How can i register when text and shapes has been clicked on?

rect(x, y, 100, 100)
text("click here", 50, 50)
Is there a way to use mousePressed() so it registers when these two items have been clicked on?
It sounds like you're looking for collision detection. Specifically, you're probably looking for point-rectangle collision detection, to determine whether the mouse is inside a rectangle.
Google is your friend, but here's an example:
float rectX;
float rectY;
float rectWidth;
float rectHeight;
void setup() {
size(300, 300);
rectX = 50;
rectY = 100;
rectWidth = 200;
rectHeight = 100;
}
void draw() {
background(64);
if (mouseX > rectX && mouseX < rectX + rectWidth && mouseY > rectY && mouseY < rectY + rectHeight) {
fill(255, 0, 0);
}
else {
fill(0, 255, 0);
}
rect(rectX, rectY, rectWidth, rectHeight);
}
Shameless self-promotion: here is a tutorial on collision detection in Processing.

Resources