Thanks
here is a simple movement using curvepoint (comparable to lerp)
A more complex sketch
here is a more complex sketch:
The ArrayList<PointMy> listPointMy
are the vectors (I my sketch this is a track for a rollercoaster);
you want to look at function rollerCoaster()
Chrisir
// Track for the rollercoaster:
// holding the curveVertex points in 3D - the core data. Here you add and edit your points.
ArrayList<PointMy> listPointMy = new ArrayList();
// move a sphere along the curve (Rollercoaster)
boolean showRollercoasterFlag = false;
int showRollercoaster_i; // current number of sphere on track for the Rollercoaster CAR
int i2=0; // counter for the taken steps between 2 single points of track for rollercoaster
boolean firstTime=true;
PVector camPV=new PVector();
// ---------------------------------------------------------------------
// CORE functions
void setup() {
size(1440, 880, P3D);
background(255);
makeArrayList(); // the track
}// func
void draw() {
drawForNormal();
}//draw
//------------------------------------------------------------------------------
void drawForNormal() {
background(255);
lights();
// show ArrayList
showArrayList();
if (true) {
rollerCoaster();
}//if
}// func
// -------------------------------------------------------------------------
void makeArrayList() {
// http://de.wikipedia.org/wiki/Ellipse#Ellipsengleichung_.28Parameterform.29
float radiusX=300;
float radiusY=110;
float centerX=0;
float centerZ=0;
for (int angleStar = 0; angleStar <= 360; angleStar += 4) {
float starX = centerX + (cos (radians(angleStar)) * radiusX);
float starY = 0;
float starZ = centerZ + (sin (radians(angleStar)) * radiusY);
// the part on the right gets elevated
if (starX>220) {
starY=map(starX-220, 0, 310, -10, -420);
}
PVector newPVector = new PVector(starX, starY, starZ);
listPointMy.add ( new PointMy ( newPVector, false) ); // 3D
}//for
listPointMy.get(65).p.y -= 155;
}//func
void showArrayList() {
// show the curve
noFill();
stroke(0);
beginShape();
int i=0;
if (listPointMy.size()>0) {
listPointMy.get(i).useAsCurveVertexPVector();
for ( i = 0; i < listPointMy.size(); i++) {
listPointMy.get(i).useAsCurveVertexPVector();
}
i=listPointMy.size()-1;
listPointMy.get(i).useAsCurveVertexPVector();
}//if
endShape();
//show the points (additionally)
noStroke();
float rad=3;
for ( i = 0; i < listPointMy.size(); i++) {
PointMy pm = listPointMy.get(i);
PVector pv=pm.p;
// if we are close to the mouse, color green, else red
if (dist(mouseX, mouseY, pv.x, pv.y)<11 || pm.selected) {
// near to mouse
fill( 0, 255, 0); // green
rad=7;
} else {
// normal
fill(255, 0, 0); // red
rad=3;
}
pm.showAsSphere(rad);
}//for
}//func
// ------------------------------------------------------------------------
// interprete the spline as a rollercoaster track with a CAR on it
void rollerCoaster() {
ellipseMode(CENTER);
// get two points between which the CAR currently is running
PointMy pm1=listPointMy.get( showRollercoaster_i );
PointMy pm2=listPointMy.get( showRollercoaster_i+1 );
// get dist between 2 points
float dist1 = pm1.p.dist(pm2.p);
// calculate the steps between the 2 points depending on dist1 between them (smooth running)
int steps; // = 9;
steps = int(dist1 / 2);
// calc t (can be seen as amt in lerp() / curvePoint)
float t = i2 / float(steps);
// similar to lerp() wth amt:
float x = curvePoint(pm1.p.x, pm1.p.x, pm2.p.x, pm2.p.x, t);
float y = curvePoint(pm1.p.y, pm1.p.y, pm2.p.y, pm2.p.y, t);
float z = curvePoint(pm1.p.z, pm1.p.z, pm2.p.z, pm2.p.z, t);
// different camera view for rollercoaster view
setRollerCoasterCamera(x, y, z, t);
// show ball&box [the rollercoaster car]
if (true) {
fill(255, 2, 244);
noStroke();
pushMatrix();
translate(x, y, z);
box(9);
translate(0, -5, 0);
sphere(7);
popMatrix();
}
i2++;
if (i2>steps) {
showRollercoaster_i++;
if (showRollercoaster_i>listPointMy.size()-2) { // little rough management at the end of arraylist... ???
showRollercoaster_i=0;
}//if
i2=0;
}//if
}//func
void setRollerCoasterCamera(float x, float y, float z,
float t) {
// camera view for rollercoaster view
camPV = getCameraPositionFromBall(x, y, z);
camera(camPV.x, camPV.y-4, camPV.z,
0, 0, 0,
0, 1, 0);
}//func
PVector getCameraPositionFromBall(float bx, float by, float bz) {
// leading to a result that has the points nicely on a circle.
// Usage: centerPV is at the center of a virtual circle, outsidePV on its circumference.
// Function returns the point (new PVector(x1, y1, z1)) with the radius radius1 that prolongs the Radius
// from centerPV over outsidePV (further out) to the resulting PVector new PVector(x1, y1, z1).
PVector centerPV = new PVector(0, 0, 0);
PVector outsidePV = new PVector(bx, by, bz);
float angle1 = atan2(outsidePV.z-centerPV.z, outsidePV.x-centerPV.x);
float radius1 = 0;// pre-init
// adjust : we calculate the radius here
// radius1 = 700/2 + 120;
float d0 = centerPV.dist(outsidePV);
// d0 = dist(centerPV.x, centerPV.y, outsidePV.x, outsidePV.y);
float d1 = map (d0, 10, 1000, 140, 1450); // float d1 = map (d0, 10, 1000, 40, 1350);
radius1 = d1;
float x1 = cos(angle1) * radius1 + centerPV.x;
float y1 = 0;
//y1 = lerp(centerPV.y, outsidePV.y, map (d0, 10, 1000, 1.5, 1.9));
//y1 = lerp(centerPV.y, outsidePV.y, 1.3);
y1 = outsidePV.y-26;
float z1 = sin(angle1) * radius1 + centerPV.y;
return new PVector(x1, y1, z1);
} // method
// ==================================================================
class PointMy {
// one point one the track
PVector p; // position
boolean selected=false; // selected y/n
float theX, theY; // screenX and screenY
// constructor
PointMy( PVector p_, boolean selected_ ) {
p = p_.copy();
selected = selected_;
} // constructor
void showAsSphere( float rad ) {
pushMatrix();
translate(p.x, p.y, p.z);
theX = screenX(0, 0, 0); // monitor and store screen position
theY = screenY(0, 0, 0);
noStroke();
sphere(rad);
popMatrix();
} // method
void useAsCurveVertexPVector() {
// like curveVertex but gets a PVector as input
// (just an easy way to use vectors for curveVertex)
curveVertex(p.x, p.y, p.z);
} // method
//
}//class
//