/** * Returns a random unit Quaternion. * * <p>You can create a randomly directed unit vector using: * * <p>{@code PVector randomDir = new PVector(1.0f, 0.0f, 0.0f);} <br> * {@code randomDir = Quaternion.multiply(Quaternion.randomQuaternion(), randomDir);} */ public static final Quaternion randomQuaternion() { float seed = (float) Math.random(); float r1 = PApplet.sqrt(1.0f - seed); float r2 = PApplet.sqrt(seed); float t1 = 2.0f * PI * (float) Math.random(); float t2 = 2.0f * PI * (float) Math.random(); return new Quaternion( PApplet.sin(t1) * r1, PApplet.cos(t1) * r1, PApplet.sin(t2) * r2, PApplet.cos(t2) * r2); }
public void computeMidPoint() { PVector p1 = points.get(0); PVector p2 = points.get(points.size() - 1); int steps = (int) (25 * .5f * t); int i = (int) (steps * .5f); float s = (float) i / steps; float x = PApplet.lerp(p1.x, p2.x, s); float y = (is3D) ? PApplet.lerp(p1.y, p2.y, s) : PApplet.lerp(p1.y, p2.y, s) - h * PApplet.sin(s * PApplet.PI); float z = (is3D) ? h * PApplet.sin(s * PApplet.PI) : 0; midPoint = new PVector(x, y, z); }
// A function to rotate a vector public void rotateVector(PVector v, float theta) { float m = v.mag(); float a = v.heading2D(); a += theta; v.x = m * PApplet.cos(a); v.y = m * PApplet.sin(a); }
/** * Convenience method to calculate <code>res</code> vertices along a circle of <code>R</code> * radius * * @param R Radius of circle * @param res Number of points to calculate * @return */ public static UVertexList getCircle(float R, int res) { UVertexList vl = new UVertexList(); float D = TWO_PI / (float) (res - 1); for (int i = 0; i < res; i++) vl.add(PApplet.cos(D * (float) i) * R, PApplet.sin(D * (float) i) * R, 0); return vl; }
/** * Returns the exponential of the Quaternion. * * @see #log() */ public final Quaternion exp() { float theta = PApplet.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); if (theta < 1E-6f) return new Quaternion(this.x, this.y, this.z, PApplet.cos(theta)); else { float coef = PApplet.sin(theta) / theta; return new Quaternion(this.x * coef, this.y * coef, this.z * coef, PApplet.cos(theta)); } }
void randomWalk(Mimo m) { Simulation1.app.noiseSeed(Simulation1.app.millis()); float speed = Simulation1.app.noise(Simulation1.app.frameCount * 0.1f) * maxSpeed; if (Simulation1.app.random(1) < 0.99) { return; } float a = PApplet.map( Simulation1.app.random(1), 0, 1, directionChangeRange.x, directionChangeRange.y); m.vel = new PVector(PApplet.cos(a), PApplet.sin(a)); m.vel.mult(speed); }
private void calculateCoordinates() { float x = 0; float y = 0; float z = 0; coordinates = new PVector[latDetail + 1][longDetail + 1]; for (int a = 0 + (int) (latDetail * bottomCrop); a <= latDetail - (latDetail * topCrop); a++) { for (int b = 0 + (int) (longDetail * leftCrop); b <= longDetail - (longDetail * rightCrop); b++) { System.out.println("A:" + a + " " + "B:" + b); x = radius * PApplet.cos((PConstants.TWO_PI / longDetail) * b) * PApplet.sin((PConstants.PI / latDetail) * a); y = radius * PApplet.sin((PConstants.TWO_PI / longDetail) * b) * PApplet.sin((PConstants.PI / latDetail) * a); z = radius * PApplet.cos((PConstants.PI / latDetail) * a); // guardo las coordenadas // de sur a norte // y de este a oeste. // coordinates[a][b] = new PVector(x, y, z); } } }
/** * Returns the slerp interpolation of quaternions {@code a} and {@code b}, at time {@code t}. * * <p>{@code t} should range in {@code [0,1]}. Result is a when {@code t=0 } and {@code b} when * {@code t=1}. * * <p>When {@code allowFlip} is true (default) the slerp interpolation will always use the * "shortest path" between the quaternions' orientations, by "flipping" the source Quaternion if * needed (see {@link #negate()}). * * @param a the first Quaternion * @param b the second Quaternion * @param t the t interpolation parameter * @param allowFlip tells whether or not the interpolation allows axis flip */ public static final Quaternion slerp(Quaternion a, Quaternion b, float t, boolean allowFlip) { // Warning: this method should not normalize the Quaternion float cosAngle = Quaternion.dotProduct(a, b); float c1, c2; // Linear interpolation for close orientations if ((1.0 - PApplet.abs(cosAngle)) < 0.01) { c1 = 1.0f - t; c2 = t; } else { // Spherical interpolation float angle = PApplet.acos(PApplet.abs(cosAngle)); float sinAngle = PApplet.sin(angle); c1 = PApplet.sin(angle * (1.0f - t)) / sinAngle; c2 = PApplet.sin(angle * t) / sinAngle; } // Use the shortest path if (allowFlip && (cosAngle < 0.0)) c1 = -c1; return new Quaternion( c1 * a.x + c2 * b.x, c1 * a.y + c2 * b.y, c1 * a.z + c2 * b.z, c1 * a.w + c2 * b.w, false); }
// Project each corner of the object onto the "ground" void project(PVector[] _points) { for (int p = 0; p < _points.length; p++) { // Find the angle of the corner being project relative to the sun PVector projection = _points[p].get(); projection.sub(Stage.source); float angle = projection.heading2D(); // Calculate the distance of projection // Based on height of the point from the "ground" as defined by the // alt float _alt = PApplet.abs(_points[p].y - Stage.alt); float yOffset = _alt * PApplet.sin(angle); float radius = yOffset / PApplet.sin(angle); shadow[p] = _points[p].get(); shadow[p].add(new PVector(radius * PApplet.cos(angle), radius * PApplet.sin(angle))); // println("Source: " + source + "\t" + "Point: " + p + "\t" + // "Angle: " + degrees(angle) + "\t" + "Offset: " + offset); } }
/** * Sets the Quaternion as a rotation of {@link #axis() axis} and {@link #angle() angle} (in * radians). * * <p>The {@code axis} does not need to be normalized. A null {@code axis} will result in an * identity Quaternion. * * @param axis the PVector representing the axis * @param angle the angle in radians */ public void fromAxisAngle(PVector axis, float angle) { float norm = axis.mag(); if (norm < 1E-8f) { // Null rotation this.x = 0.0f; this.y = 0.0f; this.z = 0.0f; this.w = 1.0f; } else { float sin_half_angle = PApplet.sin(angle / 2.0f); this.x = sin_half_angle * axis.x / norm; this.y = sin_half_angle * axis.y / norm; this.z = sin_half_angle * axis.z / norm; this.w = PApplet.cos(angle / 2.0f); } }
public void computePoints() { // PVector p1 = map.worldPoint(ll1.x, ll1.y); // PVector p2 = map.worldPoint(ll2.x, ll2.y); PVector p1 = new PVector(0, 300); PVector p2 = new PVector(800, 300); int steps = 50; this.removeAll(); for (int i = 0; i <= steps; i++) { float s = (float) i / steps; float x = PApplet.lerp(p1.x, p2.x, s); float y = PApplet.lerp(p1.y, p2.y, s) - h * PApplet.sin(s * PApplet.PI); float z = 0; add(new PVector(x, y, z)); } }
private void update(Mimo m) { if (m.ancestor && (m.pos.x <= 0 || m.pos.x >= Simulation1.screenWidth || m.pos.y <= 0 || m.pos.y >= Simulation1.screenHeight)) { // orient the ancestor towards the center float a = PApplet.atan2( Simulation1.screenHeight / 2 - m.pos.y, Simulation1.screenWidth / 2 - m.pos.x); m.vel = new PVector(PApplet.cos(a), PApplet.sin(a)); float speed = Simulation1.app.noise(Simulation1.app.frameCount * 0.1f) * maxSpeed; m.vel.mult(speed); } else { randomWalk(m); } m.pos.add(m.vel); }
public void moveNormals() { changeMode(); pApplet.pushMatrix(); for (int j = 0; j < model.getSegmentCount(); j++) { Segment segment = model.getSegment(j); Face[] faces = segment.getFaces(); pApplet.beginShape(PConstants.QUADS); for (int i = 0; i < faces.length; i++) { PVector[] vertices = faces[i].getVertices(); PVector normal = faces[i].getNormal(); float nor = PApplet.abs(PApplet.sin(PApplet.radians((pApplet.frameCount + i))) * 100); for (PVector vertex : vertices) { pApplet.vertex( vertex.x + (normal.x * nor), vertex.y + (normal.y * nor), vertex.z + (normal.z * nor)); } } pApplet.endShape(); } pApplet.popMatrix(); }
/** * Rotate the vector by an angle (only 2D vectors), magnitude remains the same * * @param theta the angle of rotation */ public void rotate(float theta) { float xTemp = x; // Might need to check for rounding errors like with angleBetween function? x = x * PApplet.cos(theta) - y * PApplet.sin(theta); y = xTemp * PApplet.sin(theta) + y * PApplet.cos(theta); }