OSP Volumen 3D y Flecha de Vector
Imagen
Para rotar un elemento
se puede trabajar con el código:
1. Con matriz de rotación
```
/**
* www.opensourcephysics.org/
* @author Wolfgang Christian
*/
import org.opensourcephysics.display3d.simple3d.*;
import org.opensourcephysics.frames.Display3DFrame;
import org.opensourcephysics.numerics.*;
public class MatrixRotationApp {
public static void main(String[] args) {
Display3DFrame frame = new Display3DFrame("Axis-angle Rotation");
frame.setDecorationType(org.opensourcephysics.display3d.core.VisualizationHints.DECORATION_AXES);
Element ellipsoid = new ElementEllipsoid();
Element arrow = new ElementArrow();
ellipsoid.setSizeXYZ(0.4, 0.4, 1.0);
frame.addElement(arrow);
frame.addElement(ellipsoid);
frame.setVisible(true);
frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
double theta = 0;
double[] axis = new double[] {0.5, 0.5, 1}; // rotation axis
arrow.setSizeXYZ(axis);
while(true) { // animate until the program exits
try {
Thread.sleep(100);
} catch(InterruptedException ex) {}
theta += Math.PI/40;
Transformation transformation = Matrix3DTransformation.rotation(theta, axis);
ellipsoid.setTransformation(transformation);
frame.render();
}
}
}
```
2. Con quaterniones
```
/**
* www.opensourcephysics.org/
* @author Wolfgang Christian
*/
import org.opensourcephysics.display3d.simple3d.*;
import org.opensourcephysics.frames.Display3DFrame;
import org.opensourcephysics.numerics.*;
public class QRotationApp {
public static void main(String[] args) {
Display3DFrame frame = new Display3DFrame("Quaternion Rotation");
frame.setDecorationType(org.opensourcephysics.display3d.core.VisualizationHints.DECORATION_AXES);
Element ellipsoid = new ElementEllipsoid();
Element arrow = new ElementArrow();
ellipsoid.setSizeXYZ(0.4, 0.4, 1.0);
Quaternion rotation = new Quaternion(1, 0, 0, 0);
ellipsoid.setTransformation(rotation);
frame.addElement(arrow);
frame.addElement(ellipsoid);
frame.setVisible(true);
frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
double theta = 0;
double[] n = new double[] {0.5, 0.5, 1}; // rotation axis
arrow.setSizeXYZ(n);
while(true) { // animate until the program exits
try {
Thread.sleep(100);
} catch(InterruptedException ex) {}
theta += Math.PI/40;
double cos = Math.cos(theta/2), sin = Math.sin(theta/2);
// setCoordinates will normalize quaternion
rotation.setCoordinates(cos, sin*n[0], sin*n[1], sin*n[2]);
ellipsoid.setTransformation(rotation);
frame.render();
}
}
}
```
ID:(2433, 0)
OSP Volumen, con Resorte y Esfera
Imagen
Para graficar una masa oscilando en un resorte
se puede trabajar con el código:
```
/**
* www.opensourcephysics.org/
* @author Wolfgang Christian
*/
import org.opensourcephysics.controls.*;
import org.opensourcephysics.display3d.core.interaction.*;
import org.opensourcephysics.display3d.simple3d.*;
import org.opensourcephysics.numerics.*;
public class SHO3DApp extends AbstractSimulation implements ODE, InteractionListener {
// Graphical elements
private DrawingPanel3D panel;
private ElementSpring spring;
private ElementCircle ball;
// initial state values = {x, v, t}
private double[] state = new double[] {0.0, 0.0, 0.0};
private double k = 1; // spring constant
private double b = 0.2; // damping constant
private double length = 1; // Spring length at rest
private double ballSize = 0.4;
private double blockSize = 0.1;
private ODESolver ode_solver = new RK4(this);
public SHO3DApp() {
panel = new DrawingPanel3D();
panel.setPreferredMinMax(-length, length, -length, length, -length, length);
panel.getCamera().setAzimuth(-Math.PI/2); // This is so that the 3D and 2D views look similar
panel.getVisualizationHints().setAllowQuickRedraw(false); // The scene is simple, so draw it properly when rotating
panel.getVisualizationHints().setShowCoordinates(org.opensourcephysics.display3d.core.DrawingPanel3D.TOP_LEFT);
panel.getVisualizationHints().setYFormat(null);
panel.getVisualizationHints().setZFormat(null);
Element wall = new ElementBox();
wall.setXYZ(-length-blockSize/2, 0, 0);
wall.setSizeXYZ(blockSize, 0.8, 0.8);
wall.getStyle().setResolution(new Resolution(1, 4, 4));
panel.addElement(wall);
spring = new ElementSpring();
spring.setXYZ(-length, 0, 0);
spring.setSizeXYZ(length+state[0]-ballSize/3, 0, 0); // size y=0.0 and size z=0.0 imply that it will remain parallel to the X axis
spring.setRadius(0.1); // The radius of the spring (normal to its direction). Default is actually 0.1
panel.addElement(spring);
ball = new ElementCircle();
ball.setXYZ(state[0], 0, 0);
ball.setSizeXYZ(ballSize, ballSize, ballSize);
ball.getInteractionTarget(org.opensourcephysics.display3d.core.Element.TARGET_POSITION).setEnabled(true);
ball.addInteractionListener(this);
panel.addElement(ball);
panel.setMessage("Drag the ball.");
DrawingFrame3D frame = new DrawingFrame3D();
frame.setDrawingPanel3D(panel);
frame.getJFrame().setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
protected void doStep() {
ode_solver.step();
ball.setX(state[0]);
spring.setSizeX(length+state[0]-ballSize/3); // Force the spring to follow the bob
panel.setMessage("t="+Util.f2(state[2]), 0);
}
// Impementation of InteractionListener
public void interactionPerformed(InteractionEvent _event) {
switch(_event.getID()) {
case InteractionEvent.MOUSE_PRESSED :
stopSimulation();
break;
case InteractionEvent.MOUSE_DRAGGED :
state[0] = ball.getX();
state[1] = 0;
ball.setY(0);
ball.setZ(0);
spring.setSizeX(length+state[0]-ballSize/3); // Force the spring to follow the ball
panel.render();
break;
case InteractionEvent.MOUSE_RELEASED :
startSimulation();
break;
}
}
// Impementation of ODE
public double[] getState() {
return state;
}
public void getRate(double[] state, double[] rate) {
rate[0] = state[1]; // dx/dt = v
double force = -k*state[0]-b*state[1];
rate[1] = force; // dv/dt = force
rate[2] = 1; // dt/dt = 1
}
public static void main(String[] args) {
(new SHO3DApp()).startSimulation(); // starts simulation after it is instantiated
}
}
```
ID:(1813, 0)