├── resources ├── code │ ├── ant-contrib-1.0b3.jar │ ├── deploy_web.sh │ ├── doc.sh │ └── ExampleTaglet.java └── stylesheet.css ├── .gitignore ├── src └── peasy │ ├── PeasyWheelHandler.java │ ├── PeasyDragHandler.java │ ├── InterpolationManager.java │ ├── CameraState.java │ ├── DampedAction.java │ ├── org │ └── apache │ │ └── commons │ │ └── math │ │ ├── geometry │ │ ├── NotARotationMatrixException.java │ │ ├── CardanEulerSingularityException.java │ │ ├── RotationOrder.java │ │ └── Vector3D.java │ │ └── MathException.java │ ├── InterpolationUtil.java │ └── PeasyCam.java ├── library.properties ├── .pydevproject ├── .classpath ├── .fatjar ├── commons-math-1.2 ├── PEASY-README.txt ├── NOTICE.txt ├── RELEASE-NOTES.txt └── LICENSE.txt ├── examples ├── HelloPeasy │ └── HelloPeasy.pde ├── HeadUpDisplay │ └── HeadUpDisplay.pde ├── CameraStates │ └── CameraStates.pde ├── HelloPeasy_Offscreen │ └── HelloPeasy_Offscreen.pde ├── ReassignDragHandler │ └── ReassignDragHandler.pde ├── MultiView_Offscreen │ └── MultiView_Offscreen.pde └── MultiView_Onscreen │ └── MultiView_Onscreen.pde ├── .project ├── test └── examples │ ├── HelloPeasy │ └── HelloPeasy.java │ ├── HeadUpDisplay │ └── HeadUpDisplay.java │ ├── CameraStates │ └── CameraStates.java │ ├── Resizeable │ └── Resizeable.java │ ├── MultiView_Offscreen │ └── MultiView_Offscreen.java │ ├── Resizeable_Offscreen │ └── Resizeable_Offscreen.java │ └── MultiView_Onscreen │ └── MultiView_Onscreen.java ├── test-export.jardesc ├── .settings ├── org.eclipse.jdt.ui.prefs └── org.eclipse.jdt.core.prefs ├── web ├── stylesheet.css └── index.html ├── README.textile └── LICENSE.txt /resources/code/ant-contrib-1.0b3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdf/peasycam/HEAD/resources/code/ant-contrib-1.0b3.jar -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | PeasyCam.jar 2 | distribution 3 | bin 4 | examples/*/applet 5 | web/peasycam.jar 6 | reference 7 | *.swp 8 | 9 | -------------------------------------------------------------------------------- /src/peasy/PeasyWheelHandler.java: -------------------------------------------------------------------------------- 1 | package peasy; 2 | 3 | public interface PeasyWheelHandler { 4 | public void handleWheel(final int delta); 5 | } 6 | -------------------------------------------------------------------------------- /src/peasy/PeasyDragHandler.java: -------------------------------------------------------------------------------- 1 | package peasy; 2 | 3 | public interface PeasyDragHandler { 4 | public void handleDrag(final double dx, final double dy); 5 | } 6 | -------------------------------------------------------------------------------- /resources/code/deploy_web.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd /c/europa-winter07/workspace/PeasyCam/distribution/web 3 | chmod -R a+rwX * 4 | rsync -azv --exclude '.svn/' --delete -e ssh * mrfeinberg.com:/var/www/html/mrfeinberg.com/peasycam 5 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name = PeasyCam 2 | authors = [Jonathan Feinberg](http://mrfeinberg.com/) 3 | url = http://mrfeinberg.com/peasycam/ 4 | categories = 3D 5 | sentence = A mouse driven camera-control library for 3D sketches. 6 | version = 301 7 | prettyVersion = 301 8 | minRevision = 227 9 | maxRevision = 0 10 | -------------------------------------------------------------------------------- /.pydevproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | python 2.6 6 | Default 7 | 8 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.fatjar: -------------------------------------------------------------------------------- 1 | #Fat Jar Configuration File 2 | #Thu Jun 20 21:46:04 EDT 2013 3 | onejar.license.required=true 4 | manifest.classpath= 5 | manifest.removesigners=true 6 | onejar.checkbox=false 7 | jarname=HelloPeasy.jar 8 | manifest.mergeall=true 9 | manifest.mainclass=peasy.test.TestPeasy 10 | manifest.file= 11 | jarname.isextern=false 12 | onejar.expand= 13 | excludes= 14 | includes= 15 | -------------------------------------------------------------------------------- /commons-math-1.2/PEASY-README.txt: -------------------------------------------------------------------------------- 1 | PeasyCam uses a tiny subset of the commons math project, to wit, 2 | the geometry routines. Per the rights outlined in its 3 | Apache License, I've "modified" commons math by throwing eveything 4 | away that isn't the geometry routines. 5 | 6 | In order to avoid conflicts with other instances of commons math in 7 | a user's classpath, I've modified the packages. 8 | 9 | The complete commons math library is available at 10 | 11 | http://commons.apache.org/math/ -------------------------------------------------------------------------------- /resources/code/doc.sh: -------------------------------------------------------------------------------- 1 | # a shell script to create a java documentation 2 | # for a processing library. 3 | # 4 | # make changes to the variables below so they 5 | # fit the structure of your library 6 | 7 | # the package name of your library 8 | package=peasy; 9 | 10 | # source folder location 11 | src=../src; 12 | 13 | # the destination folder of your documentation 14 | dest=../documentation; 15 | 16 | 17 | # compile the java documentation 18 | javadoc -d $dest -stylesheetfile ./stylesheet.css -sourcepath ${src} ${package} 19 | -------------------------------------------------------------------------------- /examples/HelloPeasy/HelloPeasy.pde: -------------------------------------------------------------------------------- 1 | 2 | import peasy.PeasyCam; 3 | 4 | 5 | PeasyCam cam; 6 | 7 | public void settings() { 8 | size(800, 600, P3D); 9 | } 10 | 11 | public void setup() { 12 | cam = new PeasyCam(this, 400); 13 | } 14 | 15 | public void draw() { 16 | rotateX(-.5f); 17 | rotateY(-.5f); 18 | lights(); 19 | scale(10); 20 | strokeWeight(1 / 10f); 21 | background(0); 22 | fill(255, 0, 0); 23 | box(30); 24 | pushMatrix(); 25 | translate(0, 0, 20); 26 | fill(0, 0, 255); 27 | box(5); 28 | popMatrix(); 29 | } 30 | -------------------------------------------------------------------------------- /src/peasy/InterpolationManager.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package peasy; 5 | 6 | import peasy.PeasyCam.AbstractInterp; 7 | 8 | class InterpolationManager { 9 | private AbstractInterp currentInterpolator = null; 10 | 11 | protected synchronized void startInterpolation(final AbstractInterp interpolation) { 12 | cancelInterpolation(); 13 | currentInterpolator = interpolation; 14 | currentInterpolator.start(); 15 | } 16 | 17 | protected synchronized void cancelInterpolation() { 18 | if (currentInterpolator != null) { 19 | currentInterpolator.cancel(); 20 | currentInterpolator = null; 21 | } 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | PeasyCam 4 | 5 | 6 | 7 | 8 | 9 | org.python.pydev.PyDevBuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.jdt.core.javabuilder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.python.pydev.pythonNature 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/HeadUpDisplay/HeadUpDisplay.pde: -------------------------------------------------------------------------------- 1 | 2 | import peasy.PeasyCam; 3 | 4 | 5 | // 6 | // screen-aligned, orthographic HUD-scope 7 | // 8 | 9 | PeasyCam cam; 10 | 11 | public void settings() { 12 | size(800, 600, P3D); 13 | smooth(8); 14 | } 15 | 16 | public void setup() { 17 | cam = new PeasyCam(this, 400); 18 | } 19 | 20 | public void draw() { 21 | rotateX(-.5f); 22 | rotateY(-.5f); 23 | lights(); 24 | scale(10); 25 | strokeWeight(1 / 10f); 26 | background(0); 27 | fill(96, 255, 0); 28 | box(30); 29 | pushMatrix(); 30 | translate(0, 0, 20); 31 | fill(0, 96, 255); 32 | box(5); 33 | popMatrix(); 34 | 35 | cam.beginHUD(); 36 | fill(0, 128); 37 | rect(0, 0, 70, 30); 38 | fill(255); 39 | text("" + nfc(frameRate, 2), 10, 18); 40 | cam.endHUD(); 41 | } 42 | -------------------------------------------------------------------------------- /test/examples/HelloPeasy/HelloPeasy.java: -------------------------------------------------------------------------------- 1 | package examples.HelloPeasy; 2 | 3 | import peasy.PeasyCam; 4 | import processing.core.PApplet; 5 | 6 | public class HelloPeasy extends PApplet { 7 | 8 | PeasyCam cam; 9 | 10 | public void settings() { 11 | size(800, 600, P3D); 12 | } 13 | 14 | public void setup() { 15 | cam = new PeasyCam(this, 400); 16 | } 17 | 18 | public void draw() { 19 | rotateX(-.5f); 20 | rotateY(-.5f); 21 | lights(); 22 | scale(10); 23 | strokeWeight(1 / 10f); 24 | background(0); 25 | fill(255, 0, 0); 26 | box(30); 27 | pushMatrix(); 28 | translate(0, 0, 20); 29 | fill(0, 0, 255); 30 | box(5); 31 | popMatrix(); 32 | } 33 | 34 | public static void main(String args[]) { 35 | PApplet.main(new String[] { HelloPeasy.class.getName() }); 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /examples/CameraStates/CameraStates.pde: -------------------------------------------------------------------------------- 1 | 2 | import peasy.*; 3 | 4 | 5 | // 6 | // '1' save current camera-state 7 | // '2' apply saved camera-state 8 | // 9 | 10 | PeasyCam cam; 11 | 12 | public void settings() { 13 | size(800, 600, P3D); 14 | } 15 | 16 | public void setup() { 17 | cam = new PeasyCam(this, 400); 18 | state = cam.getState(); 19 | } 20 | 21 | public void draw() { 22 | rotateX(-.5f); 23 | rotateY(-.5f); 24 | lights(); 25 | scale(10); 26 | strokeWeight(1 / 10f); 27 | background(0); 28 | fill(220, 255, 0); 29 | box(30); 30 | pushMatrix(); 31 | translate(0, 0, 20); 32 | fill(0, 96, 255); 33 | box(5); 34 | popMatrix(); 35 | } 36 | 37 | CameraState state; 38 | 39 | public void keyReleased() { 40 | if (key == '1') state = cam.getState(); 41 | if (key == '2') cam.setState(state, 1000); 42 | } 43 | -------------------------------------------------------------------------------- /examples/HelloPeasy_Offscreen/HelloPeasy_Offscreen.pde: -------------------------------------------------------------------------------- 1 | import peasy.PeasyCam; 2 | 3 | PeasyCam cam; 4 | PGraphics canvas; 5 | 6 | void setup() 7 | { 8 | size(500, 500, P2D); 9 | cam = new PeasyCam(this, 400); 10 | 11 | canvas = createGraphics(width, height, P3D); 12 | } 13 | 14 | void draw() 15 | { 16 | // draw a simple rotating cube around a sphere onto an offscreen canvas 17 | canvas.beginDraw(); 18 | canvas.background(55); 19 | 20 | canvas.pushMatrix(); 21 | 22 | canvas.rotateX(radians(frameCount % 360)); 23 | canvas.rotateZ(radians(frameCount % 360)); 24 | 25 | canvas.noStroke(); 26 | canvas.fill(20, 20, 20); 27 | canvas.box(100); 28 | 29 | canvas.fill(150, 255, 255); 30 | canvas.sphere(60); 31 | 32 | canvas.popMatrix(); 33 | canvas.endDraw(); 34 | 35 | // apply view matrix of peasy to canvas 36 | cam.getState().apply(canvas); 37 | 38 | // draw canvas onto onscreen 39 | image(canvas, 0, 0); 40 | } -------------------------------------------------------------------------------- /examples/ReassignDragHandler/ReassignDragHandler.pde: -------------------------------------------------------------------------------- 1 | import peasy.*; 2 | 3 | PeasyCam cam; 4 | 5 | void setup() { 6 | size(600, 600, P3D); 7 | 8 | cam = new PeasyCam(this, 100); 9 | cam.setMinimumDistance(100); 10 | cam.setMaximumDistance(500); 11 | 12 | // Reassign some drag handlers in order to free the left-click-mouse-drag for other uses 13 | PeasyDragHandler orbitDH = cam.getRotateDragHandler(); // get the RotateDragHandler 14 | cam.setCenterDragHandler(orbitDH); // set it to the Center/Wheel drag 15 | PeasyDragHandler panDH = cam.getPanDragHandler(); // get the PanDragHandler 16 | cam.setRightDragHandler(panDH); // set it to the right-button mouse drag 17 | cam.setLeftDragHandler(null); // sets no left-drag Handler 18 | } 19 | void draw() { 20 | background(0); 21 | fill(255, 0, 0); 22 | box(30); 23 | pushMatrix(); 24 | translate(0, 0, 20); 25 | fill(0, 0, 255); 26 | box(5); 27 | popMatrix(); 28 | } 29 | -------------------------------------------------------------------------------- /test/examples/HeadUpDisplay/HeadUpDisplay.java: -------------------------------------------------------------------------------- 1 | package examples.HeadUpDisplay; 2 | 3 | import peasy.PeasyCam; 4 | import processing.core.PApplet; 5 | 6 | public class HeadUpDisplay extends PApplet { 7 | 8 | // 9 | // screen-aligned, orthographic HUD-scope 10 | // 11 | PeasyCam cam; 12 | 13 | public void settings() { 14 | size(800, 600, P3D); 15 | smooth(8); 16 | } 17 | 18 | public void setup() { 19 | cam = new PeasyCam(this, 400); 20 | } 21 | 22 | public void draw() { 23 | rotateX(-.5f); 24 | rotateY(-.5f); 25 | lights(); 26 | scale(10); 27 | strokeWeight(1 / 10f); 28 | background(0); 29 | fill(96, 255, 0); 30 | box(30); 31 | pushMatrix(); 32 | translate(0, 0, 20); 33 | fill(0, 96, 255); 34 | box(5); 35 | popMatrix(); 36 | 37 | cam.beginHUD(); 38 | fill(0, 128); 39 | rect(0, 0, 70, 30); 40 | fill(255); 41 | text("" + nfc(frameRate, 2), 10, 18); 42 | cam.endHUD(); 43 | } 44 | 45 | public static void main(String args[]) { 46 | PApplet.main(new String[] { HeadUpDisplay.class.getName() }); 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /test/examples/CameraStates/CameraStates.java: -------------------------------------------------------------------------------- 1 | package examples.CameraStates; 2 | 3 | import peasy.*; 4 | import processing.core.PApplet; 5 | 6 | public class CameraStates extends PApplet { 7 | 8 | // 9 | // '1' save current camera-state 10 | // '2' apply saved camera-state 11 | // 12 | 13 | PeasyCam cam; 14 | 15 | public void settings() { 16 | size(800, 600, P3D); 17 | } 18 | 19 | public void setup() { 20 | cam = new PeasyCam(this, 400); 21 | state = cam.getState(); 22 | } 23 | 24 | public void draw() { 25 | rotateX(-.5f); 26 | rotateY(-.5f); 27 | lights(); 28 | scale(10); 29 | strokeWeight(1 / 10f); 30 | background(0); 31 | fill(220, 255, 0); 32 | box(30); 33 | pushMatrix(); 34 | translate(0, 0, 20); 35 | fill(0, 96, 255); 36 | box(5); 37 | popMatrix(); 38 | } 39 | 40 | CameraState state; 41 | 42 | public void keyReleased() { 43 | if (key == '1') 44 | state = cam.getState(); 45 | if (key == '2') 46 | cam.setState(state, 1000); 47 | } 48 | 49 | public static void main(String args[]) { 50 | PApplet.main(new String[] { CameraStates.class.getName() }); 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /test-export.jardesc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /test/examples/Resizeable/Resizeable.java: -------------------------------------------------------------------------------- 1 | package examples.Resizeable; 2 | 3 | import peasy.PeasyCam; 4 | import processing.core.PApplet; 5 | 6 | public class Resizeable extends PApplet { 7 | 8 | // 9 | // Resizeable Window example. 10 | // 11 | 12 | PeasyCam cam; 13 | 14 | public void settings() { 15 | size(800, 600, P3D); 16 | smooth(8); 17 | } 18 | 19 | public void setup() { 20 | surface.setResizable(true); 21 | cam = new PeasyCam(this, 400); 22 | } 23 | 24 | public void handleResize(){ 25 | 26 | cam.setViewport(0, 0, width, height); 27 | cam.feed(); 28 | } 29 | 30 | public void draw() { 31 | 32 | handleResize(); 33 | 34 | perspective(60 * DEG_TO_RAD, width/(float)height, 1, 20000); 35 | rotateX(-.5f); 36 | rotateY(-.5f); 37 | lights(); 38 | scale(10); 39 | strokeWeight(1 / 10f); 40 | background(0); 41 | fill(96, 255, 0); 42 | box(30); 43 | pushMatrix(); 44 | translate(0, 0, 20); 45 | fill(0, 96, 255); 46 | box(5); 47 | popMatrix(); 48 | 49 | cam.beginHUD(); 50 | fill(0, 128); 51 | rect(0, 0, 70, 30); 52 | fill(255); 53 | text("" + nfc(frameRate, 2), 10, 18); 54 | cam.endHUD(); 55 | } 56 | 57 | public static void main(String args[]) { 58 | PApplet.main(new String[] { Resizeable.class.getName() }); 59 | } 60 | 61 | } -------------------------------------------------------------------------------- /src/peasy/CameraState.java: -------------------------------------------------------------------------------- 1 | /* 2 | The PeasyCam Processing library, which provides an easy-peasy 3 | camera for 3D sketching. 4 | 5 | Copyright 2008 Jonathan Feinberg 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | package peasy; 20 | 21 | import java.io.Serializable; 22 | 23 | import peasy.org.apache.commons.math.geometry.Rotation; 24 | import peasy.org.apache.commons.math.geometry.Vector3D; 25 | import processing.core.PApplet; 26 | import processing.core.PGraphics; 27 | 28 | public class CameraState implements Serializable { 29 | private static final long serialVersionUID = 1L; 30 | final Rotation rotation; 31 | final Vector3D center; 32 | final double distance; 33 | 34 | public CameraState(final Rotation rotation, final Vector3D center, 35 | final double distance) { 36 | this.rotation = rotation; 37 | this.center = center; 38 | this.distance = distance; 39 | } 40 | 41 | public void apply(final PApplet a) { 42 | if (a.recorder != null) { 43 | apply(a.recorder); 44 | } 45 | apply(a.g); 46 | } 47 | 48 | public void apply(final PGraphics g) { 49 | PeasyCam.apply(g, center, rotation, distance); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/peasy/DampedAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | The PeasyCam Processing library, which provides an easy-peasy 3 | camera for 3D sketching. 4 | 5 | Copyright 2008 Jonathan Feinberg 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | package peasy; 20 | 21 | /** 22 | * Based on a damned clever and aesthetic idea by David Bollinger. 23 | * 24 | * http://www.davebollinger.com/works/p5/catmouse/CatMouse.pde.txt 25 | * 26 | * @author jdf 27 | * 28 | */ 29 | abstract public class DampedAction { 30 | private final PeasyCam p; 31 | private double velocity; 32 | private final double damping; 33 | 34 | public DampedAction(final PeasyCam p) { 35 | this(p, 0.16); 36 | } 37 | 38 | public DampedAction(final PeasyCam p, final double friction) { 39 | this.p = p; 40 | this.velocity = 0; 41 | this.damping = 1.0 - friction; 42 | p.getApplet().registerMethod("draw", this); 43 | } 44 | 45 | public void impulse(final double impulse) { 46 | velocity += impulse; 47 | } 48 | 49 | public void draw() { 50 | if (velocity == 0) { 51 | return; 52 | } 53 | behave(velocity); 54 | p.feed(); 55 | velocity *= damping; 56 | if (Math.abs(velocity) < .001) { 57 | velocity = 0; 58 | } 59 | } 60 | 61 | public void stop() { 62 | velocity = 0; 63 | } 64 | 65 | abstract protected void behave(final double velocity); 66 | } 67 | -------------------------------------------------------------------------------- /src/peasy/org/apache/commons/math/geometry/NotARotationMatrixException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package peasy.org.apache.commons.math.geometry; 19 | 20 | import peasy.org.apache.commons.math.MathException; 21 | 22 | /** 23 | * This class represents exceptions thrown while building rotations from 24 | * matrices. 25 | * 26 | * @version $Revision: 627994 $ $Date: 2008-02-15 03:16:05 -0700 (Fri, 15 Feb 27 | * 2008) $ 28 | * @since 1.2 29 | */ 30 | 31 | public class NotARotationMatrixException extends MathException { 32 | 33 | /** 34 | * Simple constructor. Build an exception by translating and formating a 35 | * message 36 | * 37 | * @param specifier 38 | * format specifier (to be translated) 39 | * @param parts 40 | * to insert in the format (no translation) 41 | */ 42 | public NotARotationMatrixException(final String specifier, final Object[] parts) { 43 | super(specifier, parts); 44 | } 45 | 46 | /** Serializable version identifier */ 47 | private static final long serialVersionUID = 5647178478658937642L; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/peasy/org/apache/commons/math/geometry/CardanEulerSingularityException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package peasy.org.apache.commons.math.geometry; 19 | 20 | import peasy.org.apache.commons.math.MathException; 21 | 22 | /** 23 | * This class represents exceptions thrown while extractiong Cardan or Euler 24 | * angles from a rotation. 25 | * 26 | * @version $Revision: 620312 $ $Date: 2008-02-10 12:28:59 -0700 (Sun, 10 Feb 27 | * 2008) $ 28 | * @since 1.2 29 | */ 30 | public class CardanEulerSingularityException extends MathException { 31 | 32 | /** 33 | * Simple constructor. build an exception with a default message. 34 | * 35 | * @param isCardan 36 | * if true, the rotation is related to Cardan angles, if false it 37 | * is related to EulerAngles 38 | */ 39 | public CardanEulerSingularityException(final boolean isCardan) { 40 | super(isCardan ? "Cardan angles singularity" : "Euler angles singularity", 41 | new Object[0]); 42 | } 43 | 44 | /** Serializable version identifier */ 45 | private static final long serialVersionUID = -1360952845582206770L; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/peasy/InterpolationUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | The PeasyCam Processing library, which provides an easy-peasy 3 | camera for 3D sketching. 4 | 5 | Copyright 2008 Jonathan Feinberg 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | package peasy; 20 | 21 | import peasy.org.apache.commons.math.geometry.Rotation; 22 | import peasy.org.apache.commons.math.geometry.Vector3D; 23 | 24 | public class InterpolationUtil { 25 | 26 | // Thanks to Michael Kaufmann for improvements to this function. 27 | static public Rotation slerp(final Rotation a, final Rotation b, final double t) { 28 | final double a0 = a.getQ0(), a1 = a.getQ1(), a2 = a.getQ2(), a3 = a.getQ3(); 29 | double b0 = b.getQ0(), b1 = b.getQ1(), b2 = b.getQ2(), b3 = b.getQ3(); 30 | 31 | double cosTheta = a0 * b0 + a1 * b1 + a2 * b2 + a3 * b3; 32 | if (cosTheta < 0) { 33 | b0 = -b0; 34 | b1 = -b1; 35 | b2 = -b2; 36 | b3 = -b3; 37 | cosTheta = -cosTheta; 38 | } 39 | 40 | final double theta = Math.acos(cosTheta); 41 | final double sinTheta = Math.sqrt(1.0 - cosTheta * cosTheta); 42 | 43 | double w1, w2; 44 | if (sinTheta > 0.001) { 45 | w1 = Math.sin((1.0 - t) * theta) / sinTheta; 46 | w2 = Math.sin(t * theta) / sinTheta; 47 | } else { 48 | w1 = 1.0 - t; 49 | w2 = t; 50 | } 51 | return new Rotation(w1 * a0 + w2 * b0, w1 * a1 + w2 * b1, w1 * a2 + w2 * b2, w1 52 | * a3 + w2 * b3, true); 53 | } 54 | 55 | static public double smooth(final double a, final double b, final double t) { 56 | final double smooth = (t * t * (3 - 2 * t)); 57 | return (b * smooth) + (a * (1 - smooth)); 58 | 59 | } 60 | 61 | static public Vector3D smooth(final Vector3D a, final Vector3D b, final double t) { 62 | return new Vector3D(smooth(a.getX(), b.getX(), t), smooth(a.getY(), b.getY(), t), 63 | smooth(a.getZ(), b.getZ(), t)); 64 | } 65 | 66 | static public double linear(final double a, final double b, final double t) { 67 | return a + (b - a) * t; 68 | } 69 | 70 | static public Vector3D linear(final Vector3D a, final Vector3D b, final double t) { 71 | return new Vector3D(linear(a.getX(), b.getX(), t), linear(a.getY(), b.getY(), t), 72 | linear(a.getZ(), b.getZ(), t)); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.ui.prefs: -------------------------------------------------------------------------------- 1 | #Thu Apr 22 18:55:47 EDT 2010 2 | cleanup.add_default_serial_version_id=true 3 | cleanup.add_generated_serial_version_id=false 4 | cleanup.add_missing_annotations=false 5 | cleanup.add_missing_deprecated_annotations=true 6 | cleanup.add_missing_methods=false 7 | cleanup.add_missing_nls_tags=false 8 | cleanup.add_missing_override_annotations=true 9 | cleanup.add_serial_version_id=false 10 | cleanup.always_use_blocks=true 11 | cleanup.always_use_parentheses_in_expressions=false 12 | cleanup.always_use_this_for_non_static_field_access=false 13 | cleanup.always_use_this_for_non_static_method_access=false 14 | cleanup.convert_to_enhanced_for_loop=true 15 | cleanup.correct_indentation=true 16 | cleanup.format_source_code=true 17 | cleanup.format_source_code_changes_only=false 18 | cleanup.make_local_variable_final=true 19 | cleanup.make_parameters_final=true 20 | cleanup.make_private_fields_final=true 21 | cleanup.make_type_abstract_if_missing_method=false 22 | cleanup.make_variable_declarations_final=true 23 | cleanup.never_use_blocks=false 24 | cleanup.never_use_parentheses_in_expressions=true 25 | cleanup.organize_imports=true 26 | cleanup.qualify_static_field_accesses_with_declaring_class=false 27 | cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true 28 | cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true 29 | cleanup.qualify_static_member_accesses_with_declaring_class=true 30 | cleanup.qualify_static_method_accesses_with_declaring_class=false 31 | cleanup.remove_private_constructors=true 32 | cleanup.remove_trailing_whitespaces=true 33 | cleanup.remove_trailing_whitespaces_all=true 34 | cleanup.remove_trailing_whitespaces_ignore_empty=false 35 | cleanup.remove_unnecessary_casts=true 36 | cleanup.remove_unnecessary_nls_tags=true 37 | cleanup.remove_unused_imports=true 38 | cleanup.remove_unused_local_variables=false 39 | cleanup.remove_unused_private_fields=true 40 | cleanup.remove_unused_private_members=false 41 | cleanup.remove_unused_private_methods=true 42 | cleanup.remove_unused_private_types=true 43 | cleanup.sort_members=false 44 | cleanup.sort_members_all=false 45 | cleanup.use_blocks=true 46 | cleanup.use_blocks_only_for_return_and_throw=false 47 | cleanup.use_parentheses_in_expressions=false 48 | cleanup.use_this_for_non_static_field_access=false 49 | cleanup.use_this_for_non_static_field_access_only_if_necessary=true 50 | cleanup.use_this_for_non_static_method_access=false 51 | cleanup.use_this_for_non_static_method_access_only_if_necessary=true 52 | cleanup_profile=_jdf 53 | cleanup_settings_version=2 54 | eclipse.preferences.version=1 55 | formatter_profile=_jdf 56 | formatter_settings_version=11 57 | org.eclipse.jdt.ui.text.custom_code_templates= 58 | -------------------------------------------------------------------------------- /examples/MultiView_Offscreen/MultiView_Offscreen.pde: -------------------------------------------------------------------------------- 1 | 2 | 3 | import peasy.PeasyCam; 4 | 5 | 6 | // 7 | // 8 | // MultiView (advanced version) 9 | // 10 | // N x N Camera Views of the same scene, using N x N separate pgraphics. 11 | // 12 | // 13 | 14 | final int NX = 3; 15 | final int NY = 2; 16 | PeasyCam[] cameras = new PeasyCam[NX * NY]; 17 | 18 | public void settings() { 19 | size(1280, 720, P2D); // 2D 20 | smooth(8); 21 | } 22 | 23 | public void setup() { 24 | 25 | int gap = 5; 26 | 27 | // tiling size 28 | int tilex = floor((width - gap) / NX); 29 | int tiley = floor((height - gap) / NY); 30 | 31 | // viewport offset ... corrected gap due to floor() 32 | int offx = (width - (tilex * NX - gap)) / 2; 33 | int offy = (height - (tiley * NY - gap)) / 2; 34 | 35 | // viewport dimension 36 | int cw = tilex - gap; 37 | int ch = tiley - gap; 38 | 39 | // create new viewport for each camera 40 | for(int y = 0; y < NY; y++){ 41 | for(int x = 0; x < NX; x++){ 42 | int id = y * NX + x; 43 | int cx = offx + x * tilex; 44 | int cy = offy + y * tiley; 45 | PGraphics pg = createGraphics(cw, ch, P3D); 46 | cameras[id] = new PeasyCam(this, pg, 400); 47 | cameras[id].setViewport(cx, cy, cw, ch); // this is the key of this whole demo 48 | } 49 | } 50 | 51 | } 52 | 53 | 54 | public void draw(){ 55 | // render scene once per camera/viewport 56 | for(int i = 0; i < cameras.length; i++){ 57 | displayScene(cameras[i], i); 58 | } 59 | 60 | background(0); 61 | for(int i = 0; i < cameras.length; i++){ 62 | int[] viewport = cameras[i].getViewport(); 63 | image(cameras[i].getCanvas(), viewport[0], viewport[1], viewport[2], viewport[3]); 64 | } 65 | } 66 | 67 | 68 | public void displayScene(PeasyCam cam, int ID){ 69 | 70 | PGraphics pg = cam.getCanvas(); 71 | 72 | int[] viewport = cam.getViewport(); 73 | int w = viewport[2]; 74 | int h = viewport[3]; 75 | 76 | pg.beginDraw(); 77 | pg.resetMatrix(); 78 | 79 | // modelview - using camera state 80 | cam.feed(); 81 | 82 | // projection - using camera viewport 83 | pg.perspective(60 * PI/180, w/(float)h, 1, 5000); 84 | 85 | // clear background (scissors makes sure we only clear the region we own) 86 | pg.background(24); 87 | pg.stroke(0); 88 | pg.strokeWeight(0.3f); 89 | 90 | // scene objects 91 | pg.pushMatrix(); 92 | pg.translate(-100, 0, 0); 93 | pg.fill(0,96,255); 94 | pg.box(100); 95 | pg.popMatrix(); 96 | 97 | pg.pushMatrix(); 98 | pg.translate(100, 0, 0); 99 | pg.rotateX(PI/2); 100 | float c = 255 * ID/(float) (cameras.length-1); 101 | pg.fill(255, 255-c/2, 255-c); 102 | pg.sphere(80); 103 | pg.popMatrix(); 104 | 105 | // screen-aligned 2D HUD 106 | cam.beginHUD(); 107 | pg.rectMode(CORNER); 108 | pg.fill(0); 109 | pg.rect(0, 0, 60, 23); 110 | pg.fill(255,128,0); 111 | pg.text("cam "+ID, 10, 15); 112 | cam.endHUD(); 113 | 114 | pg.endDraw(); 115 | } 116 | -------------------------------------------------------------------------------- /web/stylesheet.css: -------------------------------------------------------------------------------- 1 | /* processingLibs style by andreas schlegel, sojamo. */ 2 | 3 | 4 | * { 5 | margin:0; 6 | padding:0; 7 | border:0; 8 | } 9 | 10 | 11 | body { 12 | font-family : Verdana, Geneva, Arial, Helvetica, sans-serif; 13 | font-size : 100%; 14 | font-weight : normal; 15 | line-height : normal; 16 | } 17 | 18 | #container { 19 | margin-left:64px; 20 | background-color:#fff; 21 | } 22 | 23 | #header { 24 | float:left; 25 | padding-top:24px; 26 | padding-bottom:48px; 27 | } 28 | 29 | #menu { 30 | margin-top:16px; 31 | float:left; 32 | margin-bottom:64px; 33 | } 34 | 35 | 36 | #about, 37 | #download, 38 | #examples, 39 | #misc { 40 | width:480px; 41 | float:left; 42 | margin-right:24px; 43 | } 44 | 45 | #resources, #info { 46 | width:320px; 47 | float:left; 48 | } 49 | 50 | 51 | .clear { 52 | clear:both; 53 | } 54 | 55 | #footer { 56 | margin-top:300px; 57 | height:20px; 58 | margin-bottom:32px; 59 | } 60 | 61 | 62 | ul { 63 | list-style:disc; 64 | padding:0; 65 | margin: 0 0 1em 1em; 66 | } 67 | 68 | #menu ul { 69 | list-style:none; 70 | margin: 0; 71 | } 72 | #menu ul li, #subMenu ul li { 73 | float:left; 74 | padding-right:6px; 75 | } 76 | 77 | 78 | 79 | 80 | 81 | 82 | /* Headings */ 83 | 84 | h1 { 85 | font-size:2em; 86 | font-weight:normal; 87 | } 88 | 89 | 90 | h2, h3, h4, h5, th { 91 | font-size:1.3em; 92 | font-weight:normal; 93 | margin-bottom:4px; 94 | } 95 | 96 | 97 | 98 | p { 99 | font-size:1em; 100 | width:90%; 101 | margin-bottom:1em; 102 | } 103 | 104 | 105 | pre, code { 106 | font-family:"Consolas", "Courier New", Courier, monospace; 107 | font-size:1em; 108 | line-height:normal; 109 | } 110 | 111 | pre { margin-bottom: 1em } 112 | 113 | hr { 114 | border:0; 115 | height:1px; 116 | margin-bottom:24px; 117 | } 118 | 119 | 120 | a { 121 | text-decoration: underline; 122 | font-weight: normal; 123 | } 124 | 125 | 126 | a:hover, 127 | a:active { 128 | text-decoration: underline; 129 | font-weight: normal; 130 | } 131 | 132 | 133 | a:visited, 134 | a:link:visited { 135 | text-decoration: underline; 136 | font-weight: normal; 137 | } 138 | 139 | 140 | 141 | img { 142 | border: 0px solid #000000; 143 | } 144 | 145 | 146 | 147 | 148 | 149 | /* COLORS */ 150 | 151 | 152 | body { 153 | color : #333; 154 | background-color :#fff; 155 | } 156 | 157 | 158 | #header { 159 | background-color:#fff; 160 | color:#333; 161 | } 162 | 163 | 164 | 165 | h1, h2, h3, h4, h5, h6 { 166 | color:#666; 167 | } 168 | 169 | 170 | pre, code { 171 | color: #000000; 172 | } 173 | 174 | 175 | a,strong { 176 | color: #333; 177 | } 178 | 179 | 180 | a:hover, 181 | a:active { 182 | color: #333; 183 | } 184 | 185 | 186 | a:visited, 187 | a:link:visited { 188 | color: #333; 189 | } 190 | 191 | 192 | #footer, #menu { 193 | background-color:#fff; 194 | color:#333; 195 | } 196 | 197 | 198 | #footer a, #menu a { 199 | color:#333; 200 | } 201 | 202 | td { vertical-align: top; padding-right: 1em } -------------------------------------------------------------------------------- /test/examples/MultiView_Offscreen/MultiView_Offscreen.java: -------------------------------------------------------------------------------- 1 | package examples.MultiView_Offscreen; 2 | 3 | import peasy.PeasyCam; 4 | import processing.core.PApplet; 5 | import processing.core.PGraphics; 6 | 7 | public class MultiView_Offscreen extends PApplet { 8 | 9 | // 10 | // 11 | // MultiView (advanced version) 12 | // 13 | // N x N Camera Views of the same scene, using N x N separate pgraphics. 14 | // 15 | // 16 | 17 | final int NX = 3; 18 | final int NY = 2; 19 | PeasyCam[] cameras = new PeasyCam[NX * NY]; 20 | 21 | public void settings() { 22 | size(1280, 720, P2D); // 2D 23 | smooth(8); 24 | } 25 | 26 | public void setup() { 27 | 28 | int gap = 5; 29 | 30 | // tiling size 31 | int tilex = floor((width - gap) / NX); 32 | int tiley = floor((height - gap) / NY); 33 | 34 | // viewport offset ... corrected gap due to floor() 35 | int offx = (width - (tilex * NX - gap)) / 2; 36 | int offy = (height - (tiley * NY - gap)) / 2; 37 | 38 | // viewport dimension 39 | int cw = tilex - gap; 40 | int ch = tiley - gap; 41 | 42 | // create new viewport for each camera 43 | for (int y = 0; y < NY; y++) { 44 | for (int x = 0; x < NX; x++) { 45 | int id = y * NX + x; 46 | int cx = offx + x * tilex; 47 | int cy = offy + y * tiley; 48 | PGraphics pg = createGraphics(cw, ch, P3D); 49 | cameras[id] = new PeasyCam(this, pg, 400); 50 | cameras[id].setViewport(cx, cy, cw, ch); // this is the key of this whole demo 51 | } 52 | } 53 | 54 | } 55 | 56 | public void draw() { 57 | // render scene once per camera/viewport 58 | for (int i = 0; i < cameras.length; i++) { 59 | displayScene(cameras[i], i); 60 | } 61 | 62 | background(0); 63 | for (int i = 0; i < cameras.length; i++) { 64 | int[] viewport = cameras[i].getViewport(); 65 | image(cameras[i].getCanvas(), viewport[0], viewport[1], viewport[2], 66 | viewport[3]); 67 | } 68 | } 69 | 70 | public void displayScene(PeasyCam cam, int ID) { 71 | 72 | PGraphics pg = cam.getCanvas(); 73 | 74 | int[] viewport = cam.getViewport(); 75 | int w = viewport[2]; 76 | int h = viewport[3]; 77 | 78 | pg.beginDraw(); 79 | pg.resetMatrix(); 80 | 81 | // modelview - using camera state 82 | cam.feed(); 83 | 84 | // projection - using camera viewport 85 | pg.perspective(60 * PI / 180, w / (float)h, 1, 5000); 86 | 87 | // clear background (scissors makes sure we only clear the region we own) 88 | pg.background(24); 89 | pg.stroke(0); 90 | pg.strokeWeight(0.3f); 91 | 92 | // scene objects 93 | pg.pushMatrix(); 94 | pg.translate(-100, 0, 0); 95 | pg.fill(0, 96, 255); 96 | pg.box(100); 97 | pg.popMatrix(); 98 | 99 | pg.pushMatrix(); 100 | pg.translate(100, 0, 0); 101 | pg.rotateX(PI / 2); 102 | float c = 255 * ID / (float)(cameras.length - 1); 103 | pg.fill(255, 255 - c / 2, 255 - c); 104 | pg.sphere(80); 105 | pg.popMatrix(); 106 | 107 | // screen-aligned 2D HUD 108 | cam.beginHUD(); 109 | pg.rectMode(CORNER); 110 | pg.fill(0); 111 | pg.rect(0, 0, 60, 23); 112 | pg.fill(255, 128, 0); 113 | pg.text("cam " + ID, 10, 15); 114 | cam.endHUD(); 115 | 116 | pg.endDraw(); 117 | } 118 | 119 | public static void main(String args[]) { 120 | PApplet.main(new String[] { MultiView_Offscreen.class.getName() }); 121 | } 122 | 123 | } -------------------------------------------------------------------------------- /test/examples/Resizeable_Offscreen/Resizeable_Offscreen.java: -------------------------------------------------------------------------------- 1 | package examples.Resizeable_Offscreen; 2 | 3 | import peasy.PeasyCam; 4 | import processing.core.PApplet; 5 | import processing.core.PShape; 6 | import processing.opengl.PGraphics3D; 7 | 8 | public class Resizeable_Offscreen extends PApplet { 9 | 10 | // 11 | // Resizeable Window example, using an offscreen rendertarget. 12 | // 13 | 14 | PeasyCam cam; 15 | 16 | // offscreen render target 17 | PGraphics3D pg; 18 | 19 | int window_w = 0; 20 | int window_h = 0; 21 | 22 | public void settings() { 23 | size(800, 600, P2D); 24 | smooth(8); 25 | } 26 | 27 | public void setup() { 28 | surface.setResizable(true); 29 | 30 | int w = 2 * width / 3 - 10; 31 | int h = height - 20; 32 | pg = (PGraphics3D)createGraphics(w, h, P3D); 33 | 34 | cam = new PeasyCam(this, pg, 400); 35 | } 36 | 37 | public void handleResize() { 38 | 39 | int w = 2 * width / 3 - 10; 40 | int h = height - 20; 41 | 42 | // check if window got resized 43 | if (window_w != width || window_h != height) { 44 | 45 | // Unfortunately processing has no easy, official way to resize a PGraphics. 46 | // The following is a workaround to resize a PGraphics while still keeping 47 | // the reference. 48 | int smooth = pg.smooth; 49 | pg.dispose(); 50 | pg.removeCache(pg); 51 | pg.setPrimary(false); 52 | pg.setParent(this); 53 | pg.setSize(w, h); 54 | pg.initialized = false; 55 | pg.smooth = smooth; 56 | 57 | // Alternatively we could create a new PGraphics instead and pass it to 58 | // the camera,... but PeasyCam.g is final atm. 59 | // TODO: discuss final PeasyCam.g 60 | 61 | // pg.dispose(); 62 | // pg = (PGraphics3D) createGraphics(w, h, P3D); 63 | // cam.setCanvas(pg); 64 | 65 | } 66 | 67 | // update new window dimension 68 | window_w = width; 69 | window_h = height; 70 | 71 | // update camera viewport 72 | cam.setViewport(10, 10, w, h); 73 | // apply camera feed 74 | cam.feed(); 75 | } 76 | 77 | public void draw() { 78 | 79 | handleResize(); 80 | 81 | // render offscreen 82 | pg.beginDraw(); 83 | { 84 | pg.perspective(60 * DEG_TO_RAD, pg.width / (float)pg.height, 1, 20000); 85 | pg.rotateX(-.5f); 86 | pg.rotateY(-.5f); 87 | pg.lights(); 88 | pg.scale(10); 89 | pg.strokeWeight(1 / 10f); 90 | pg.background(16); 91 | pg.fill(255, 128, 0); 92 | pg.box(30); 93 | pg.pushMatrix(); 94 | pg.translate(0, 0, 20); 95 | pg.fill(0, 96, 255); 96 | pg.box(5); 97 | pg.popMatrix(); 98 | 99 | cam.beginHUD(); 100 | { 101 | pg.fill(0, 128); 102 | pg.rect(0, 0, 150, 30); 103 | pg.fill(255); 104 | pg.text("Distance: " + nf((float)cam.getDistance(), 1, 2), 10, 18); 105 | } 106 | cam.endHUD(); 107 | } 108 | pg.endDraw(); 109 | 110 | 111 | // render onscreen (the primary graphics is 2D) 112 | background(48); 113 | 114 | // offscreen result 115 | int[] vp = cam.getViewport(); 116 | image(pg, vp[0], vp[1], vp[2], vp[3]); 117 | 118 | // text 119 | fill(255); 120 | int tx = vp[0] + vp[2] + 15 ; 121 | int ty = 30; 122 | text("FrameRate: " + nfc(frameRate, 2), tx, ty); 123 | } 124 | 125 | 126 | 127 | public static void main(String args[]) { 128 | PApplet.main(new String[] { Resizeable_Offscreen.class.getName() }); 129 | } 130 | 131 | } -------------------------------------------------------------------------------- /examples/MultiView_Onscreen/MultiView_Onscreen.pde: -------------------------------------------------------------------------------- 1 | 2 | 3 | import peasy.PeasyCam; 4 | 5 | import processing.opengl.PGL; 6 | import processing.opengl.PGraphics3D; 7 | import processing.opengl.PJOGL; 8 | 9 | 10 | // 11 | // 12 | // MultiView (advanced version) 13 | // 14 | // N x N Camera Views of the same scene, on only one PGraphics. 15 | // 16 | // In this demo only one render-target is used -> the primary PGraphics3D ... this.g 17 | // Each Camera still has its own mouse-handler. 18 | // Only the viewport-position/dimension is used to build the camera state. 19 | // 20 | // For rendering, some OpenGL instructions (viewport, scissors) are used to 21 | // render the scene to its actual camera viewport position/size. 22 | // 23 | // 24 | 25 | final int NX = 3; 26 | final int NY = 2; 27 | PeasyCam[] cameras = new PeasyCam[NX * NY]; 28 | 29 | public void settings() { 30 | size(1280, 720, P3D); // 3D 31 | smooth(8); 32 | } 33 | 34 | public void setup() { 35 | 36 | int gap = 5; 37 | 38 | // tiling size 39 | int tilex = floor((width - gap) / NX); 40 | int tiley = floor((height - gap) / NY); 41 | 42 | // viewport offset ... corrected gap due to floor() 43 | int offx = (width - (tilex * NX - gap)) / 2; 44 | int offy = (height - (tiley * NY - gap)) / 2; 45 | 46 | // viewport dimension 47 | int cw = tilex - gap; 48 | int ch = tiley - gap; 49 | 50 | // create new viewport for each camera 51 | for(int y = 0; y < NY; y++){ 52 | for(int x = 0; x < NX; x++){ 53 | int id = y * NX + x; 54 | int cx = offx + x * tilex; 55 | int cy = offy + y * tiley; 56 | cameras[id] = new PeasyCam(this, 400); 57 | cameras[id].setViewport(cx, cy, cw, ch); // this is the key of this whole demo 58 | } 59 | } 60 | 61 | } 62 | 63 | 64 | public void draw(){ 65 | // clear background once, for the whole window 66 | setGLGraphicsViewport(0, 0, width, height); 67 | background(0); 68 | 69 | // render scene once per camera/viewport 70 | for(int i = 0; i < cameras.length; i++){ 71 | pushStyle(); 72 | pushMatrix(); 73 | displayScene(cameras[i], i); 74 | popMatrix(); 75 | popStyle(); 76 | } 77 | // setGLGraphicsViewport(0, 0, width, height); 78 | } 79 | 80 | 81 | // some OpenGL instructions to set our custom viewport 82 | // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glViewport.xhtml 83 | // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glScissor.xhtml 84 | void setGLGraphicsViewport(int x, int y, int w, int h){ 85 | PGraphics3D pg = (PGraphics3D) this.g; 86 | PJOGL pgl = (PJOGL) pg.beginPGL(); pg.endPGL(); 87 | 88 | pgl.enable(PGL.SCISSOR_TEST); 89 | pgl.scissor (x,y,w,h); 90 | pgl.viewport(x,y,w,h); 91 | } 92 | 93 | 94 | public void displayScene(PeasyCam cam, int ID){ 95 | 96 | int[] viewport = cam.getViewport(); 97 | int w = viewport[2]; 98 | int h = viewport[3]; 99 | int x = viewport[0]; 100 | int y = viewport[1]; 101 | int y_inv = height - y - h; // inverted y-axis 102 | 103 | // scissors-test and viewport transformation 104 | setGLGraphicsViewport(x, y_inv, w, h); 105 | 106 | // modelview - using camera state 107 | cam.feed(); 108 | 109 | // projection - using camera viewport 110 | perspective(60 * PI/180, w/(float)h, 1, 5000); 111 | 112 | // clear background (scissors makes sure we only clear the region we own) 113 | background(24); 114 | stroke(0); 115 | strokeWeight(1); 116 | 117 | // scene objects 118 | pushMatrix(); 119 | translate(-100, 0, 0); 120 | fill(0,96,255); 121 | box(100); 122 | popMatrix(); 123 | 124 | pushMatrix(); 125 | translate(100, 0, 0); 126 | rotateX(PI/2); 127 | float c = 255 * ID/(float) (cameras.length-1); 128 | fill(255-c/2, 255, 255-c); 129 | sphere(80); 130 | popMatrix(); 131 | 132 | // screen-aligned 2D HUD 133 | cam.beginHUD(); 134 | rectMode(CORNER); 135 | fill(0); 136 | rect(0, 0, 60, 23); 137 | fill(255,128,0); 138 | text("cam "+ID, 10, 15); 139 | cam.endHUD(); 140 | } 141 | -------------------------------------------------------------------------------- /test/examples/MultiView_Onscreen/MultiView_Onscreen.java: -------------------------------------------------------------------------------- 1 | package examples.MultiView_Onscreen; 2 | 3 | import peasy.PeasyCam; 4 | import processing.core.PApplet; 5 | import processing.opengl.PGL; 6 | import processing.opengl.PGraphics3D; 7 | import processing.opengl.PJOGL; 8 | 9 | public class MultiView_Onscreen extends PApplet { 10 | 11 | // 12 | // 13 | // MultiView (advanced version) 14 | // 15 | // N x N Camera Views of the same scene, on only one PGraphics. 16 | // 17 | // In this demo only one render-target is used -> the primary PGraphics3D ... this.g 18 | // Each Camera still has its own mouse-handler. 19 | // Only the viewport-position/dimension is used to build the camera state. 20 | // 21 | // For rendering, some OpenGL instructions (viewport, scissors) are used to 22 | // render the scene to its actual camera viewport position/size. 23 | // 24 | // 25 | 26 | final int NX = 3; 27 | final int NY = 2; 28 | PeasyCam[] cameras = new PeasyCam[NX * NY]; 29 | 30 | public void settings() { 31 | size(1280, 720, P3D); // 3D 32 | smooth(8); 33 | } 34 | 35 | public void setup() { 36 | 37 | int gap = 5; 38 | 39 | // tiling size 40 | int tilex = floor((width - gap) / NX); 41 | int tiley = floor((height - gap) / NY); 42 | 43 | // viewport offset ... corrected gap due to floor() 44 | int offx = (width - (tilex * NX - gap)) / 2; 45 | int offy = (height - (tiley * NY - gap)) / 2; 46 | 47 | // viewport dimension 48 | int cw = tilex - gap; 49 | int ch = tiley - gap; 50 | 51 | // create new viewport for each camera 52 | for (int y = 0; y < NY; y++) { 53 | for (int x = 0; x < NX; x++) { 54 | int id = y * NX + x; 55 | int cx = offx + x * tilex; 56 | int cy = offy + y * tiley; 57 | cameras[id] = new PeasyCam(this, 400); 58 | cameras[id].setViewport(cx, cy, cw, ch); // this is the key of this whole demo 59 | } 60 | } 61 | 62 | } 63 | 64 | public void draw() { 65 | // clear background once, for the whole window 66 | setGLGraphicsViewport(0, 0, width, height); 67 | background(0); 68 | 69 | // render scene once per camera/viewport 70 | for (int i = 0; i < cameras.length; i++) { 71 | pushStyle(); 72 | pushMatrix(); 73 | displayScene(cameras[i], i); 74 | popMatrix(); 75 | popStyle(); 76 | } 77 | // setGLGraphicsViewport(0, 0, width, height); 78 | } 79 | 80 | // some OpenGL instructions to set our custom viewport 81 | // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glViewport.xhtml 82 | // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glScissor.xhtml 83 | void setGLGraphicsViewport(int x, int y, int w, int h) { 84 | PGraphics3D pg = (PGraphics3D)this.g; 85 | PJOGL pgl = (PJOGL)pg.beginPGL(); 86 | pg.endPGL(); 87 | 88 | pgl.enable(PGL.SCISSOR_TEST); 89 | pgl.scissor(x, y, w, h); 90 | pgl.viewport(x, y, w, h); 91 | } 92 | 93 | public void displayScene(PeasyCam cam, int ID) { 94 | 95 | int[] viewport = cam.getViewport(); 96 | int w = viewport[2]; 97 | int h = viewport[3]; 98 | int x = viewport[0]; 99 | int y = viewport[1]; 100 | int y_inv = height - y - h; // inverted y-axis 101 | 102 | // scissors-test and viewport transformation 103 | setGLGraphicsViewport(x, y_inv, w, h); 104 | 105 | // modelview - using camera state 106 | cam.feed(); 107 | 108 | // projection - using camera viewport 109 | perspective(60 * PI / 180, w / (float)h, 1, 5000); 110 | 111 | // clear background (scissors makes sure we only clear the region we own) 112 | background(24); 113 | stroke(0); 114 | strokeWeight(1); 115 | 116 | // scene objects 117 | pushMatrix(); 118 | translate(-100, 0, 0); 119 | fill(0, 96, 255); 120 | box(100); 121 | popMatrix(); 122 | 123 | pushMatrix(); 124 | translate(100, 0, 0); 125 | rotateX(PI / 2); 126 | float c = 255 * ID / (float)(cameras.length - 1); 127 | fill(255 - c / 2, 255, 255 - c); 128 | sphere(80); 129 | popMatrix(); 130 | 131 | // screen-aligned 2D HUD 132 | cam.beginHUD(); 133 | rectMode(CORNER); 134 | fill(0); 135 | rect(0, 0, 60, 23); 136 | fill(255, 128, 0); 137 | text("cam " + ID, 10, 15); 138 | cam.endHUD(); 139 | } 140 | 141 | public static void main(String args[]) { 142 | PApplet.main(new String[] { MultiView_Onscreen.class.getName() }); 143 | } 144 | 145 | } -------------------------------------------------------------------------------- /commons-math-1.2/NOTICE.txt: -------------------------------------------------------------------------------- 1 | Apache Commons Math 2 | Copyright 2001-2008 The Apache Software Foundation 3 | 4 | This product includes software developed by 5 | The Apache Software Foundation (http://www.apache.org/). 6 | 7 | 8 | This product includes software translated from the lmder, lmpar 9 | and qrsolv Fortran routines from the Minpack package and 10 | distributed under the following disclaimer: 11 | 12 | ---------- http://www.netlib.org/minpack/disclaimer ---------- 13 | Minpack Copyright Notice (1999) University of Chicago. All rights reserved 14 | 15 | Redistribution and use in source and binary forms, with or 16 | without modification, are permitted provided that the 17 | following conditions are met: 18 | 19 | 1. Redistributions of source code must retain the above 20 | copyright notice, this list of conditions and the following 21 | disclaimer. 22 | 23 | 2. Redistributions in binary form must reproduce the above 24 | copyright notice, this list of conditions and the following 25 | disclaimer in the documentation and/or other materials 26 | provided with the distribution. 27 | 28 | 3. The end-user documentation included with the 29 | redistribution, if any, must include the following 30 | acknowledgment: 31 | 32 | "This product includes software developed by the 33 | University of Chicago, as Operator of Argonne National 34 | Laboratory. 35 | 36 | Alternately, this acknowledgment may appear in the software 37 | itself, if and wherever such third-party acknowledgments 38 | normally appear. 39 | 40 | 4. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" 41 | WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE 42 | UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND 43 | THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR 44 | IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES 45 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE 46 | OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY 47 | OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR 48 | USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF 49 | THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) 50 | DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION 51 | UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL 52 | BE CORRECTED. 53 | 54 | 5. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT 55 | HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF 56 | ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, 57 | INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF 58 | ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF 59 | PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER 60 | SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT 61 | (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, 62 | EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE 63 | POSSIBILITY OF SUCH LOSS OR DAMAGES. 64 | ---------- http://www.netlib.org/minpack/disclaimer ---------- 65 | 66 | 67 | 68 | This product includes software translated from the odex Fortran routine 69 | developed by E. Hairer and G. Wanner and distributed under the following 70 | license: 71 | 72 | ---------- http://www.unige.ch/~hairer/prog/licence.txt ---------- 73 | Copyright (c) 2004, Ernst Hairer 74 | 75 | Redistribution and use in source and binary forms, with or without 76 | modification, are permitted provided that the following conditions are 77 | met: 78 | 79 | - Redistributions of source code must retain the above copyright 80 | notice, this list of conditions and the following disclaimer. 81 | 82 | - Redistributions in binary form must reproduce the above copyright 83 | notice, this list of conditions and the following disclaimer in the 84 | documentation and/or other materials provided with the distribution. 85 | 86 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 87 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 88 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 89 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 90 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 91 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 92 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 93 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 94 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 95 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 96 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 97 | ---------- http://www.unige.ch/~hairer/prog/licence.txt ---------- 98 | -------------------------------------------------------------------------------- /README.textile: -------------------------------------------------------------------------------- 1 | PeasyCam provides a dead-simple mouse-driven camera for Processing. It is created and maintained by "Jonathan Feinberg":http://mrfeinberg.com/. It is free for all uses, per the Apache 2.0 license. 2 | 3 | h3. Download 4 | 5 | h4. Processing 1.5.1 6 | 7 | You can download a version of Peasycam compatible with Processing 1.5.1 here: 8 | "http://static.mrfeinberg.com/peasycam/peasycam_15100.zip":http://static.mrfeinberg.com/peasycam/peasycam_15100.zip 9 | 10 | h4. Processing 2 and Later 11 | 12 | You can install the latest Peasycam from within Processing via the menus Sketch > Import Library... > Add Library... 13 | 14 | h3. Example 15 | 16 |
PeasyCam camera;
17 | 
18 | void setup() {
19 |     // PeasyCam constructor:
20 |     // PeasyCam(PApplet parent,
21 |     //          double lookAtX, double lookAtY, double lookAtZ, 
22 |     //          double distance);
23 |     camera = new PeasyCam(this, 0, 0, 0, 50);
24 | }
25 | 26 | That's it. Now a mouse left-drag will rotate the camera around the subject, a right drag will zoom in and out, and a middle-drag will pan. A double-click restores the camera to its original position. 27 | 28 | The PeasyCam is positioned on a sphere whose radius is the given distance from the look-at point. Rotations are around axes that pass through the looked-at point. 29 | 30 | h3. Constructors 31 | 32 |
PeasyCam(PApplet parent, double lookAtX, double lookAtY, double lookAtZ, double distance);
33 | PeasyCam(PApplet parent, double distance); // look at 0,0,0
34 | 35 | h3. Methods 36 | 37 |
camera.setActive(boolean active);  // false to make this camera stop responding to mouse
38 | 
39 | // By default, the camera is in "free rotation" mode, but you can
40 | // constrain it to any axis, around the look-at point:
41 | camera.setYawRotationMode();   // like spinning a globe
42 | camera.setPitchRotationMode(); // like a somersault
43 | camera.setRollRotationMode();  // like a radio knob
44 | camera.setSuppressRollRotationMode();  // Permit pitch/yaw only.
45 | 
46 | // Then you can set it back to its default mode:
47 | camera.setFreeRotationMode();
48 | 
49 | // reassign particular drag gestures, or set them to null
50 | camera.setLeftDragHandler(PeasyDragHandler handler);
51 | camera.setCenterDragHandler(PeasyDragHandler handler);
52 | camera.setRightDragHandler(PeasyDragHandler handler);
53 | PeasyDragHandler getPanDragHandler();
54 | PeasyDragHandler getRotateDragHandler();
55 | PeasyDragHandler getZoomDragHandler();
56 | 
57 | // mouse wheel zooms by default; set null, or make your own
58 | camera.setWheelHandler(PeasyWheelHandler handler);
59 | PeasyWheelHandler getZoomWheelHandler();
60 | 
61 | // change sensitivity of built-in mouse wheel zoom
62 | camera.setWheelScale(double scale); // 1.0 by default
63 | double getWheelScale();
64 | 
65 | // make your own!
66 | public interface PeasyDragHandler {
67 | 	public void handleDrag(final double dx, final double dy);
68 | }
69 | public interface PeasyWheelHandler {
70 | 	public void handleWheel(final int delta);
71 | }
72 | 
73 | camera.lookAt(double x, double y, double z);
74 | camera.rotateX(double angle);  // rotate around the x-axis passing through the subject
75 | camera.rotateY(double angle);  // rotate around the y-axis passing through the subject
76 | camera.rotateZ(double angle);  // rotate around the z-axis passing through the subject
77 | camera.setDistance(double d);  // distance from looked-at point
78 | camera.pan(double dx, double dy);     // move the looked-at point relative to current orientation
79 | 
80 | camera.reset();
81 | camera.reset(long animationTimeInMillis);  // reset camera to its starting settings
82 | 
83 | CameraState state = camera.getState(); // get a serializable settings object for current state
84 | camera.setState(CameraState state);
85 | camera.setState(CameraState state, long animationTimeInMillis); // set the camera to the given saved state
86 | 
87 | // Utility methods to permit the use of a Heads-Up Display
88 | // Thanks, A.W. Martin
89 | camera.beginHUD();
90 | // now draw things that you want relative to the camera's position and orientation
91 | camera.endHUD(); // always!
92 | 93 | PeasyCam is impervious to gimbal lock, and has no known "singularities" or discontinuities in its behavior. It relies on the excellent "Apache Commons Math":http://commons.apache.org/math/ "geometry package":http://commons.apache.org/math/userguide/geometry.html for its rotations. 94 | 95 | h3. Contributors 96 | 97 | Thanks: "Gennaro Senatore":http://wiki.uelceca.net/msc0809/published/gennaro+senatore, "Michael Kaufmann":http://www.michael-kaufmann.ch/, "Oori Shalev":http://ooish.com/, Jeffrey Gentes, "A.W. Martin":http://imaginationfeed.com, "Yiannis Chatzikonstantinou":http://prototy.blogspot.com/, and "Donald Ephraim Curtis":http://milkbox.net/ for bug reports and feature suggestions. 98 | -------------------------------------------------------------------------------- /resources/stylesheet.css: -------------------------------------------------------------------------------- 1 | /* Javadoc style sheet */ 2 | /* Define colors, fonts and other style attributes here to override the defaults */ 3 | /* processingLibs style by andreas schlegel, sojamo */ 4 | 5 | 6 | body { 7 | margin : 0; 8 | padding : 0; 9 | padding-left : 10px; 10 | padding-right : 8px; 11 | background-color : #FFFFFF; 12 | font-family : Verdana, Geneva, Arial, Helvetica, sans-serif; 13 | font-size : 100%; 14 | font-size : 0.7em; 15 | font-weight : normal; 16 | line-height : normal; 17 | margin-bottom:30px; 18 | } 19 | 20 | 21 | 22 | 23 | /* Headings */ 24 | h1, h2, h3, h4, h5, th { 25 | font-family :Arial, Helvetica, sans-serif; 26 | font-size:1.2em; 27 | } 28 | 29 | 30 | p { 31 | font-size : 1em; 32 | width:80%; 33 | } 34 | 35 | pre, code { 36 | font-family : "Courier New", Courier, monospace; 37 | font-size : 12px; 38 | line-height : normal; 39 | } 40 | 41 | 42 | 43 | table { 44 | border:0; 45 | margin-bottom:10px; 46 | margin-top:10px; 47 | } 48 | 49 | 50 | tr, td { 51 | border-top: 0px solid; 52 | border-left: 0px solid; 53 | padding-top:8px; 54 | padding-bottom:8px; 55 | } 56 | 57 | 58 | 59 | hr { 60 | border:0; 61 | height:1px; 62 | padding:0; 63 | margin:0; 64 | margin-bottom:4px; 65 | 66 | } 67 | 68 | 69 | 70 | dd, th, td, font { 71 | font-size:1.0em; 72 | line-height:1.0em; 73 | } 74 | 75 | 76 | 77 | dt { 78 | margin-bottom:0px; 79 | } 80 | 81 | 82 | 83 | dd { 84 | margin-top:2px; 85 | margin-bottom:4px; 86 | } 87 | 88 | 89 | 90 | a { 91 | text-decoration: underline; 92 | font-weight: normal; 93 | } 94 | 95 | a:hover, 96 | a:active { 97 | text-decoration: underline; 98 | font-weight: normal; 99 | } 100 | 101 | a:visited, 102 | a:link:visited { 103 | text-decoration: underline; 104 | font-weight: normal; 105 | } 106 | 107 | 108 | img { 109 | border: 0px solid #000000; 110 | } 111 | 112 | 113 | 114 | /* Navigation bar fonts */ 115 | .NavBarCell1 { 116 | border:0; 117 | } 118 | 119 | .NavBarCell1Rev { 120 | border:0; 121 | } 122 | 123 | .NavBarFont1 { 124 | font-family: Arial, Helvetica, sans-serif; 125 | font-size:1.1em; 126 | } 127 | 128 | 129 | .NavBarFont1 b { 130 | font-weight:normal; 131 | } 132 | 133 | 134 | 135 | .NavBarFont1:after, .NavBarFont1Rev:after { 136 | font-weight:normal; 137 | content: " \\"; 138 | } 139 | 140 | 141 | .NavBarFont1Rev { 142 | font-family: Arial, Helvetica, sans-serif; 143 | font-size:1.1em; 144 | } 145 | 146 | .NavBarFont1Rev b { 147 | font-family: Arial, Helvetica, sans-serif; 148 | font-size:1.1em; 149 | font-weight:normal; 150 | } 151 | 152 | .NavBarCell2 { 153 | font-family: Arial, Helvetica, sans-serif; 154 | } 155 | 156 | .NavBarCell3 { 157 | font-family: Arial, Helvetica, sans-serif; 158 | } 159 | 160 | 161 | 162 | font.FrameItemFont { 163 | font-family: Helvetica, Arial, sans-serif; 164 | font-size:1.1em; 165 | line-height:1.1em; 166 | } 167 | 168 | font.FrameHeadingFont { 169 | font-family: Helvetica, Arial, sans-serif; 170 | line-height:32px; 171 | } 172 | 173 | /* Font used in left-hand frame lists */ 174 | .FrameTitleFont { 175 | font-family: Helvetica, Arial, sans-serif 176 | } 177 | 178 | 179 | .toggleList { 180 | padding:0; 181 | margin:0; 182 | margin-top:12px; 183 | } 184 | 185 | .toggleList dt { 186 | font-weight:bold; 187 | font-size:12px; 188 | font-family:arial,sans-serif; 189 | padding:0px; 190 | margin:10px 0px 10px 0px; 191 | } 192 | 193 | .toggleList dt span { 194 | font-family: monospace; 195 | padding:0; 196 | margin:0; 197 | } 198 | 199 | 200 | .toggleList dd { 201 | margin:0; 202 | padding:0; 203 | } 204 | 205 | html.isjs .toggleList dd { 206 | display: none; 207 | } 208 | 209 | .toggleList pre { 210 | padding: 4px 4px 4px 4px; 211 | } 212 | 213 | 214 | 215 | 216 | 217 | /* COLORS */ 218 | 219 | pre, code { 220 | color: #000000; 221 | } 222 | 223 | 224 | body { 225 | color : #333333; 226 | background-color :#FFFFFF; 227 | } 228 | 229 | 230 | h1, h2, h3, h4, h5, h6 { 231 | color:#555; 232 | } 233 | 234 | a, 235 | .toggleList dt { 236 | color: #1a7eb0; 237 | } 238 | 239 | a:hover, 240 | a:active { 241 | color: #1a7eb0; 242 | } 243 | 244 | a:visited, 245 | a:link:visited { 246 | color: #1a7eb0; 247 | } 248 | 249 | td,tr { 250 | border-color: #999999; 251 | } 252 | 253 | hr { 254 | color:#999999; 255 | background:#999999; 256 | } 257 | 258 | 259 | .TableHeadingColor { 260 | background: #dcdcdc; 261 | color: #555; 262 | } 263 | 264 | 265 | .TableSubHeadingColor { 266 | background: #EEEEFF 267 | } 268 | 269 | .TableRowColor { 270 | background: #FFFFFF 271 | } 272 | 273 | 274 | .NavBarCell1 { 275 | background-color:#dcdcdc; 276 | color:#000; 277 | } 278 | 279 | .NavBarCell1 a { 280 | color:#333; 281 | } 282 | 283 | 284 | .NavBarCell1Rev { 285 | background-color:transparent; 286 | } 287 | 288 | .NavBarFont1 { 289 | color:#333; 290 | } 291 | 292 | 293 | .NavBarFont1Rev { 294 | color:#fff; 295 | } 296 | 297 | .NavBarCell2 { 298 | background-color:#999; 299 | } 300 | 301 | .NavBarCell2 a { 302 | color:#fff; 303 | } 304 | 305 | 306 | 307 | .NavBarCell3 { 308 | background-color:#dcdcdc; 309 | } 310 | 311 | -------------------------------------------------------------------------------- /src/peasy/org/apache/commons/math/geometry/RotationOrder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package peasy.org.apache.commons.math.geometry; 19 | 20 | /** 21 | * This class is a utility representing a rotation order specification for 22 | * Cardan or Euler angles specification. 23 | * 24 | * This class cannot be instanciated by the user. He can only use one of the 25 | * twelve predefined supported orders as an argument to either the 26 | * {@link Rotation#Rotation(RotationOrder,double,double,double)} constructor or 27 | * the {@link Rotation#getAngles} method. 28 | * 29 | * @version $Revision: 620312 $ $Date: 2008-02-10 12:28:59 -0700 (Sun, 10 Feb 30 | * 2008) $ 31 | * @since 1.2 32 | */ 33 | public final class RotationOrder { 34 | 35 | /** 36 | * Private constructor. This is a utility class that cannot be instantiated 37 | * by the user, so its only constructor is private. 38 | * 39 | * @param name 40 | * name of the rotation order 41 | * @param a1 42 | * axis of the first rotation 43 | * @param a2 44 | * axis of the second rotation 45 | * @param a3 46 | * axis of the third rotation 47 | */ 48 | private RotationOrder(final String name, final Vector3D a1, final Vector3D a2, 49 | final Vector3D a3) { 50 | this.name = name; 51 | this.a1 = a1; 52 | this.a2 = a2; 53 | this.a3 = a3; 54 | } 55 | 56 | /** 57 | * Get a string representation of the instance. 58 | * 59 | * @return a string representation of the instance (in fact, its name) 60 | */ 61 | public String toString() { 62 | return name; 63 | } 64 | 65 | /** 66 | * Get the axis of the first rotation. 67 | * 68 | * @return axis of the first rotation 69 | */ 70 | public Vector3D getA1() { 71 | return a1; 72 | } 73 | 74 | /** 75 | * Get the axis of the second rotation. 76 | * 77 | * @return axis of the second rotation 78 | */ 79 | public Vector3D getA2() { 80 | return a2; 81 | } 82 | 83 | /** 84 | * Get the axis of the second rotation. 85 | * 86 | * @return axis of the second rotation 87 | */ 88 | public Vector3D getA3() { 89 | return a3; 90 | } 91 | 92 | /** 93 | * Set of Cardan angles. this ordered set of rotations is around X, then 94 | * around Y, then around Z 95 | */ 96 | public static final RotationOrder XYZ = new RotationOrder("XYZ", Vector3D.plusI, 97 | Vector3D.plusJ, Vector3D.plusK); 98 | 99 | /** 100 | * Set of Cardan angles. this ordered set of rotations is around X, then 101 | * around Z, then around Y 102 | */ 103 | public static final RotationOrder XZY = new RotationOrder("XZY", Vector3D.plusI, 104 | Vector3D.plusK, Vector3D.plusJ); 105 | 106 | /** 107 | * Set of Cardan angles. this ordered set of rotations is around Y, then 108 | * around X, then around Z 109 | */ 110 | public static final RotationOrder YXZ = new RotationOrder("YXZ", Vector3D.plusJ, 111 | Vector3D.plusI, Vector3D.plusK); 112 | 113 | /** 114 | * Set of Cardan angles. this ordered set of rotations is around Y, then 115 | * around Z, then around X 116 | */ 117 | public static final RotationOrder YZX = new RotationOrder("YZX", Vector3D.plusJ, 118 | Vector3D.plusK, Vector3D.plusI); 119 | 120 | /** 121 | * Set of Cardan angles. this ordered set of rotations is around Z, then 122 | * around X, then around Y 123 | */ 124 | public static final RotationOrder ZXY = new RotationOrder("ZXY", Vector3D.plusK, 125 | Vector3D.plusI, Vector3D.plusJ); 126 | 127 | /** 128 | * Set of Cardan angles. this ordered set of rotations is around Z, then 129 | * around Y, then around X 130 | */ 131 | public static final RotationOrder ZYX = new RotationOrder("ZYX", Vector3D.plusK, 132 | Vector3D.plusJ, Vector3D.plusI); 133 | 134 | /** 135 | * Set of Euler angles. this ordered set of rotations is around X, then 136 | * around Y, then around X 137 | */ 138 | public static final RotationOrder XYX = new RotationOrder("XYX", Vector3D.plusI, 139 | Vector3D.plusJ, Vector3D.plusI); 140 | 141 | /** 142 | * Set of Euler angles. this ordered set of rotations is around X, then 143 | * around Z, then around X 144 | */ 145 | public static final RotationOrder XZX = new RotationOrder("XZX", Vector3D.plusI, 146 | Vector3D.plusK, Vector3D.plusI); 147 | 148 | /** 149 | * Set of Euler angles. this ordered set of rotations is around Y, then 150 | * around X, then around Y 151 | */ 152 | public static final RotationOrder YXY = new RotationOrder("YXY", Vector3D.plusJ, 153 | Vector3D.plusI, Vector3D.plusJ); 154 | 155 | /** 156 | * Set of Euler angles. this ordered set of rotations is around Y, then 157 | * around Z, then around Y 158 | */ 159 | public static final RotationOrder YZY = new RotationOrder("YZY", Vector3D.plusJ, 160 | Vector3D.plusK, Vector3D.plusJ); 161 | 162 | /** 163 | * Set of Euler angles. this ordered set of rotations is around Z, then 164 | * around X, then around Z 165 | */ 166 | public static final RotationOrder ZXZ = new RotationOrder("ZXZ", Vector3D.plusK, 167 | Vector3D.plusI, Vector3D.plusK); 168 | 169 | /** 170 | * Set of Euler angles. this ordered set of rotations is around Z, then 171 | * around Y, then around Z 172 | */ 173 | public static final RotationOrder ZYZ = new RotationOrder("ZYZ", Vector3D.plusK, 174 | Vector3D.plusJ, Vector3D.plusK); 175 | 176 | /** Name of the rotations order. */ 177 | private final String name; 178 | 179 | /** Axis of the first rotation. */ 180 | private final Vector3D a1; 181 | 182 | /** Axis of the second rotation. */ 183 | private final Vector3D a2; 184 | 185 | /** Axis of the third rotation. */ 186 | private final Vector3D a3; 187 | 188 | } 189 | -------------------------------------------------------------------------------- /commons-math-1.2/RELEASE-NOTES.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache Commons Math Version 1.2 3 | RELEASE NOTES 4 | 5 | 6 | This release combines bug fixes and new features. Most notable among the new 7 | features are the estimation, optimization, geometry and ode packages added 8 | from the Mantissa library. Implementations of fast Fourier transform, QR 9 | decomposition and several numerical integration algorithms have also been 10 | added, along with enhancements and extensions to packages included in Commons 11 | Math 1.1. This release is source and binary compatible with earlier versions 12 | of Commons Math. 13 | 14 | For more information on Apache Commons Math, see 15 | http://commons.apache.org/math/ 16 | 17 | 18 | SUMMARY OF CHANGES 19 | 20 | ADDITIONS 21 | 22 | * Added the estimation, optimization, geometry and ode packages from the 23 | Mantissa library. 24 | 25 | * MATH-120. Added Pascal distribution implementation. Thanks to Todd C. 26 | Parnell. 27 | 28 | * MATH-148. Added QR Decomposition. Thanks to Joni Salonen. 29 | 30 | * MATH-140. Added Fast Fourier Transform implementation. Thanks to Xiaogang 31 | Zhang. 32 | 33 | * MATH-173. Added one-way ANOVA implementation. Thanks to Bob MacCallum. 34 | 35 | * Added an angle normalization method in MathUtils to force angles in some 36 | user-defined interval 37 | 38 | * Added vectorial covariance computation (either sample or population 39 | covariance) 40 | 41 | * Added multivariate summary statistics. 42 | 43 | 44 | BUG FIXES 45 | 46 | * Fixed numerous warnings in test code. 47 | 48 | * MATH-156. Use the initial guess provided by the user in 49 | BrentSolver.solve(), thus improving speed. Thanks to Tyler Ward. 50 | 51 | * MATH-18. Made ComplexFormat format double values with a provided 52 | NumberFormat instance instead of using the real part format for all values. 53 | Thanks to Phil Steitz. 54 | 55 | * MATH-60. Modified ProperFractionFormat to reject embedded minus signs. 56 | Thanks to Nhung Nnguyen. 57 | 58 | * MATH-151. Added a nextAfter method in MathUtils to return the next 59 | machine-representable number in a specified direction from a given floating 60 | point number. Used this to ensure that MathUtils.round does not return 61 | incorrect results for numbers with bad IEEE754 representations. Thanks to 62 | Luc Maisonobe. 63 | 64 | * MATH-85. Modified getSumSquaredErrors method in SimpleRegression to always 65 | return a non-negative result. Thanks to Mark Osborn, Luc Maisonobe. 66 | 67 | * MATH-153. Corrected nextInt and nextLong to handle wide value ranges. 68 | Thanks to Remi Arntzen. 69 | 70 | * MATH-166. Increased default precision of Gamma and Beta functions. Thanks 71 | to Lukas Theussl. 72 | 73 | * MATH-167. Modified NormalDistributionImpl.cumulativeProbablity to catch 74 | MaxIterationsExceededException and return 0 or 1, resp. if the argument is 75 | more than 20 standard deviations from the mean. 76 | 77 | * MATH-174. Changed Mean.evaluate() to use a two-pass algorithm, improving 78 | accuracy by exploiting the the fact that this method has access to the full 79 | array of data values. 80 | 81 | * MATH-175. Added check and rescaling of expected counts to sum to sum of 82 | expected counts if necessary in ChiSquare test. Thanks to Carl Anderson. 83 | 84 | * MATH-164. Handle multiplication of Complex numbers with infinite parts 85 | specially. 86 | 87 | * MATH-182. Add integer overflow checks in Fraction constructor using double 88 | parameter. 89 | 90 | * MATH-185. Throw EOFException when using empty files with ValueServer in 91 | replay and digest modes. 92 | 93 | * MATH-184. Fixed AbstractIntegerDistribution cumulativeProbablility(-,-) to 94 | correctly handle double arguments. Thanks to Yegor Bryukhov. 95 | 96 | 97 | UPDATES 98 | 99 | * MATH-158. Added log function to MathUtils. Thanks to Hasan Diwan. 100 | 101 | * MATH-160. Added two sample (binned comparison) ChiSquare test. Thanks to 102 | Matthias Hummel. 103 | 104 | * MATH-170. Added SynchronizedDescriptiveStatistics class. Thanks to David J. 105 | M. Karlsen. 106 | 107 | * MATH-154. Added addAndCheck, mulAndCheck, and subAndCheck MathUtils methods 108 | for long integer arguments. Thanks to Remi Arntzen. 109 | 110 | * MATH-171. Merged most functions from ComplexUtils into Complex class, added 111 | static factory method to Complex. Thanks to Niall Pemberton. 112 | 113 | * Deprecated abstract factory methods and made DescriptiveStatistics and and 114 | SummaryStatistics concrete classes. Pushed implementations up from 115 | DescriptiveStatisticsImpl, SummaryStatisticsImpl. Made implementations of 116 | statistics configurable via setters. 117 | 118 | * MATH-176. Add errors guessing to least-squares estimators. Thanks to 119 | Kazuhiro Koshino. 120 | 121 | * MATH-179. Add tests for Fraction constructor using double parameter. Thanks 122 | to Niall Pemberton. 123 | 124 | * MATH-181. Add Fraction constructor using max denominator value. Thanks to 125 | Niall Pemberton. 126 | 127 | * Added a equals and hash methods in MathUtils to check for double arrays 128 | 129 | * MATH-191. Added getSumOfLogs method to SummaryStatistics and made SumOfLogs 130 | instance used by GeometricMean configurable. 131 | 132 | * MATH-188. Made numerator and denominator final in Fraction and deprecated 133 | protected real and imaginary parts fields in Complex, making Fraction 134 | immutable and preparing Complex to become fully immutable in 2.0. Thanks to 135 | Sebastian Bazley. 136 | 137 | DEPRECATIONS SUMMARY 138 | 139 | * The abstract factory pattern used to enable pluggable implementations in the 140 | statistics, analysis and distributions packages has been deprecated and 141 | replaced by setter injection. 142 | 143 | * Non-localized exception messages and associated constructors have been 144 | deprecated and replaced by localized versions. 145 | 146 | * Most methods from the ComplexUtils class have been deprecated, with 147 | implementations moved to the Complex class. 148 | 149 | See "clirr-report.html" included in the docs directory of the binary 150 | distribution for a detailed list of API changes. The "errors" reported at the 151 | top of the report are due to protected fields being moved to superclasses. 152 | These fields are still available, so there is no backward compatibility issue. 153 | 154 | BUILDING COMMONS MATH 155 | 156 | Commons math can be built from the source distribution using Maven 1, Maven 2, 157 | or Ant, launching any one of these from the top-level directory of the unpacked 158 | zip or tarball. For detailed build instructions and information about how to 159 | contribute to Commons Math, see "developers.html" in the docs directory of the 160 | binary distribution. 161 | 162 | -------------------------------------------------------------------------------- /resources/code/ExampleTaglet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or 5 | * without modification, are permitted provided that the following 6 | * conditions are met: 7 | * 8 | * -Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * -Redistribution in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in 13 | * the documentation and/or other materials provided with the 14 | * distribution. 15 | * 16 | * Neither the name of Sun Microsystems, Inc. or the names of 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * This software is provided "AS IS," without a warranty of any 21 | * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND 22 | * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, 23 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY 24 | * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY 25 | * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR 26 | * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR 27 | * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE 28 | * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, 29 | * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER 30 | * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF 31 | * THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN 32 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 33 | * 34 | * You acknowledge that Software is not designed, licensed or 35 | * intended for use in the design, construction, operation or 36 | * maintenance of any nuclear facility. 37 | */ 38 | 39 | import com.sun.tools.doclets.Taglet; 40 | import com.sun.javadoc.*; 41 | import java.util.Map; 42 | import java.io.*; 43 | /** 44 | * A sample Taglet representing @example. This tag can be used in any kind of 45 | * {@link com.sun.javadoc.Doc}. It is not an inline tag. The text is displayed 46 | * in yellow to remind the developer to perform a task. For 47 | * example, "@example Hello" would be shown as: 48 | *
49 | *
50 | * To Do: 51 | *
Fix this! 52 | *
53 | *
54 | * 55 | * @author Jamie Ho 56 | * @since 1.4 57 | */ 58 | 59 | public class ExampleTaglet implements Taglet { 60 | 61 | private static final String NAME = "example"; 62 | private static final String HEADER = "example To Do:"; 63 | 64 | /** 65 | * Return the name of this custom tag. 66 | */ 67 | public String getName() { 68 | return NAME; 69 | } 70 | 71 | /** 72 | * Will return true since @example 73 | * can be used in field documentation. 74 | * @return true since @example 75 | * can be used in field documentation and false 76 | * otherwise. 77 | */ 78 | public boolean inField() { 79 | return true; 80 | } 81 | 82 | /** 83 | * Will return true since @example 84 | * can be used in constructor documentation. 85 | * @return true since @example 86 | * can be used in constructor documentation and false 87 | * otherwise. 88 | */ 89 | public boolean inConstructor() { 90 | return true; 91 | } 92 | 93 | /** 94 | * Will return true since @example 95 | * can be used in method documentation. 96 | * @return true since @example 97 | * can be used in method documentation and false 98 | * otherwise. 99 | */ 100 | public boolean inMethod() { 101 | return true; 102 | } 103 | 104 | /** 105 | * Will return true since @example 106 | * can be used in method documentation. 107 | * @return true since @example 108 | * can be used in overview documentation and false 109 | * otherwise. 110 | */ 111 | public boolean inOverview() { 112 | return true; 113 | } 114 | 115 | /** 116 | * Will return true since @example 117 | * can be used in package documentation. 118 | * @return true since @example 119 | * can be used in package documentation and false 120 | * otherwise. 121 | */ 122 | public boolean inPackage() { 123 | return true; 124 | } 125 | 126 | /** 127 | * Will return true since @example 128 | * can be used in type documentation (classes or interfaces). 129 | * @return true since @example 130 | * can be used in type documentation and false 131 | * otherwise. 132 | */ 133 | public boolean inType() { 134 | return true; 135 | } 136 | 137 | /** 138 | * Will return false since @example 139 | * is not an inline tag. 140 | * @return false since @example 141 | * is not an inline tag. 142 | */ 143 | 144 | public boolean isInlineTag() { 145 | return false; 146 | } 147 | 148 | /** 149 | * Register this Taglet. 150 | * @param tagletMap the map to register this tag to. 151 | */ 152 | public static void register(Map tagletMap) { 153 | ExampleTaglet tag = new ExampleTaglet(); 154 | Taglet t = (Taglet) tagletMap.get(tag.getName()); 155 | if (t != null) { 156 | tagletMap.remove(tag.getName()); 157 | } 158 | tagletMap.put(tag.getName(), tag); 159 | } 160 | 161 | /** 162 | * Given the Tag representation of this custom 163 | * tag, return its string representation. 164 | * @param tag the Tag representation of this custom tag. 165 | */ 166 | public String toString(Tag tag) { 167 | return createHTML(readFile(tag.text())); 168 | } 169 | 170 | 171 | /** 172 | * Given an array of Tags representing this custom 173 | * tag, return its string representation. 174 | * @param tags the array of Tags representing of this custom tag. 175 | */ 176 | public String toString(Tag[] tags) { 177 | if (tags.length == 0) { 178 | return null; 179 | } 180 | return createHTML(readFile(tags[0].text())); 181 | } 182 | 183 | 184 | 185 | String createHTML(String theString) { 186 | if(theString!=null) { 187 | String dd = ""; 193 | 194 | return dd+"\n
" + 195 | "
+Example
" + 196 | "
"+theString+"
" + 197 | "
"; 198 | } 199 | return ""; 200 | } 201 | 202 | 203 | /** 204 | * check if the examples directory exists and return the example as given in the tag. 205 | * @param theExample the name of the example 206 | */ 207 | String readFile(String theExample) { 208 | String record = ""; 209 | String myResult = ""; 210 | int recCount = 0; 211 | String myDir = "../examples"; 212 | File file=new File(myDir); 213 | if(file.exists()==false) { 214 | myDir = "./examples"; 215 | } 216 | try { 217 | FileReader fr = new FileReader(myDir+"/"+theExample+"/"+theExample+".pde"); 218 | BufferedReader br = new BufferedReader(fr); 219 | record = new String(); 220 | while ((record = br.readLine()) != null) { 221 | myResult += record+"\n"; 222 | } 223 | } catch (IOException e) { 224 | System.out.println(e); 225 | return null; 226 | } 227 | return myResult; 228 | } 229 | } 230 | 231 | 232 | -------------------------------------------------------------------------------- /src/peasy/org/apache/commons/math/MathException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package peasy.org.apache.commons.math; 18 | 19 | import java.io.PrintStream; 20 | import java.io.PrintWriter; 21 | import java.text.MessageFormat; 22 | import java.util.Locale; 23 | import java.util.MissingResourceException; 24 | import java.util.ResourceBundle; 25 | 26 | /** 27 | * Base class for commons-math checked exceptions. 28 | *

29 | * Supports nesting, emulating JDK 1.4 behavior if necessary. 30 | *

31 | *

32 | * 33 | * @version $Revision: 620312 $ $Date: 2008-02-10 12:28:59 -0700 (Sun, 10 Feb 34 | * 2008) $ 35 | */ 36 | public class MathException extends Exception { 37 | 38 | /** Serializable version identifier */ 39 | private static final long serialVersionUID = -8602234299177097102L; 40 | 41 | /** 42 | * Does JDK support nested exceptions? 43 | */ 44 | private static final boolean JDK_SUPPORTS_NESTED; 45 | 46 | static { 47 | boolean flag = false; 48 | try { 49 | Throwable.class.getDeclaredMethod("getCause", new Class[0]); 50 | flag = true; 51 | } catch (final NoSuchMethodException ex) { 52 | flag = false; 53 | } 54 | JDK_SUPPORTS_NESTED = flag; 55 | } 56 | 57 | /** Cache for resources bundle. */ 58 | private static ResourceBundle cachedResources = null; 59 | 60 | /** 61 | * Pattern used to build the message. 62 | */ 63 | private final String pattern; 64 | 65 | /** 66 | * Arguments used to build the message. 67 | */ 68 | private final Object[] arguments; 69 | 70 | /** 71 | * Root cause of the exception 72 | */ 73 | private final Throwable rootCause; 74 | 75 | /** 76 | * Translate a string to a given locale. 77 | * 78 | * @param s 79 | * string to translate 80 | * @param locale 81 | * locale into which to translate the string 82 | * @return translated string or original string for unsupported locales or 83 | * unknown strings 84 | */ 85 | private static String translate(final String s, final Locale locale) { 86 | try { 87 | if ((cachedResources == null) 88 | || (!cachedResources.getLocale().equals(locale))) { 89 | // caching the resource bundle 90 | cachedResources = ResourceBundle.getBundle( 91 | "peasy.org.apache.commons.math.MessagesResources", locale); 92 | } 93 | 94 | if (cachedResources.getLocale().getLanguage().equals(locale.getLanguage())) { 95 | // the value of the resource is the translated string 96 | return cachedResources.getString(s); 97 | } 98 | 99 | } catch (final MissingResourceException mre) { 100 | // do nothing here 101 | } 102 | 103 | // the locale is not supported or the resource is unknown 104 | // don't translate and fall back to using the string as is 105 | return s; 106 | 107 | } 108 | 109 | /** 110 | * Builds a message string by from a pattern and its arguments. 111 | * 112 | * @param pattern 113 | * format specifier 114 | * @param arguments 115 | * format arguments 116 | * @param locale 117 | * Locale in which the message should be translated 118 | * @return a message string 119 | */ 120 | private static String buildMessage(final String pattern, final Object[] arguments, 121 | final Locale locale) { 122 | // do it the hard way, for Java 1.3. compatibility 123 | final MessageFormat mf = new MessageFormat(translate(pattern, locale)); 124 | mf.setLocale(locale); 125 | return mf.format(arguments); 126 | } 127 | 128 | /** 129 | * Constructs a new MathException with no detail message. 130 | */ 131 | public MathException() { 132 | super(); 133 | this.pattern = null; 134 | this.arguments = new Object[0]; 135 | this.rootCause = null; 136 | } 137 | 138 | /** 139 | * Constructs a new MathException with specified detail 140 | * message. 141 | * 142 | * @param msg 143 | * the error message. 144 | * @deprecated as of 1.2, replaced by 145 | * {@link #MathException(String, Object[])} 146 | */ 147 | @Deprecated 148 | public MathException(final String msg) { 149 | super(msg); 150 | this.pattern = msg; 151 | this.arguments = new Object[0]; 152 | this.rootCause = null; 153 | } 154 | 155 | /** 156 | * Constructs a new MathException with specified formatted 157 | * detail message. Message formatting is delegated to 158 | * {@link java.text.MessageFormat}. 159 | * 160 | * @param pattern 161 | * format specifier 162 | * @param arguments 163 | * format arguments 164 | */ 165 | public MathException(final String pattern, final Object[] arguments) { 166 | super(buildMessage(pattern, arguments, Locale.US)); 167 | this.pattern = pattern; 168 | this.arguments = arguments.clone(); 169 | this.rootCause = null; 170 | } 171 | 172 | /** 173 | * Constructs a new MathException with specified nested 174 | * Throwable root cause. 175 | * 176 | * @param rootCause 177 | * the exception or error that caused this exception to be 178 | * thrown. 179 | */ 180 | public MathException(final Throwable rootCause) { 181 | super((rootCause == null ? null : rootCause.getMessage())); 182 | this.pattern = getMessage(); 183 | this.arguments = new Object[0]; 184 | this.rootCause = rootCause; 185 | } 186 | 187 | /** 188 | * Constructs a new MathException with specified detail message 189 | * and nested Throwable root cause. 190 | * 191 | * @param msg 192 | * the error message. 193 | * @param rootCause 194 | * the exception or error that caused this exception to be 195 | * thrown. 196 | * @deprecated as of 1.2, replaced by 197 | * {@link #MathException(String, Object[], Throwable)} 198 | */ 199 | @Deprecated 200 | public MathException(final String msg, final Throwable rootCause) { 201 | super(msg); 202 | this.pattern = msg; 203 | this.arguments = new Object[0]; 204 | this.rootCause = rootCause; 205 | } 206 | 207 | /** 208 | * Constructs a new MathException with specified formatted 209 | * detail message and nested Throwable root cause. Message 210 | * formatting is delegated to {@link java.text.MessageFormat}. 211 | * 212 | * @param pattern 213 | * format specifier 214 | * @param arguments 215 | * format arguments 216 | * @param rootCause 217 | * the exception or error that caused this exception to be 218 | * thrown. 219 | * @since 1.2 220 | */ 221 | public MathException(final String pattern, final Object[] arguments, 222 | final Throwable rootCause) { 223 | super(buildMessage(pattern, arguments, Locale.US)); 224 | this.pattern = pattern; 225 | this.arguments = arguments.clone(); 226 | this.rootCause = rootCause; 227 | } 228 | 229 | /** 230 | * Gets the pattern used to build the message of this throwable. 231 | * 232 | * @return the pattern used to build the message of this throwable 233 | * @since 1.2 234 | */ 235 | public String getPattern() { 236 | return pattern; 237 | } 238 | 239 | /** 240 | * Gets the arguments used to build the message of this throwable. 241 | * 242 | * @return the arguments used to build the message of this throwable 243 | * @since 1.2 244 | */ 245 | public Object[] getArguments() { 246 | return arguments.clone(); 247 | } 248 | 249 | /** 250 | * Gets the message in a specified locale. 251 | * 252 | * @param locale 253 | * Locale in which the message should be translated 254 | * 255 | * @return localized message 256 | * @since 1.2 257 | */ 258 | public String getMessage(final Locale locale) { 259 | return (pattern == null) ? null : buildMessage(pattern, arguments, locale); 260 | } 261 | 262 | /** 263 | * Gets the cause of this throwable. 264 | * 265 | * @return the cause of this throwable, or null 266 | */ 267 | @Override 268 | public Throwable getCause() { 269 | return rootCause; 270 | } 271 | 272 | /** 273 | * Prints the stack trace of this exception to the standard error stream. 274 | */ 275 | @Override 276 | public void printStackTrace() { 277 | printStackTrace(System.err); 278 | } 279 | 280 | /** 281 | * Prints the stack trace of this exception to the specified stream. 282 | * 283 | * @param out 284 | * the PrintStream to use for output 285 | */ 286 | @Override 287 | public void printStackTrace(final PrintStream out) { 288 | synchronized (out) { 289 | final PrintWriter pw = new PrintWriter(out, false); 290 | printStackTrace(pw); 291 | // Flush the PrintWriter before it's GC'ed. 292 | pw.flush(); 293 | } 294 | } 295 | 296 | /** 297 | * Prints the stack trace of this exception to the specified writer. 298 | * 299 | * @param out 300 | * the PrintWriter to use for output 301 | */ 302 | @Override 303 | public void printStackTrace(final PrintWriter out) { 304 | synchronized (out) { 305 | super.printStackTrace(out); 306 | if (rootCause != null && JDK_SUPPORTS_NESTED == false) { 307 | out.print("Caused by: "); 308 | rootCause.printStackTrace(out); 309 | } 310 | } 311 | } 312 | 313 | } 314 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | ##yourLibrary## 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |

21 | 22 | 25 | 26 | 38 | 39 |
40 | 41 |
42 | 43 | 68 |
44 |
import peasy.*;
 45 | 
 46 | PeasyCam cam;
 47 | 
 48 | void setup() {
 49 |   size(200,200,P3D);
 50 |   cam = new PeasyCam(this, 100);
 51 |   cam.setMinimumDistance(50);
 52 |   cam.setMaximumDistance(500);
 53 | }
 54 | void draw() {
 55 |   rotateX(-.5);
 56 |   rotateY(-.5);
 57 |   background(0);
 58 |   fill(255,0,0);
 59 |   box(30);
 60 |   pushMatrix();
 61 |   translate(0,0,20);
 62 |   fill(0,0,255);
 63 |   box(5);
 64 |   popMatrix();
 65 | }
 66 | 
67 |
69 |
70 | 71 | 72 |
73 |

##yourLibrary## v##versionNumber##

74 |

75 | A library by ##author## for the 76 | programming environment 77 | processing. 78 | Distributed under the Apache Public License, version 79 | 2.0. 80 | Last update, ##date##. 81 |

82 | 83 |

PeasyCam provides a dead-simple mouse-driven camera for Processing.

84 |

Example

85 |
PeasyCam camera;
 86 | 
 87 | void setup() {
 88 |   camera = new PeasyCam(this, 0, 0, 0, 50);
 89 | }
90 |

91 | That's it. Now a mouse left-drag will rotate the camera around the subject, 92 | a right drag will zoom in and out, and a middle-drag (command-left-drag on mac) will pan. A 93 | double-click restores the camera to its original position. The shift key constrains rotation 94 | and panning to one axis or the other. 95 |

96 |

97 | The PeasyCam is positioned on a sphere whose radius is the given 98 | distance from the look-at point. Rotations are around axes that 99 | pass through the looked-at point. 100 |

101 | 102 |

103 | PeasyCam is impervious to gimbal lock, and has no known "singularities" or 104 | discontinuities in its behavior. It relies on the excellent 105 | Apache Commons Math 106 | geometry package 107 | for its rotations. 108 |

109 | 110 |

Thanks

111 |

Useful bug reports and feature suggestions were provided by:

112 | 121 |

Please let me know if I've forgotten to acknowledge you.

122 | 123 |
124 |

Installing Peasycam

125 |

Processing 1.5.1

126 |

You can download a version of Peasycam compatible with Processing 1.5.1 here: 127 | http://static.mrfeinberg.com/peasycam/peasycam_15100.zip 129 |

130 | 131 |

Processing 2 and Later

132 |

You can install the latest Peasycam from within Processing via the 133 | menus Sketch > Import Library... > Add Library... 134 |

135 |
136 | 137 | 138 |

Constructors

139 |
PeasyCam(PApplet parent, double lookAtX, double lookAtY, double lookAtZ, double distance);
140 | PeasyCam(PApplet parent, double distance); // look at 0,0,0
141 | 
142 | 143 |

Methods

144 |
camera.setActive(boolean active);  // false to make this camera stop responding to mouse
145 | 
146 | // By default, the camera is in "free rotation" mode, but you can
147 | // constrain it to any axis, around the look-at point:
148 | camera.setYawRotationMode();   // like spinning a globe
149 | camera.setPitchRotationMode(); // like a somersault
150 | camera.setRollRotationMode();  // like a radio knob
151 | camera.setSuppressRollRotationMode();  // Permit pitch/yaw only.
152 | 
153 | // Then you can set it back to its default mode:
154 | camera.setFreeRotationMode();
155 | 
156 | // reassign particular drag gestures, or set them to null
157 | camera.setLeftDragHandler(PeasyDragHandler handler);
158 | camera.setCenterDragHandler(PeasyDragHandler handler);
159 | camera.setRightDragHandler(PeasyDragHandler handler);
160 | PeasyDragHandler getPanDragHandler();
161 | PeasyDragHandler getRotateDragHandler();
162 | PeasyDragHandler getZoomDragHandler();
163 | 
164 | // mouse wheel zooms by default; set null, or make your own
165 | camera.setWheelHandler(PeasyWheelHandler handler);
166 | PeasyWheelHandler getZoomWheelHandler();
167 | 
168 | // change sensitivity of built-in mouse wheel zoom
169 | camera.setWheelScale(double scale); // 1.0 by default
170 | double getWheelScale();
171 | 
172 | // make your own!
173 | public interface PeasyDragHandler {
174 |     public void handleDrag(final double dx, final double dy);
175 | }
176 | public interface PeasyWheelHandler {
177 |     public void handleWheel(final int delta);
178 | }
179 | camera.setResetOnDoubleClick(boolean resetOnDoubleClick); // default true
180 | 
181 | camera.lookAt(double x, double y, double z);
182 | camera.lookAt(double x, double y, double z, long animationTimeInMillis);
183 | camera.lookAt(double x, double y, double z, double distance);
184 | camera.lookAt(double x, double y, double z, double distance, long animationTimeInMillis);
185 | 
186 | camera.rotateX(double angle);  // rotate around the x-axis passing through the subject
187 | camera.rotateY(double angle);  // rotate around the y-axis passing through the subject
188 | camera.rotateZ(double angle);  // rotate around the z-axis passing through the subject
189 | camera.setDistance(double d);  // distance from looked-at point
190 | camera.pan(double dx, double dy);   // move the looked-at point relative to current orientation
191 | 
192 | double camera.getDistance();  // current distance
193 | float[] camera.getLookAt();  // float[] { x, y, z }, looked-at point
194 | 
195 | camera.setMinimumDistance(double minimumDistance);
196 | camera.setMaximumDistance(double maximumDistance);  // clamp zooming
197 | 
198 | camera.reset();
199 | camera.reset(long animationTimeInMillis);  // reset camera to its starting settings
200 | 
201 | CameraState state = camera.getState(); // get a serializable settings object for current state
202 | camera.setState(CameraState state);
203 | camera.setState(CameraState state, long animationTimeInMillis); // set the camera to the given saved state
204 | 
205 | float[] rotations = camera.getRotations(); // x, y, and z rotations required to face camera in model space
206 | camera.setRotations(double pitch, double yaw, double roll); // rotations are applied in that order
207 | float[] position = camera.getPosition(); // x, y, and z coordinates of camera in model space
208 | 
209 | // Utility methods to permit the use of a Heads-Up Display
210 | // Thanks, A.W. Martin
211 | camera.beginHUD();
212 | // now draw things that you want relative to the camera's position and orientation
213 | camera.endHUD(); // always!
214 |
215 | 216 |
217 |

Keywords ##keywords##

218 |

Reference. Have a look at the javadoc reference here. a copy of the reference is included in the .zip as well.

219 |

Source. The source code of ##yourLibrary## 220 | is available at ##source:host##, 221 | and its repository can be browsed 222 | here. Fork it and fix it!

223 |
224 | 225 | 234 | 235 |
236 |

Tested

237 |

238 | 239 | Platform ##tested:platform## 240 | 241 | 242 |
Processing ##tested:processingVersion## 243 | 244 | 245 |
Dependencies ##tested:dependencies## 246 |

247 |
248 | 249 | 250 | 251 | 252 | 257 | 258 | 259 | 263 | 264 | 265 |
266 |
267 | 268 | 271 |
272 | 273 | 274 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /commons-math-1.2/LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /src/peasy/org/apache/commons/math/geometry/Vector3D.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package peasy.org.apache.commons.math.geometry; 19 | 20 | import java.io.Serializable; 21 | 22 | /** 23 | * This class implements vectors in a three-dimensional space. 24 | *

25 | * Instance of this class are guaranteed to be immutable. 26 | *

27 | * 28 | * @version $Revision: 627998 $ $Date: 2008-02-15 03:24:50 -0700 (Fri, 15 Feb 29 | * 2008) $ 30 | * @since 1.2 31 | */ 32 | 33 | public class Vector3D implements Serializable { 34 | 35 | /** First canonical vector (coordinates: 1, 0, 0). */ 36 | public static final Vector3D plusI = new Vector3D(1, 0, 0); 37 | 38 | /** Opposite of the first canonical vector (coordinates: -1, 0, 0). */ 39 | public static final Vector3D minusI = new Vector3D(-1, 0, 0); 40 | 41 | /** Second canonical vector (coordinates: 0, 1, 0). */ 42 | public static final Vector3D plusJ = new Vector3D(0, 1, 0); 43 | 44 | /** Opposite of the second canonical vector (coordinates: 0, -1, 0). */ 45 | public static final Vector3D minusJ = new Vector3D(0, -1, 0); 46 | 47 | /** Third canonical vector (coordinates: 0, 0, 1). */ 48 | public static final Vector3D plusK = new Vector3D(0, 0, 1); 49 | 50 | /** Opposite of the third canonical vector (coordinates: 0, 0, -1). */ 51 | public static final Vector3D minusK = new Vector3D(0, 0, -1); 52 | 53 | /** Null vector (coordinates: 0, 0, 0). */ 54 | public static final Vector3D zero = new Vector3D(0, 0, 0); 55 | 56 | /** 57 | * Simple constructor. Build a null vector. 58 | */ 59 | public Vector3D() { 60 | x = 0; 61 | y = 0; 62 | z = 0; 63 | } 64 | 65 | /** 66 | * Simple constructor. Build a vector from its coordinates 67 | * 68 | * @param x 69 | * abscissa 70 | * @param y 71 | * ordinate 72 | * @param z 73 | * height 74 | * @see #getX() 75 | * @see #getY() 76 | * @see #getZ() 77 | */ 78 | public Vector3D(final double x, final double y, final double z) { 79 | this.x = x; 80 | this.y = y; 81 | this.z = z; 82 | } 83 | 84 | /** 85 | * Simple constructor. Build a vector from its azimuthal coordinates 86 | * 87 | * @param alpha 88 | * azimuth (α) around Z (0 is +X, π/2 is +Y, π is -X 89 | * and 3π/2 is -Y) 90 | * @param delta 91 | * elevation (δ) above (XY) plane, from -π/2 to +π/2 92 | * @see #getAlpha() 93 | * @see #getDelta() 94 | */ 95 | public Vector3D(final double alpha, final double delta) { 96 | final double cosDelta = Math.cos(delta); 97 | this.x = Math.cos(alpha) * cosDelta; 98 | this.y = Math.sin(alpha) * cosDelta; 99 | this.z = Math.sin(delta); 100 | } 101 | 102 | /** 103 | * Multiplicative constructor Build a vector from another one and a scale 104 | * factor. The vector built will be a * u 105 | * 106 | * @param a 107 | * scale factor 108 | * @param u 109 | * base (unscaled) vector 110 | */ 111 | public Vector3D(final double a, final Vector3D u) { 112 | this.x = a * u.x; 113 | this.y = a * u.y; 114 | this.z = a * u.z; 115 | } 116 | 117 | /** 118 | * Linear constructor Build a vector from two other ones and corresponding 119 | * scale factors. The vector built will be a1 * u1 + a2 * u2 120 | * 121 | * @param a1 122 | * first scale factor 123 | * @param u1 124 | * first base (unscaled) vector 125 | * @param a2 126 | * second scale factor 127 | * @param u2 128 | * second base (unscaled) vector 129 | */ 130 | public Vector3D(final double a1, final Vector3D u1, final double a2, final Vector3D u2) { 131 | this.x = a1 * u1.x + a2 * u2.x; 132 | this.y = a1 * u1.y + a2 * u2.y; 133 | this.z = a1 * u1.z + a2 * u2.z; 134 | } 135 | 136 | /** 137 | * Linear constructor Build a vector from three other ones and corresponding 138 | * scale factors. The vector built will be a1 * u1 + a2 * u2 + a3 * u3 139 | * 140 | * @param a1 141 | * first scale factor 142 | * @param u1 143 | * first base (unscaled) vector 144 | * @param a2 145 | * second scale factor 146 | * @param u2 147 | * second base (unscaled) vector 148 | * @param a3 149 | * third scale factor 150 | * @param u3 151 | * third base (unscaled) vector 152 | */ 153 | public Vector3D(final double a1, final Vector3D u1, final double a2, 154 | final Vector3D u2, final double a3, final Vector3D u3) { 155 | this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x; 156 | this.y = a1 * u1.y + a2 * u2.y + a3 * u3.y; 157 | this.z = a1 * u1.z + a2 * u2.z + a3 * u3.z; 158 | } 159 | 160 | /** 161 | * Linear constructor Build a vector from four other ones and corresponding 162 | * scale factors. The vector built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 163 | * * u4 164 | * 165 | * @param a1 166 | * first scale factor 167 | * @param u1 168 | * first base (unscaled) vector 169 | * @param a2 170 | * second scale factor 171 | * @param u2 172 | * second base (unscaled) vector 173 | * @param a3 174 | * third scale factor 175 | * @param u3 176 | * third base (unscaled) vector 177 | * @param a4 178 | * fourth scale factor 179 | * @param u4 180 | * fourth base (unscaled) vector 181 | */ 182 | public Vector3D(final double a1, final Vector3D u1, final double a2, 183 | final Vector3D u2, final double a3, final Vector3D u3, final double a4, 184 | final Vector3D u4) { 185 | this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x + a4 * u4.x; 186 | this.y = a1 * u1.y + a2 * u2.y + a3 * u3.y + a4 * u4.y; 187 | this.z = a1 * u1.z + a2 * u2.z + a3 * u3.z + a4 * u4.z; 188 | } 189 | 190 | /** 191 | * Get the abscissa of the vector. 192 | * 193 | * @return abscissa of the vector 194 | * @see #Vector3D(double, double, double) 195 | */ 196 | public double getX() { 197 | return x; 198 | } 199 | 200 | /** 201 | * Get the ordinate of the vector. 202 | * 203 | * @return ordinate of the vector 204 | * @see #Vector3D(double, double, double) 205 | */ 206 | public double getY() { 207 | return y; 208 | } 209 | 210 | /** 211 | * Get the height of the vector. 212 | * 213 | * @return height of the vector 214 | * @see #Vector3D(double, double, double) 215 | */ 216 | public double getZ() { 217 | return z; 218 | } 219 | 220 | /** 221 | * Get the norm for the vector. 222 | * 223 | * @return euclidian norm for the vector 224 | */ 225 | public double getNorm() { 226 | return Math.sqrt(x * x + y * y + z * z); 227 | } 228 | 229 | /** 230 | * Get the azimuth of the vector. 231 | * 232 | * @return azimuth (α) of the vector, between -π and +π 233 | * @see #Vector3D(double, double) 234 | */ 235 | public double getAlpha() { 236 | return Math.atan2(y, x); 237 | } 238 | 239 | /** 240 | * Get the elevation of the vector. 241 | * 242 | * @return elevation (δ) of the vector, between -π/2 and +π/2 243 | * @see #Vector3D(double, double) 244 | */ 245 | public double getDelta() { 246 | return Math.asin(z / getNorm()); 247 | } 248 | 249 | /** 250 | * Add a vector to the instance. 251 | * 252 | * @param v 253 | * vector to add 254 | * @return a new vector 255 | */ 256 | public Vector3D add(final Vector3D v) { 257 | return new Vector3D(x + v.x, y + v.y, z + v.z); 258 | } 259 | 260 | /** 261 | * Add a scaled vector to the instance. 262 | * 263 | * @param factor 264 | * scale factor to apply to v before adding it 265 | * @param v 266 | * vector to add 267 | * @return a new vector 268 | */ 269 | public Vector3D add(final double factor, final Vector3D v) { 270 | return new Vector3D(x + factor * v.x, y + factor * v.y, z + factor * v.z); 271 | } 272 | 273 | /** 274 | * Subtract a vector from the instance. 275 | * 276 | * @param v 277 | * vector to subtract 278 | * @return a new vector 279 | */ 280 | public Vector3D subtract(final Vector3D v) { 281 | return new Vector3D(x - v.x, y - v.y, z - v.z); 282 | } 283 | 284 | /** 285 | * Subtract a scaled vector from the instance. 286 | * 287 | * @param factor 288 | * scale factor to apply to v before subtracting it 289 | * @param v 290 | * vector to subtract 291 | * @return a new vector 292 | */ 293 | public Vector3D subtract(final double factor, final Vector3D v) { 294 | return new Vector3D(x - factor * v.x, y - factor * v.y, z - factor * v.z); 295 | } 296 | 297 | /** 298 | * Get a normalized vector aligned with the instance. 299 | * 300 | * @return a new normalized vector 301 | * @exception ArithmeticException 302 | * if the norm is zero 303 | */ 304 | public Vector3D normalize() { 305 | final double s = getNorm(); 306 | if (s == 0) { 307 | throw new ArithmeticException("cannot normalize a zero norm vector"); 308 | } 309 | return scalarMultiply(1 / s); 310 | } 311 | 312 | /** 313 | * Get a vector orthogonal to the instance. 314 | *

315 | * There are an infinite number of normalized vectors orthogonal to the 316 | * instance. This method picks up one of them almost arbitrarily. It is 317 | * useful when one needs to compute a reference frame with one of the axes 318 | * in a predefined direction. The following example shows how to build a 319 | * frame having the k axis aligned with the known vector u : 320 | * 321 | *

322 | 	 * <code>
323 | 	 *   Vector3D k = u.normalize();
324 | 	 *   Vector3D i = k.orthogonal();
325 | 	 *   Vector3D j = Vector3D.crossProduct(k, i);
326 | 	 * </code>
327 | 	 * 
328 | * 329 | *

330 | * 331 | * @return a new normalized vector orthogonal to the instance 332 | * @exception ArithmeticException 333 | * if the norm of the instance is null 334 | */ 335 | public Vector3D orthogonal() { 336 | 337 | final double threshold = 0.6 * getNorm(); 338 | if (threshold == 0) { 339 | throw new ArithmeticException("null norm"); 340 | } 341 | 342 | if ((x >= -threshold) && (x <= threshold)) { 343 | final double inverse = 1 / Math.sqrt(y * y + z * z); 344 | return new Vector3D(0, inverse * z, -inverse * y); 345 | } else if ((y >= -threshold) && (y <= threshold)) { 346 | final double inverse = 1 / Math.sqrt(x * x + z * z); 347 | return new Vector3D(-inverse * z, 0, inverse * x); 348 | } 349 | final double inverse = 1 / Math.sqrt(x * x + y * y); 350 | return new Vector3D(inverse * y, -inverse * x, 0); 351 | 352 | } 353 | 354 | /** 355 | * Compute the angular separation between two vectors. 356 | *

357 | * This method computes the angular separation between two vectors using the 358 | * dot product for well separated vectors and the cross product for almost 359 | * aligned vectors. This allow to have a good accuracy in all cases, even 360 | * for vectors very close to each other. 361 | *

362 | * 363 | * @param v1 364 | * first vector 365 | * @param v2 366 | * second vector 367 | * @return angular separation between v1 and v2 368 | * @exception ArithmeticException 369 | * if either vector has a null norm 370 | */ 371 | public static double angle(final Vector3D v1, final Vector3D v2) { 372 | 373 | final double normProduct = v1.getNorm() * v2.getNorm(); 374 | if (normProduct == 0) { 375 | throw new ArithmeticException("null norm"); 376 | } 377 | 378 | final double dot = dotProduct(v1, v2); 379 | final double threshold = normProduct * 0.9999; 380 | if ((dot < -threshold) || (dot > threshold)) { 381 | // the vectors are almost aligned, compute using the sine 382 | final Vector3D v3 = crossProduct(v1, v2); 383 | if (dot >= 0) { 384 | return Math.asin(v3.getNorm() / normProduct); 385 | } 386 | return Math.PI - Math.asin(v3.getNorm() / normProduct); 387 | } 388 | 389 | // the vectors are sufficiently separated to use the cosine 390 | return Math.acos(dot / normProduct); 391 | 392 | } 393 | 394 | /** 395 | * Get the opposite of the instance. 396 | * 397 | * @return a new vector which is opposite to the instance 398 | */ 399 | public Vector3D negate() { 400 | return new Vector3D(-x, -y, -z); 401 | } 402 | 403 | /** 404 | * Multiply the instance by a scalar 405 | * 406 | * @param a 407 | * scalar 408 | * @return a new vector 409 | */ 410 | public Vector3D scalarMultiply(final double a) { 411 | return new Vector3D(a * x, a * y, a * z); 412 | } 413 | 414 | /** 415 | * Compute the dot-product of two vectors. 416 | * 417 | * @param v1 418 | * first vector 419 | * @param v2 420 | * second vector 421 | * @return the dot product v1.v2 422 | */ 423 | public static double dotProduct(final Vector3D v1, final Vector3D v2) { 424 | return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; 425 | } 426 | 427 | /** 428 | * Compute the cross-product of two vectors. 429 | * 430 | * @param v1 431 | * first vector 432 | * @param v2 433 | * second vector 434 | * @return the cross product v1 ^ v2 as a new Vector 435 | */ 436 | public static Vector3D crossProduct(final Vector3D v1, final Vector3D v2) { 437 | return new Vector3D(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x 438 | * v2.y - v1.y * v2.x); 439 | } 440 | 441 | /** Abscissa. */ 442 | private final double x; 443 | 444 | /** Ordinate. */ 445 | private final double y; 446 | 447 | /** Height. */ 448 | private final double z; 449 | 450 | /** Serializable version identifier */ 451 | private static final long serialVersionUID = -5721105387745193385L; 452 | 453 | } 454 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | #Thu Apr 22 18:55:46 EDT 2010 2 | eclipse.preferences.version=1 3 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.compliance=1.5 7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.source=1.5 13 | org.eclipse.jdt.core.formatter.align_type_members_on_columns=false 14 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 15 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 16 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 17 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 18 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 19 | org.eclipse.jdt.core.formatter.alignment_for_assignment=0 20 | org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 21 | org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 22 | org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 23 | org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 24 | org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 25 | org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 26 | org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 27 | org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 28 | org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 29 | org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 30 | org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 31 | org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 32 | org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 33 | org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 34 | org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 35 | org.eclipse.jdt.core.formatter.blank_lines_after_package=1 36 | org.eclipse.jdt.core.formatter.blank_lines_before_field=0 37 | org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 38 | org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 39 | org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 40 | org.eclipse.jdt.core.formatter.blank_lines_before_method=1 41 | org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 42 | org.eclipse.jdt.core.formatter.blank_lines_before_package=0 43 | org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 44 | org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 45 | org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line 46 | org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line 47 | org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line 48 | org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line 49 | org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line 50 | org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line 51 | org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line 52 | org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line 53 | org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line 54 | org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line 55 | org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line 56 | org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false 57 | org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false 58 | org.eclipse.jdt.core.formatter.comment.format_block_comments=false 59 | org.eclipse.jdt.core.formatter.comment.format_header=false 60 | org.eclipse.jdt.core.formatter.comment.format_html=true 61 | org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=false 62 | org.eclipse.jdt.core.formatter.comment.format_line_comments=false 63 | org.eclipse.jdt.core.formatter.comment.format_source_code=true 64 | org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true 65 | org.eclipse.jdt.core.formatter.comment.indent_root_tags=true 66 | org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert 67 | org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert 68 | org.eclipse.jdt.core.formatter.comment.line_length=80 69 | org.eclipse.jdt.core.formatter.compact_else_if=true 70 | org.eclipse.jdt.core.formatter.continuation_indentation=2 71 | org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 72 | org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false 73 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true 74 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true 75 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true 76 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true 77 | org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true 78 | org.eclipse.jdt.core.formatter.indent_empty_lines=false 79 | org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true 80 | org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true 81 | org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true 82 | org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false 83 | org.eclipse.jdt.core.formatter.indentation.size=4 84 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert 85 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert 86 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert 87 | org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert 88 | org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert 89 | org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert 90 | org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert 91 | org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert 92 | org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert 93 | org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert 94 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert 95 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert 96 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert 97 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert 98 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert 99 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert 100 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert 101 | org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert 102 | org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert 103 | org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert 104 | org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert 105 | org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert 106 | org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert 107 | org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert 108 | org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert 109 | org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=do not insert 110 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert 111 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert 112 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert 113 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert 114 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert 115 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert 116 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert 117 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert 118 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert 119 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert 120 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert 121 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert 122 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert 123 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert 124 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert 125 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert 126 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert 127 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert 128 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert 129 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert 130 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert 131 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert 132 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert 133 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert 134 | org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert 135 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert 136 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert 137 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert 138 | org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert 139 | org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert 140 | org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert 141 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert 142 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert 143 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert 144 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert 145 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert 146 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert 147 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert 148 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert 149 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert 150 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert 151 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert 152 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert 153 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert 154 | org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert 155 | org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert 156 | org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert 157 | org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert 158 | org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert 159 | org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert 160 | org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert 161 | org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert 162 | org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert 163 | org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert 164 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert 165 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert 166 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert 167 | org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert 168 | org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert 169 | org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert 170 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert 171 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert 172 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert 173 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert 174 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert 175 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert 176 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert 177 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert 178 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert 179 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert 180 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert 181 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert 182 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert 183 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert 184 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert 185 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert 186 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert 187 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert 188 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert 189 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert 190 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert 191 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert 192 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert 193 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert 194 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert 195 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert 196 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert 197 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert 198 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert 199 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert 200 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert 201 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert 202 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert 203 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert 204 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert 205 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert 206 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert 207 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert 208 | org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert 209 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert 210 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert 211 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert 212 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert 213 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert 214 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert 215 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert 216 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert 217 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert 218 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert 219 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert 220 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert 221 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert 222 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert 223 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert 224 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert 225 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert 226 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert 227 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert 228 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert 229 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert 230 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert 231 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert 232 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert 233 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert 234 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert 235 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert 236 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert 237 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert 238 | org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert 239 | org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert 240 | org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert 241 | org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert 242 | org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert 243 | org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert 244 | org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert 245 | org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert 246 | org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert 247 | org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert 248 | org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert 249 | org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert 250 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert 251 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert 252 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert 253 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert 254 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert 255 | org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false 256 | org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false 257 | org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false 258 | org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false 259 | org.eclipse.jdt.core.formatter.lineSplit=90 260 | org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false 261 | org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false 262 | org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 263 | org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 264 | org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true 265 | org.eclipse.jdt.core.formatter.tabulation.char=tab 266 | org.eclipse.jdt.core.formatter.tabulation.size=4 267 | org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false 268 | org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true 269 | -------------------------------------------------------------------------------- /src/peasy/PeasyCam.java: -------------------------------------------------------------------------------- 1 | /* 2 | The PeasyCam Processing library, which provides an easy-peasy 3 | camera for 3D sketching. 4 | 5 | Copyright 2008 Jonathan Feinberg 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | package peasy; 20 | 21 | import peasy.org.apache.commons.math.geometry.CardanEulerSingularityException; 22 | import peasy.org.apache.commons.math.geometry.Rotation; 23 | import peasy.org.apache.commons.math.geometry.RotationOrder; 24 | import peasy.org.apache.commons.math.geometry.Vector3D; 25 | import processing.core.PApplet; 26 | import processing.core.PConstants; 27 | import processing.core.PGraphics; 28 | import processing.event.KeyEvent; 29 | import processing.event.MouseEvent; 30 | import processing.opengl.PGraphicsOpenGL; 31 | 32 | /** 33 | * 34 | * @author Jonathan Feinberg 35 | * @author Thomas Diewald 36 | * 37 | */ 38 | public class PeasyCam { 39 | 40 | public final String VERSION = "301"; 41 | 42 | private static final Vector3D LOOK = Vector3D.plusK; 43 | private static final Vector3D UP = Vector3D.plusJ; 44 | private static final double SMALLEST_MINIMUM_DISTANCE = 0.01; 45 | 46 | private static enum Constraint { 47 | YAW, PITCH, ROLL, SUPPRESS_ROLL 48 | } 49 | 50 | private final PGraphics g; 51 | private final PApplet p; 52 | 53 | private final double startDistance; 54 | private final Vector3D startCenter; 55 | 56 | private boolean resetOnDoubleClick = true; 57 | private double minimumDistance = 1; 58 | private double maximumDistance = Double.MAX_VALUE; 59 | 60 | private final DampedAction rotateX, rotateY, rotateZ, dampedZoom, dampedPanX, 61 | dampedPanY; 62 | 63 | private double distance; 64 | private Vector3D center; 65 | private Rotation rotation; 66 | 67 | // viewport for the mouse-pointer [x,y,w,h] 68 | private int[] viewport = new int[4]; 69 | 70 | private Constraint dragConstraint = null; 71 | private Constraint permaConstraint = null; 72 | 73 | private final InterpolationManager rotationInterps = new InterpolationManager(); 74 | private final InterpolationManager centerInterps = new InterpolationManager(); 75 | private final InterpolationManager distanceInterps = new InterpolationManager(); 76 | 77 | private final PeasyDragHandler panHandler /* ha ha ha */ = new PeasyDragHandler() { 78 | public void handleDrag(final double dx, final double dy) { 79 | dampedPanX.impulse(dx / 8.); 80 | dampedPanY.impulse(dy / 8.); 81 | } 82 | }; 83 | private PeasyDragHandler centerDragHandler = panHandler; 84 | 85 | private final PeasyDragHandler rotateHandler = new PeasyDragHandler() { 86 | public void handleDrag(final double dx, final double dy) { 87 | mouseRotate(dx, dy); 88 | } 89 | }; 90 | private PeasyDragHandler leftDragHandler = rotateHandler; 91 | 92 | private final PeasyDragHandler zoomHandler = new PeasyDragHandler() { 93 | public void handleDrag(final double dx, final double dy) { 94 | dampedZoom.impulse(dy / 10.0); 95 | } 96 | }; 97 | private PeasyDragHandler rightDraghandler = zoomHandler; 98 | 99 | private final PeasyWheelHandler zoomWheelHandler = new PeasyWheelHandler() { 100 | public void handleWheel(final int delta) { 101 | dampedZoom.impulse(wheelScale * delta); 102 | } 103 | }; 104 | private PeasyWheelHandler wheelHandler = zoomWheelHandler; 105 | private double wheelScale = 1.0; 106 | 107 | private final PeasyEventListener peasyEventListener = new PeasyEventListener(); 108 | private boolean isActive = false; 109 | 110 | 111 | 112 | public PeasyCam(final PApplet parent, final double distance) { 113 | this(parent, parent.g, 0, 0, 0, distance); 114 | } 115 | 116 | public PeasyCam(final PApplet parent, final double lookAtX, final double lookAtY, 117 | final double lookAtZ, final double distance) { 118 | this(parent, parent.g, lookAtX, lookAtY, lookAtZ, distance); 119 | } 120 | 121 | public PeasyCam(final PApplet parent, final PGraphics pg, final double distance) { 122 | this(parent, pg, 0, 0, 0, distance); 123 | } 124 | 125 | public PeasyCam(final PApplet parent, PGraphics pg, final double lookAtX, 126 | final double lookAtY, final double lookAtZ, final double distance) { 127 | this.p = parent; 128 | this.g = pg; 129 | this.startCenter = this.center = new Vector3D(lookAtX, lookAtY, lookAtZ); 130 | this.startDistance = this.distance = Math.max(distance, 131 | SMALLEST_MINIMUM_DISTANCE); 132 | this.rotation = new Rotation(); 133 | 134 | viewport[0] = 0; 135 | viewport[1] = 0; 136 | viewport[2] = pg.width; 137 | viewport[3] = pg.height; 138 | 139 | feed(); 140 | 141 | rotateX = new DampedAction(this) { 142 | @Override 143 | protected void behave(final double velocity) { 144 | rotation = rotation.applyTo(new Rotation(Vector3D.plusI, velocity)); 145 | } 146 | }; 147 | 148 | rotateY = new DampedAction(this) { 149 | @Override 150 | protected void behave(final double velocity) { 151 | rotation = rotation.applyTo(new Rotation(Vector3D.plusJ, velocity)); 152 | } 153 | }; 154 | 155 | rotateZ = new DampedAction(this) { 156 | @Override 157 | protected void behave(final double velocity) { 158 | rotation = rotation.applyTo(new Rotation(Vector3D.plusK, velocity)); 159 | } 160 | }; 161 | 162 | dampedZoom = new DampedAction(this) { 163 | @Override 164 | protected void behave(final double velocity) { 165 | mouseZoom(velocity); 166 | } 167 | }; 168 | 169 | dampedPanX = new DampedAction(this) { 170 | @Override 171 | protected void behave(final double velocity) { 172 | mousePan(velocity, 0); 173 | } 174 | }; 175 | 176 | dampedPanY = new DampedAction(this) { 177 | @Override 178 | protected void behave(final double velocity) { 179 | mousePan(0, velocity); 180 | } 181 | }; 182 | 183 | setActive(true); 184 | } 185 | 186 | public void setActive(final boolean active) { 187 | if (active == isActive) { 188 | return; 189 | } 190 | isActive = active; 191 | if (isActive) { 192 | p.registerMethod("mouseEvent", peasyEventListener); 193 | p.registerMethod("keyEvent", peasyEventListener); 194 | } else { 195 | p.unregisterMethod("mouseEvent", peasyEventListener); 196 | p.unregisterMethod("keyEvent", peasyEventListener); 197 | } 198 | } 199 | 200 | public boolean isActive() { 201 | return isActive; 202 | } 203 | 204 | /** 205 | *

206 | * Turn on or off default mouse-handling behavior: 207 | * 208 | *

209 | * 210 | * 211 | * 212 | * 213 | * 214 | * 215 | * 216 | * 217 | * 218 | * 219 | * 220 | * 221 | * 222 | * 223 | * 224 | * 225 | * 226 | *
left-dragrotate camera around look-at point
center-dragpan camera (change look-at point)
right-dragzoom
wheelzoom
227 | * 228 | * @param isMouseControlled 229 | * @deprecated use {@link #setActive(boolean)} 230 | */ 231 | @Deprecated 232 | public void setMouseControlled(final boolean isMouseControlled) { 233 | setActive(isMouseControlled); 234 | } 235 | 236 | public double getWheelScale() { 237 | return wheelScale; 238 | } 239 | 240 | public void setWheelScale(final double wheelScale) { 241 | this.wheelScale = wheelScale; 242 | } 243 | 244 | public PeasyDragHandler getPanDragHandler() { 245 | return panHandler; 246 | } 247 | 248 | public PeasyDragHandler getRotateDragHandler() { 249 | return rotateHandler; 250 | } 251 | 252 | public PeasyDragHandler getZoomDragHandler() { 253 | return zoomHandler; 254 | } 255 | 256 | public PeasyWheelHandler getZoomWheelHandler() { 257 | return zoomWheelHandler; 258 | } 259 | 260 | public void setLeftDragHandler(final PeasyDragHandler handler) { 261 | leftDragHandler = handler; 262 | } 263 | 264 | public void setCenterDragHandler(final PeasyDragHandler handler) { 265 | centerDragHandler = handler; 266 | } 267 | 268 | public void setRightDragHandler(final PeasyDragHandler handler) { 269 | rightDraghandler = handler; 270 | } 271 | 272 | public PeasyWheelHandler getWheelHandler() { 273 | return wheelHandler; 274 | } 275 | 276 | public void setWheelHandler(final PeasyWheelHandler wheelHandler) { 277 | this.wheelHandler = wheelHandler; 278 | } 279 | 280 | public String version() { 281 | return VERSION; 282 | } 283 | 284 | public void setViewport(int x, int y, int w, int h) { 285 | viewport[0] = x; 286 | viewport[1] = y; 287 | viewport[2] = w; 288 | viewport[3] = h; 289 | } 290 | 291 | public int[] getViewport() { 292 | return viewport; 293 | } 294 | 295 | public PGraphics getCanvas() { 296 | return g; 297 | } 298 | 299 | public boolean insideViewport(double x, double y) { 300 | float x0 = viewport[0], x1 = x0 + viewport[2]; 301 | float y0 = viewport[1], y1 = y0 + viewport[3]; 302 | return (x > x0) && (x < x1) && (y > y0) && (y < y1); 303 | } 304 | 305 | protected class PeasyEventListener { 306 | 307 | public boolean isActive = false; 308 | 309 | public void keyEvent(final KeyEvent e) { 310 | if (e.getAction() == KeyEvent.RELEASE && e.isShiftDown()) 311 | dragConstraint = null; 312 | } 313 | 314 | public void mouseEvent(final MouseEvent e) { 315 | switch (e.getAction()) { 316 | 317 | case MouseEvent.PRESS: 318 | if (insideViewport(p.mouseX, p.mouseY)) { 319 | isActive = true; 320 | } 321 | break; 322 | 323 | case MouseEvent.RELEASE: 324 | dragConstraint = null; 325 | isActive = false; 326 | break; 327 | 328 | case MouseEvent.CLICK: 329 | if (insideViewport(p.mouseX, p.mouseY)) { 330 | if (resetOnDoubleClick && 2 == (int)e.getCount()) { 331 | reset(); 332 | } 333 | } 334 | break; 335 | 336 | case MouseEvent.WHEEL: 337 | if (wheelHandler != null && insideViewport(p.mouseX, p.mouseY)) { 338 | wheelHandler.handleWheel((int)e.getCount()); 339 | } 340 | break; 341 | 342 | case MouseEvent.DRAG: 343 | if (isActive) { 344 | final double dx = p.mouseX - p.pmouseX; 345 | final double dy = p.mouseY - p.pmouseY; 346 | 347 | if (e.isShiftDown()) { 348 | if (dragConstraint == null && Math.abs(dx - dy) > 1) { 349 | dragConstraint = Math.abs(dx) > Math.abs(dy) ? Constraint.YAW 350 | : Constraint.PITCH; 351 | } 352 | } else if (permaConstraint != null) { 353 | dragConstraint = permaConstraint; 354 | } else { 355 | dragConstraint = null; 356 | } 357 | 358 | final int b = p.mouseButton; 359 | if (centerDragHandler != null && (b == PConstants.CENTER 360 | || (b == PConstants.LEFT && e.isMetaDown()))) { 361 | centerDragHandler.handleDrag(dx, dy); 362 | } else if (leftDragHandler != null && b == PConstants.LEFT) { 363 | leftDragHandler.handleDrag(dx, dy); 364 | } else if (rightDraghandler != null && b == PConstants.RIGHT) { 365 | rightDraghandler.handleDrag(dx, dy); 366 | } 367 | } 368 | break; 369 | } 370 | } 371 | } 372 | 373 | private void mouseZoom(final double delta) { 374 | double new_distance = distance + delta * distance * 0.02; 375 | if (new_distance < minimumDistance) { 376 | new_distance = minimumDistance; 377 | dampedZoom.stop(); 378 | } 379 | if (new_distance > maximumDistance) { 380 | new_distance = maximumDistance; 381 | dampedZoom.stop(); 382 | } 383 | safeSetDistance(new_distance); 384 | } 385 | 386 | private void mousePan(final double dxMouse, final double dyMouse) { 387 | final double panScale = distance * 0.0025; 388 | pan(dragConstraint == Constraint.PITCH ? 0 : -dxMouse * panScale, 389 | dragConstraint == Constraint.YAW ? 0 : -dyMouse * panScale); 390 | } 391 | 392 | private void mouseRotate(final double dx, final double dy) { 393 | double mult = -Math.pow(Math.log10(1 + distance), 0.5) * 0.00125f; 394 | 395 | double dmx = dx * mult; 396 | double dmy = dy * mult; 397 | 398 | double viewX = viewport[0]; 399 | double viewY = viewport[1]; 400 | double viewW = viewport[2]; 401 | double viewH = viewport[3]; 402 | 403 | // mouse [-1, +1] 404 | double mxNdc = Math.min(Math.max((p.mouseX - viewX) / viewW, 0), 1) * 2 - 1; 405 | double myNdc = Math.min(Math.max((p.mouseY - viewY) / viewH, 0), 1) * 2 - 1; 406 | 407 | if (dragConstraint == null || dragConstraint == Constraint.YAW 408 | || dragConstraint == Constraint.SUPPRESS_ROLL) { 409 | rotateY.impulse(+dmx * (1.0 - myNdc * myNdc)); 410 | } 411 | if (dragConstraint == null || dragConstraint == Constraint.PITCH 412 | || dragConstraint == Constraint.SUPPRESS_ROLL) { 413 | rotateX.impulse(-dmy * (1.0 - mxNdc * mxNdc)); 414 | } 415 | if (dragConstraint == null || dragConstraint == Constraint.ROLL) { 416 | rotateZ.impulse(-dmx * myNdc); 417 | rotateZ.impulse(+dmy * mxNdc); 418 | } 419 | } 420 | 421 | public double getDistance() { 422 | return distance; 423 | } 424 | 425 | public void setDistance(final double newDistance) { 426 | setDistance(newDistance, 300); 427 | } 428 | 429 | public void setDistance(final double newDistance, final long animationTimeMillis) { 430 | distanceInterps 431 | .startInterpolation(new DistanceInterp(newDistance, animationTimeMillis)); 432 | } 433 | 434 | public float[] getLookAt() { 435 | return new float[] { (float)center.getX(), (float)center.getY(), 436 | (float)center.getZ() }; 437 | } 438 | 439 | public void lookAt(final double x, final double y, final double z) { 440 | centerInterps.startInterpolation(new CenterInterp(new Vector3D(x, y, z), 300)); 441 | } 442 | 443 | public void lookAt(final double x, final double y, final double z, 444 | final double distance) { 445 | lookAt(x, y, z); 446 | setDistance(distance); 447 | } 448 | 449 | public void lookAt(final double x, final double y, final double z, 450 | final long animationTimeMillis) { 451 | lookAt(x, y, z, distance, animationTimeMillis); 452 | } 453 | 454 | public void lookAt(final double x, final double y, final double z, 455 | final double distance, final long animationTimeMillis) { 456 | setState(new CameraState(rotation, new Vector3D(x, y, z), distance), 457 | animationTimeMillis); 458 | } 459 | 460 | private void safeSetDistance(final double distance) { 461 | this.distance = Math.min(maximumDistance, Math.max(minimumDistance, distance)); 462 | feed(); 463 | } 464 | 465 | public void feed() { 466 | final Vector3D pos = rotation.applyTo(LOOK).scalarMultiply(distance).add(center); 467 | final Vector3D rup = rotation.applyTo(UP); 468 | g.camera((float)pos.getX(), (float)pos.getY(), (float)pos.getZ(), // 469 | (float)center.getX(), (float)center.getY(), (float)center.getZ(), // 470 | (float)rup.getX(), (float)rup.getY(), (float)rup.getZ()); 471 | } 472 | 473 | static void apply(final PGraphics g, final Vector3D center, final Rotation rotation, 474 | final double distance) { 475 | final Vector3D pos = rotation.applyTo(LOOK).scalarMultiply(distance).add(center); 476 | final Vector3D rup = rotation.applyTo(UP); 477 | g.camera((float)pos.getX(), (float)pos.getY(), (float)pos.getZ(), // 478 | (float)center.getX(), (float)center.getY(), (float)center.getZ(), // 479 | (float)rup.getX(), (float)rup.getY(), (float)rup.getZ()); 480 | } 481 | 482 | /** 483 | * Where is the PeasyCam in world space? 484 | * 485 | * @return float[]{x,y,z} 486 | */ 487 | public float[] getPosition() { 488 | final Vector3D pos = rotation.applyTo(LOOK).scalarMultiply(distance).add(center); 489 | return new float[] { (float)pos.getX(), (float)pos.getY(), (float)pos.getZ() }; 490 | } 491 | 492 | public void reset() { 493 | reset(300); 494 | } 495 | 496 | public void reset(final long animationTimeInMillis) { 497 | setState(new CameraState(new Rotation(), startCenter, startDistance), 498 | animationTimeInMillis); 499 | } 500 | 501 | public void pan(final double dx, final double dy) { 502 | center = center.add(rotation.applyTo(new Vector3D(dx, dy, 0))); 503 | feed(); 504 | } 505 | 506 | public void rotateX(final double angle) { 507 | rotation = rotation.applyTo(new Rotation(Vector3D.plusI, angle)); 508 | feed(); 509 | } 510 | 511 | public void rotateY(final double angle) { 512 | rotation = rotation.applyTo(new Rotation(Vector3D.plusJ, angle)); 513 | feed(); 514 | } 515 | 516 | public void rotateZ(final double angle) { 517 | rotation = rotation.applyTo(new Rotation(Vector3D.plusK, angle)); 518 | feed(); 519 | } 520 | 521 | PApplet getApplet() { 522 | return p; 523 | } 524 | 525 | public CameraState getState() { 526 | return new CameraState(rotation, center, distance); 527 | } 528 | 529 | /** 530 | * Permit arbitrary rotation. (Default mode.) 531 | */ 532 | public void setFreeRotationMode() { 533 | permaConstraint = null; 534 | } 535 | 536 | /** 537 | * Only permit yaw. 538 | */ 539 | public void setYawRotationMode() { 540 | permaConstraint = Constraint.YAW; 541 | } 542 | 543 | /** 544 | * Only permit pitch. 545 | */ 546 | public void setPitchRotationMode() { 547 | permaConstraint = Constraint.PITCH; 548 | } 549 | 550 | /** 551 | * Only permit roll. 552 | */ 553 | public void setRollRotationMode() { 554 | permaConstraint = Constraint.ROLL; 555 | } 556 | 557 | /** 558 | * Only suppress roll. 559 | */ 560 | public void setSuppressRollRotationMode() { 561 | permaConstraint = Constraint.SUPPRESS_ROLL; 562 | } 563 | 564 | public void setMinimumDistance(final double minimumDistance) { 565 | this.minimumDistance = Math.max(minimumDistance, SMALLEST_MINIMUM_DISTANCE); 566 | safeSetDistance(distance); 567 | } 568 | 569 | public void setMaximumDistance(final double maximumDistance) { 570 | this.maximumDistance = maximumDistance; 571 | safeSetDistance(distance); 572 | } 573 | 574 | public void setResetOnDoubleClick(final boolean resetOnDoubleClick) { 575 | this.resetOnDoubleClick = resetOnDoubleClick; 576 | } 577 | 578 | public void setState(final CameraState state) { 579 | setState(state, 300); 580 | } 581 | 582 | public void setState(final CameraState state, final long animationTimeMillis) { 583 | if (animationTimeMillis > 0) { 584 | rotationInterps.startInterpolation( 585 | new RotationInterp(state.rotation, animationTimeMillis)); 586 | centerInterps.startInterpolation( 587 | new CenterInterp(state.center, animationTimeMillis)); 588 | distanceInterps.startInterpolation( 589 | new DistanceInterp(state.distance, animationTimeMillis)); 590 | } else { 591 | this.rotation = state.rotation; 592 | this.center = state.center; 593 | this.distance = state.distance; 594 | } 595 | feed(); 596 | } 597 | 598 | public void setRotations(final double pitch, final double yaw, final double roll) { 599 | rotationInterps.cancelInterpolation(); 600 | this.rotation = new Rotation(RotationOrder.XYZ, pitch, yaw, roll); 601 | feed(); 602 | } 603 | 604 | /** 605 | * Express the current camera rotation as an equivalent series 606 | * of world rotations, in X, Y, Z order. This is useful when, 607 | * for example, you wish to orient text towards the camera 608 | * at all times, as in 609 | * 610 | *

float[] rotations = cam.getRotations(rotations);
611 | 	 *rotateX(rotations[0]);
612 | 	 *rotateY(rotations[1]);
613 | 	 *rotateZ(rotations[2]);
614 | 	 *text("Here I am!", 0, 0, 0);
615 | */ 616 | public float[] getRotations() { 617 | try { 618 | final double[] angles = rotation.getAngles(RotationOrder.XYZ); 619 | return new float[] { (float)angles[0], (float)angles[1], (float)angles[2] }; 620 | } catch (final CardanEulerSingularityException e) { 621 | } 622 | try { 623 | final double[] angles = rotation.getAngles(RotationOrder.YXZ); 624 | return new float[] { (float)angles[1], (float)angles[0], (float)angles[2] }; 625 | } catch (final CardanEulerSingularityException e) { 626 | } 627 | try { 628 | final double[] angles = rotation.getAngles(RotationOrder.ZXY); 629 | return new float[] { (float)angles[2], (float)angles[0], (float)angles[1] }; 630 | } catch (final CardanEulerSingularityException e) { 631 | } 632 | return new float[] { 0, 0, 0 }; 633 | } 634 | 635 | private boolean pushedLights = false; 636 | 637 | /** 638 | * 639 | * begin screen-aligned 2D-drawing. 640 | *
641 | 	 * beginHUD()
642 | 	 *   disabled depth test
643 | 	 *   disabled lights
644 | 	 *   ortho
645 | 	 * endHUD()
646 | 	 * 
647 | * 648 | */ 649 | public void beginHUD() { 650 | g.hint(PConstants.DISABLE_DEPTH_TEST); 651 | g.pushMatrix(); 652 | g.resetMatrix(); 653 | // 3D is always GL (in processing 3), so this check is probably redundant. 654 | if (g.isGL() && g.is3D()) { 655 | PGraphicsOpenGL pgl = (PGraphicsOpenGL)g; 656 | pushedLights = pgl.lights; 657 | pgl.lights = false; 658 | pgl.pushProjection(); 659 | g.ortho(0, viewport[2], -viewport[3], 0, -Float.MAX_VALUE, +Float.MAX_VALUE); 660 | } 661 | } 662 | 663 | /** 664 | * 665 | * end screen-aligned 2D-drawing. 666 | * 667 | */ 668 | public void endHUD() { 669 | if (g.isGL() && g.is3D()) { 670 | PGraphicsOpenGL pgl = (PGraphicsOpenGL)g; 671 | pgl.popProjection(); 672 | pgl.lights = pushedLights; 673 | } 674 | g.popMatrix(); 675 | g.hint(PConstants.ENABLE_DEPTH_TEST); 676 | } 677 | 678 | abstract public class AbstractInterp { 679 | double startTime; 680 | final double timeInMillis; 681 | 682 | protected AbstractInterp(final long timeInMillis) { 683 | this.timeInMillis = timeInMillis; 684 | } 685 | 686 | void start() { 687 | startTime = p.millis(); 688 | p.registerMethod("draw", this); 689 | } 690 | 691 | void cancel() { 692 | p.unregisterMethod("draw", this); 693 | } 694 | 695 | public void draw() { 696 | final double t = (p.millis() - startTime) / timeInMillis; 697 | if (t > .99) { 698 | cancel(); 699 | setEndState(); 700 | } else { 701 | interp(t); 702 | } 703 | feed(); 704 | } 705 | 706 | protected abstract void interp(double t); 707 | 708 | protected abstract void setEndState(); 709 | } 710 | 711 | class DistanceInterp extends AbstractInterp { 712 | private final double startDistance = distance; 713 | private final double endDistance; 714 | 715 | public DistanceInterp(final double endDistance, final long timeInMillis) { 716 | super(timeInMillis); 717 | this.endDistance = Math.min(maximumDistance, 718 | Math.max(minimumDistance, endDistance)); 719 | } 720 | 721 | @Override 722 | protected void interp(final double t) { 723 | distance = InterpolationUtil.smooth(startDistance, endDistance, t); 724 | } 725 | 726 | @Override 727 | protected void setEndState() { 728 | distance = endDistance; 729 | } 730 | } 731 | 732 | class CenterInterp extends AbstractInterp { 733 | private final Vector3D startCenter = center; 734 | private final Vector3D endCenter; 735 | 736 | public CenterInterp(final Vector3D endCenter, final long timeInMillis) { 737 | super(timeInMillis); 738 | this.endCenter = endCenter; 739 | } 740 | 741 | @Override 742 | protected void interp(final double t) { 743 | center = InterpolationUtil.smooth(startCenter, endCenter, t); 744 | } 745 | 746 | @Override 747 | protected void setEndState() { 748 | center = endCenter; 749 | } 750 | } 751 | 752 | class RotationInterp extends AbstractInterp { 753 | final Rotation startRotation = rotation; 754 | final Rotation endRotation; 755 | 756 | public RotationInterp(final Rotation endRotation, final long timeInMillis) { 757 | super(timeInMillis); 758 | this.endRotation = endRotation; 759 | } 760 | 761 | @Override 762 | void start() { 763 | rotateX.stop(); 764 | rotateY.stop(); 765 | rotateZ.stop(); 766 | super.start(); 767 | } 768 | 769 | @Override 770 | protected void interp(final double t) { 771 | rotation = InterpolationUtil.slerp(startRotation, endRotation, t); 772 | } 773 | 774 | @Override 775 | protected void setEndState() { 776 | rotation = endRotation; 777 | } 778 | } 779 | } 780 | --------------------------------------------------------------------------------