final PVector o = origin;
final PVector v = vector;
- float x = (o.x*(v.y*v.y + v.z*v.z) - v.x*(o.y*v.y + o.z*v.z - v.x*p.x - v.y*p.y - v.z*p.z))*(1 - cos(t)) + p.x*cos(t) + (-o.z*v.y + o.y*v.z - v.z*p.y + v.y*p.z)*sin(t);
- float y = (o.y*(v.x*v.x + v.z*v.z) - v.y*(o.x*v.x + o.z*v.z - v.x*p.x - v.y*p.y - v.z*p.z))*(1 - cos(t)) + p.y*cos(t) + (o.z*v.x - o.x*v.z + v.z*p.x - v.x*p.z)*sin(t);
- float z = (o.z*(v.x*v.x + v.y*v.y) - v.z*(o.x*v.x + o.y*v.y - v.x*p.x - v.y*p.y - v.z*p.z))*(1 - cos(t)) + p.z*cos(t) + (-o.y*v.x + o.x*v.y - v.y*p.x + v.x*p.y)*sin(t);
+ final float cost = cos(t);
+ final float sint = sin(t);
+
+ float x = (o.x*(v.y*v.y + v.z*v.z) - v.x*(o.y*v.y + o.z*v.z - v.x*p.x - v.y*p.y - v.z*p.z))*(1 - cost) + p.x*cost + (-o.z*v.y + o.y*v.z - v.z*p.y + v.y*p.z)*sint;
+ float y = (o.y*(v.x*v.x + v.z*v.z) - v.y*(o.x*v.x + o.z*v.z - v.x*p.x - v.y*p.y - v.z*p.z))*(1 - cost) + p.y*cost + (o.z*v.x - o.x*v.z + v.z*p.x - v.x*p.z)*sint;
+ float z = (o.z*(v.x*v.x + v.y*v.y) - v.z*(o.x*v.x + o.y*v.y - v.x*p.x - v.y*p.y - v.z*p.z))*(1 - cost) + p.z*cost + (-o.y*v.x + o.x*v.y - v.y*p.x + v.x*p.y)*sint;
return new PVector(x, y, z);
}
}
Line getAxis() {
return axis;
}
+
+ PVector getPhaseNormal() {
+ return phaseNormal;
+ }
+
+ float getPhase() {
+ return phase;
+ }
void step(int deltaMs) {
// Rotate
// Find the appropriate point for the current rotation
// of the helix.
- PVector toroidPoint = pointOnToroidalAxis(t);
+ PVector toroidPoint = axisPoint;
+ toroidPoint.add(phaseNormal);
+ toroidPoint = axis.rotatePoint(toroidPoint, (t / period) * TWO_PI + phase);
// The rotated point represents the middle of the girth of
// the helix. Figure out if the current point is inside that
// axis. Until everything animates in the model reference
// frame, this has to be calculated at every step because
// the helices rotate.
- float t = h1.getAxis().getTValue(pt) + spokePhase;
+ Line axis = h1.getAxis();
+ float t = axis.getTValue(pt) + spokePhase;
float spokeAxisTValue = floor(((t + spokePeriod/2) / spokePeriod)) * spokePeriod;
- PVector h1point = h1.pointOnToroidalAxis(spokeAxisTValue);
- PVector h2point = h2.pointOnToroidalAxis(spokeAxisTValue);
- PVector spokeVector = PVector.sub(h2point, h1point);
+ PVector h1point = axis.getPointAt(t);
+ h1point.add(h1.getPhaseNormal());
+ h1point = axis.rotatePoint(h1point, (t / helixCoilPeriod) * TWO_PI + h1.getPhase());
+ // TODO(shaheen) investigate why h1.getAxis().getPointAt(spokeAxisTValue) doesn't quite
+ // have the same value as finding the middle between h1point and h2point.
+ PVector spokeCenter = h1.getAxis().getPointAt(spokeAxisTValue);
+ PVector spokeVector = PVector.sub(h1point, spokeCenter);
spokeVector.normalize();
Line spokeLine = new Line(h1point, spokeVector);
- float spokeLength = PVector.dist(h1point, h2point);
- // TODO(shaheen) investigate why h1.getAxis().getPointAt(spokeAxisTValue) doesn't quite
- // have the same value.
- PVector spokeCenter = PVector.add(h1point, PVector.mult(spokeVector, spokeLength/2.f));
PVector pointOnSpoke = spokeLine.projectPoint(pt);
float b = ((PVector.dist(pt, pointOnSpoke) < spokeGirth) && (PVector.dist(pointOnSpoke, spokeCenter) < spokeRadius)) ? 100.f : 0.f;
return color(100, 80.f, b);