// NMI's Java Code Viewer 5.1 © 1997-2001 B. Lemaire // http://njcv.htmlplanet.com - info@njcv.htmlplanet.com // Copy registered to Evaluation Copy // Source File Name: circular3D.java import java.applet.Applet; import java.awt.*; public class circular3D extends Applet implements Runnable { private static final double xmax = 200D; private static final double xmin = -200D; private static final double ymax = 200D; private static final double ymin = -200D; private static final double zmax = 150D; private static final double zmin = -200D; private static int id[] = { 0, 4, 8, 9, 13, 17 }; int yOffset; TextField tm; TextField tl; Dimension area; Image bgImage; Image fgImage; Graphics gb; Graphics g; Matrix3D mat; Matrix3D tmat; Checkbox cb; boolean trace; double vert[] = { 200D, 0.0D, 0.0D, 0.0D, 200D, 0.0D, 0.0D, 0.0D, 150D, -200D, 0.0D, 0.0D, 0.0D, -200D, 0.0D, 0.0D, 0.0D, -200D, 200D, 200D, 0.0D, -200D, 200D, 0.0D, 200D, -200D, 0.0D, -200D, -200D, 0.0D }; int xc; int yc; int nvert; int tvert[]; Color bgColor; double scale; double scale2; double scale3; private double w; private double r; private double mgm; double mgmcst; int msize; rMotion PP; String rts; String STR[] = { "Reset", "Clean", "Trace", "L", "Mgm" }; boolean fixMass; double third; double Unit[]; int labelX[] = { -3, 0, 4 }; int labelY[] = { -5, -5, 5 }; int PX[]; int PY[]; double xp; double yp; double theta; double length; double rmin; double rmax; double Lmoment; int chx; String Label[] = { "A", "B", "C" }; double pxs; double pys; double pzs; double px; double py; double pz; int xx; int yy; Thread animThread; long startTime; long lastTime; long delay; long delta; boolean running; private double twoPi; private double V; private double VP; private double Vcst; private double time; int size; int size2; int y2; int xv; int yv; boolean rightClick; double deltaC; double VPs; int prevx; int prevy; boolean moving; boolean changeV; FontMetrics fm; int strHeight; int strWidth; public void init() { setBackground(bgColor); for(int i = 0; i < STR.length; i++) if((rts = getParameter(STR[i])) != null) STR[i] = new String(rts); mat = new Matrix3D(); tmat = new Matrix3D(); Panel panel = new Panel(); panel.add(new Label(STR[3] + "=")); panel.add(tl = new TextField(d2String(Lmoment), 5)); panel.add(new Label(STR[4] + "=")); panel.add(tm = new TextField(String.valueOf(mgm), 3)); panel.add(new Button(STR[0])); panel.add(new Button(STR[1])); panel.add(cb = new Checkbox(STR[2])); tm.setEditable(false); add("North", panel); PP = new rMotion(scale); reset(true); } void setMsize() { msize = (int)(Math.pow(mgm, third) * 1.2D); } public boolean action(Event event, Object obj) { if(event.target instanceof Button) { String s = (String)obj; if(s.equals(STR[0])) reset(true); else if(s.equals(STR[1])) reset(false); } else if(event.target == cb) trace = cb.getState(); else if(event.target instanceof TextField) { Lmoment = Double.valueOf(tl.getText()).doubleValue() / scale3; reset(true); } return true; } public void reset(boolean flag) { clear(); time = 0.0D; if(flag) { xc = area.width / 2; yc = (area.height - (int)length) + 30; mat.unit(); mat.zrot(-120); mat.xrot(-120); moving = false; r = 100D; w = 1.5707963267948966D; xp = r; yp = 0.0D; theta = 0.0D; if(Lmoment < 100D) Lmoment = r * r * w; mgm = r * w * w * scale; setMsize(); PP.setparam(Lmoment, mgm, r); showInfo(); } refresh(); } void refresh() { mat.transform(vert, tvert, nvert); PX[0] = xc + tvert[18]; PY[0] = yc + tvert[19]; PX[1] = xc + tvert[21]; PY[1] = yc + tvert[22]; PX[2] = xc + tvert[27]; PY[2] = yc + tvert[28]; PX[3] = xc + tvert[24]; PY[3] = yc + tvert[25]; PX[4] = xc + tvert[18]; PY[4] = yc + tvert[19]; gb.setColor(Color.white); gb.drawPolygon(PX, PY, 5); for(int i1 = 0; i1 < 2; i1++) { int i = tvert[3 * i1]; int k = tvert[3 * i1 + 1]; double d = Math.sqrt(i * i + k * k); Unit[2 * i1] = (double)i / d; Unit[2 * i1 + 1] = (double)k / d; drawAxis(i, k, vert[id[i1]], labelX[i1], labelY[i1], false); } int j = tvert[9]; int l = tvert[10]; drawAxis(j, l, -vert[id[3]], 0, 0, false); j = tvert[12]; l = tvert[13]; drawAxis(j, l, -vert[id[4]], 0, 0, false); gb.setColor(Color.black); gb.fillOval(xc - 2, yc - 1, 4, 4); gb.setColor(Color.black); byte byte0 = 6; gb.drawString("X", xc + tvert[0] + byte0, yc + tvert[1] + byte0); gb.drawString("Y", xc + tvert[3] + byte0, yc + tvert[4] + byte0); gb.setColor(Color.blue); g.drawImage(bgImage, 0, 0, this); repaint(); } void drawAxis(int i, int j, double d, int k, int l, boolean flag) { double d1 = d; double d2 = (double)i / d1; double d3 = (double)j / d1; gb.setColor(Color.yellow); drawVec(gb, i, j); gb.setColor(Color.black); for(double d4 = 0.0D; d4 < d; d4 += scale2) gb.drawLine(xx = xc + (int)(d4 * d2), yy = yc + (int)(d4 * d3), xx, yy); gb.setColor(Color.black); byte byte0 = 2; byte byte1 = 4; for(double d5 = 50D; d5 <= d; d5 += 50D) { gb.fillOval(xx = (xc + (int)(d5 * d2)) - byte0, yy = (yc + (int)(d5 * d3)) - byte0, byte1, byte1); if(flag) gb.drawString(String.valueOf(d5 / 10D), xx + k, yy + l); } } void drawVec(Graphics g1, int i, int j) { g1.drawLine(xc, yc, xc + i, yc + j); } public void start() { if(animThread == null) { animThread = new Thread(this); animThread.start(); } lastTime = startTime = System.currentTimeMillis(); } public void stop() { animThread = null; running = false; } public void run() { Thread.currentThread().setPriority(1); //for(; Thread.currentThread() == animThread; Nop) { for(; Thread.currentThread() == animThread; ) { delta = System.currentTimeMillis() - lastTime; lastTime += delta; if(running) advanced((double)delta / 1000D); startTime += delay; try { Thread.sleep(Math.max(0L, startTime - System.currentTimeMillis())); continue; } catch(InterruptedException interruptedexception) { } break; } } void advanced(double d) { g.drawImage(bgImage, 0, 0, this); if(fixMass) { PP.adnanced(d); r = ((rk4) (PP)).y[0]; w = Lmoment / (r * r); } time += d; g.setColor(Color.black); //g.drawString("r=" + d2String(r * scale) + ", w=" + d2String(w), 5, 15); g.drawString("r=" + d2String(r * scale) + ", Ang. Vel.=" + d2String(w), 5, 15); g.drawString("t=" + d2String(time) + " s", xc, 15); VP = r * w * Vcst; theta += w * d; theta = theta % twoPi; xp = r * Math.cos(theta); yp = r * Math.sin(theta); mat.transform(xp, yp, 0.0D, tvert); g.setColor(Color.green); g.drawLine(xc, yc, xv = xx = xc + tvert[0], yv = yy = yc + tvert[1]); g.drawLine(xc, yc, xc, y2 = yc + (int)(length - r)); xp = -VP * Math.sin(theta); yp = VP * Math.cos(theta); mat.transform(xp, yp, 0.0D, tvert); g.setColor(Color.white); drawArrow(g, xx, yy, tvert[0], tvert[1]); g.setColor(Color.red); g.fillOval(xx - size, yy - size, size2, size2); if(trace) gb.drawLine(xx, yy, xx, yy); g.setColor(Color.black); g.fillOval((xc - msize) + 1, y2 - msize, 2 * msize, 2 * msize); g.setColor(Color.white); g.drawLine(PX[3], PY[3], PX[4], PY[4]); repaint(); } void drawArrow(Graphics g1, int i, int j, int k, int l) { g1.drawLine(i, j, i += k, j += l); double d = Math.atan((double)l / (double)k); if(k < 0) d += 3.1415926535897931D; double d1 = Math.sqrt(k * k + l * l) * 0.080000000000000002D; g1.drawLine(i, j, i - (int)(d1 * Math.cos(d + deltaC)), j - (int)(d1 * Math.sin(d + deltaC))); g1.drawLine(i, j, i - (int)(d1 * Math.cos(d - deltaC)), j - (int)(d1 * Math.sin(d - deltaC))); } public boolean mouseDown(Event event, int i, int j) { if((j -= yOffset) < 0) return false; if(event.modifiers == 4) { rightClick = true; prevy = j; prevx = i; } else { rightClick = false; } if(!running) { if(Math.sqrt((i - xv) * (i - xv) + (j - yv) * (j - yv)) < (double)size2) { changeV = true; } else { changeV = false; running = !running; } } else if(Math.abs(i - xc) < msize && j > yc + msize) { if(rightClick) fixMass = true; else fixMass = false; moving = true; running = false; prevx = i; prevy = j; } else { running = !running; moving = false; } return true; } void showInfo() { tm.setText(d2String(mgm)); tl.setText(d2String(Lmoment * scale3)); advanced(0.0D); } String d2String(double d) { float f = (float)((double)(int)(d * 100D) / 100D); String s = String.valueOf(f); if(s.indexOf(".") == -1) s += ".0"; return s; } public boolean mouseDrag(Event event, int i, int j) { if((j -= yOffset) < 0) return false; if(changeV) { VPs = VP; VP = Math.sqrt((i - xv) * (i - xv) + (j - yv) * (j - yv)); if(VP < 10D) VP = 10D; double d = VP / VPs; mgm *= d * d; setMsize(); V = VP / Vcst; Lmoment = r * V; w = V / r; PP.setparam(Lmoment, mgm, r); showInfo(); repaint(); } else if(moving) { r -= j - prevy; if(r < rmin) r = rmin; else if(r > rmax) r = rmax; if(fixMass) { PP.setparam(Lmoment, mgm, r); } else { w = Lmoment / (r * r); mgm = r * w * w * scale; setMsize(); } showInfo(); prevy = j; repaint(); } else if(rightClick && Math.sqrt((i - prevx) * (i - prevx) + (j - prevy) * (j - prevy)) > (double)size2) { tmat.unit(); tmat.xrot((2D * (double)(prevy - j)) / (double)area.width); tmat.yrot((2D * (double)(prevx - i)) / (double)area.height); prevx = i; prevy = j; mat.mult(tmat); mat.transform(vert, tvert, nvert); reset(false); advanced(0.0D); repaint(); } return true; } public boolean mouseUp(Event event, int i, int j) { if((j -= yOffset) < 0) return false; if(!rightClick) running = !running; if(changeV) running = true; else if(!fixMass) { w = Lmoment / (r * r); mgm = r * w * w * scale; setMsize(); } if(moving) { moving = false; running = true; } changeV = false; return true; } void clear() { if(g == null) { area = size(); area.height -= yOffset; bgImage = createImage(area.width, area.height); gb = bgImage.getGraphics(); fgImage = createImage(area.width, area.height); g = fgImage.getGraphics(); fm = g.getFontMetrics(); strHeight = fm.getHeight(); strWidth = fm.stringWidth("99.9, "); } gb.setColor(bgColor); gb.fillRect(0, 0, area.width, area.height); gb.setColor(Color.lightGray); gb.fillRect(0, 0, area.width - 1, area.height - 1); } public void paint(Graphics g1) { update(g1); } public void update(Graphics g1) { g1.drawImage(fgImage, 0, yOffset, this); } public circular3D() { yOffset = 50; trace = false; nvert = vert.length / 3; tvert = new int[nvert * 3]; bgColor = Color.lightGray; scale = 0.10000000000000001D; scale2 = 1.0D / scale; scale3 = scale * scale; w = 1.5707963267948966D; r = 100D; mgm = w * w * r * scale; mgmcst = 4.9000000000000004D; fixMass = false; third = 0.33333333333333331D; Unit = new double[6]; PX = new int[5]; PY = new int[5]; length = 210D; rmin = 10D; rmax = length - rmin; chx = 12; startTime = 0L; delay = 30L; running = true; twoPi = 6.2831853071795862D; Vcst = 0.29999999999999999D; size = 3; size2 = 2 * size; rightClick = false; deltaC = 0.52359877559829882D; moving = false; changeV = false; } }