import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.vecmath.*; public class Device extends JComponent implements WireMesh { private int width; private int height; private float scale; private Vector3f viewPosition = new Vector3f ( 5, 5, 5 ); private Vector3f viewNormal = new Vector3f ( -1, -1, -1); private Vector3f viewUp = new Vector3f ( 0, 0, 1); private Vector3f up; private Vector3f right; private float up0; private float right0; private Graphics g; private ParametricCurve model; private Vector3f i = new Vector3f ( 1, 0, 0 ); private Vector3f j = new Vector3f ( 0, 1, 0 ); private Vector3f k = new Vector3f ( 0, 0, 2 ); private Vector3f zero = new Vector3f ( 0, 0, 0 ); private boolean debug = false; public Device ( int h, int w, float s ){ width = w; height = h; scale = s; fixView(); } public Device ( int h, int w ) { this ( h, w, 1.0f ); } public Device() { this ( 550, 850 ); } private void fixView() { viewNormal.normalize(); up = new Vector3f(viewUp); up.scaleAdd ( - up.dot( viewNormal), viewNormal, up ); up.normalize(); right = new Vector3f(); right.cross ( viewNormal, up ); right0 = right.dot ( viewPosition ); up0 = up.dot ( viewPosition ); } public void devLine ( float x1, float y1, float x2, float y2 ) { g.drawLine ( (int) (x1*scale + width/2.0), (int) (-y1*scale + height/2.0), (int) (x2*scale + width/2.0), (int) (-y2*scale + height/2.0) ); if ( debug ) { System.out.println ( (int) (x1*scale + width/2.0) + " " + (int) (-y1*scale + height/2.0) + " " + (int) (x2*scale + width/2.0) + " " + (int) (-y2*scale + height/2.0) ); } } public Vector2f worldToView ( Vector3f v1 ) { return new Vector2f ( v1.dot ( right ) - right0, v1.dot ( up ) - up0 ); } public Vector3f modelToWorld ( Vector3f v1 ) { return v1; } public Dimension getSize() { return new Dimension ( width, height ); } public void lineVector3f ( Vector3f a, Vector3f b ) { Vector2f v1 = worldToView ( modelToWorld ( a ) ); Vector2f v2 = worldToView ( modelToWorld ( b ) ); devLine ( v1.x, v1.y, v2.x, v2.y ); } public void paint ( Graphics gIn ) { g = gIn; g.setColor ( Color.black ); model.draw(this); //debug = true; //System.out.println ( "New Paint" ); g.setColor ( Color.blue ); lineVector3f ( zero, i ); lineVector3f ( zero, j ); lineVector3f ( zero, k ); //debug = false; } public void setModel ( ParametricCurve m ) { model = m; } public static void main ( String[] args ) { try { UIManager.setLookAndFeel ( UIManager.getCrossPlatformLookAndFeelClassName() ); } catch ( Exception exc ) { System.out.println ( "Error loading L&F: " + exc ); } WindowListener l = new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }; JFrame frame = new JFrame ( "Sci Vis" ); frame.addWindowListener(l); Function3f fun = new Helix(1, 1); ParametricCurve p = new ParametricCurve ( 0, 3, 0.25f, fun ); Device d = new Device( 600, 600, 100); d.setModel ( p ); frame.getContentPane().add(d, BorderLayout.CENTER); frame.setSize ( d.getSize() ); frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); frame.show(); frame.validate(); frame.repaint(); d.requestDefaultFocus(); } }