We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
Page Index Toggle Pages: 1
arc spring?? (Read 542 times)
arc spring??
Dec 8th, 2005, 5:48pm
 
hello, i recently started using Processing and i have a quiestion.
does anyone know whether it is possible to make a spring which moves in an arc??
(the one showed in the Learning page moves vertically)

i am planning to make something like darts and i need this for the arm part.

thank you for any help!!!
Re: arc spring??
Reply #1 - Dec 9th, 2005, 8:07pm
 
Here's a very convoluted demonstration, but it uses draggable objects so you can see how it works better.

You can model your curve on a bezier path. The code below demonstrates a spring which sits on a bezier curve. A bezier curve is drawn by calculating the points on a path dependant on 4 co-ords. You use a value called "t" and modify that value between 0.0 and 1.0 to get all the points along the path to make your curve. The command bezierPoint() does all this for you.

Use the space bar to see the spring in action and use "p" if you want a print out of the curve you've made.
Code:

float M = 0.8; // Mass
float K = 0.21; // Spring constant
float D = 0.92; // Damping
float R = 0.5; // Rest position
// Spring simulation variables
float ps = 0.5; // Position
float vs = 0.0; // Velocity
float as = 0; // Acceleration
float f = 0; // Force
Draggable [] anchor = new Draggable[2];
Draggable [] control = new Draggable[2];
Draggable ball;
void setup(){
size(400,400,P3D);
anchor[0] = new Draggable (100,100,10,color(100,100,200),color(100,200,200),"rect");
anchor[1] = new Draggable (300,300,10,color(100,100,200),color(100,200,200),"rect");
control[0] = new Draggable (100,300,10,color(100,100,200),color(100,200,200),"ellipse");
control[1] = new Draggable (300,100,10,color(100,100,200),color(100,200,200),"ellipse");
float y = bezierPoint(anchor[0].y,control[0].y,control[1].y,anchor[1].y,0.5);
float x = bezierPoint(anchor[0].x,control[0].x,control[1].x,anchor[1].x,0.5);
ball = new Draggable (x,y,10,color(100,100,200),color(100,200,200),"ellipse");
ellipseMode(CENTER);
rectMode(CENTER);
}
void draw(){
background(144,130,140);
stroke(0);
bezier(
anchor[0].x,anchor[0].y,control[0].x,control[0].y,
control[1].x,control[1].y,anchor[1].x,anchor[1].y);
for (int i = 0; i < 2; i++){
anchor[i].draw();
control[i].draw();
anchor[i].update();
control[i].update();
ball.draw();
ball.updateSpring(
anchor[0].x,anchor[0].y,control[0].x,control[0].y,
control[1].x,control[1].y,anchor[1].x,anchor[1].y);
}
if(keyPressed){
switch(key){
case ' ':
ball.t = constrain(ball.t + 0.05, 0.0, 1.0);
break;
case 'p':
//print out co-ords of bezier path (rather than figure it out)
println("bezier("+
anchor[0].x+", "+anchor[0].y+", "+control[0].x+", "+control[0].y+", "+
control[1].x+", "+control[1].y+", "+anchor[1].x+", "+anchor[1].y+");");
}
}
}
class Draggable {
float x,y,t;
int size,c1,c2;
String mode;
boolean locked = false;
Draggable (float x, float y, int size, color c1, color c2, String mode) {
this.x = x;
this.y = y;
this.size = size;
this.c1 = c1;
this.c2 = c2;
this.mode = mode;
t = 0.5;
}
void draw(){
noStroke();
if (locked || over()){
fill(c1);
}
else{
fill(c2);
}
if (mode == "rect"){
stroke(c1);
rect(x,y,size*2,size*2);
}
if (mode == "ellipse"){
stroke(c1);
ellipse(x,y,size*2,size*2);
}
}
void updateSpring(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4){
// Update the spring position
if(!keyPressed) {
f = -K * (t - R); // f=-ky
as = f / M; // Set the acceleration, f=ma == a=f/m
vs = D * (vs + as); // Set the velocity
t = t + vs; // Updated position
}
if(abs(vs) < 0.1) {
vs = 0.0;
}
x = bezierPoint(x1, x2, x3, x4, t);
y = bezierPoint(y1, y2, y3, y4, t);
}
void update(){
if (over() && mousePressed){
locked = true;
}
if (locked){
x = mouseX;
y = mouseY;
}
if (!mousePressed){
locked = false;
}
}
boolean over(){
if (mouseX <= x+size && mouseX >= x-size && mouseY <= y+size && mouseY >= y-size){
return true;
}
else{
return false;
}
}
}

There's possibly another method, but I hope this gives you a kick start.
Page Index Toggle Pages: 1