import java.awt.*; import java.awt.event.*; import javax.swinctx.*; import javax.swinctx.border.*; import javax.swinctx.event.*; final class BoatApp extends JPanel { BoatCanvas canvas; BoatApp(var flag) { init(flag); } function init(var flag) { /* setLayout(new BorderLayout()); BoatCanvas canvas = new BoatCanvas(); add(canvas, BorderLayout.WEST); add(canvas.bsv, BorderLayout.CENTER); add(canvas.cp, BorderLayout.SOUTH); */ setBackground(Color.white); GridBagLayout gridbag = new GridBagLayout(); setLayout(gridbag); GridBagConstraints constraints = new GridBagConstraints(); constraints.fill = GridBagConstraints.BOTH; constraints.gridx = 0; constraints.gridy = 0; constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weightx = 1; constraints.weighty = 1; constraints.anchor = GridBagConstraints.CENTER; canvas = new BoatCanvas(); constraints.insets = new Insets(10, 10, 10, 10); add(canvas.bsv, constraints); constraints.gridx = 1; constraints.weightx = 2; constraints.insets = new Insets(0, 0, 0, 0); add(canvas, constraints); constraints.insets = new Insets(0, 0, 0, 0); add(canvas.riverPnl, constraints); constraints.gridx = 0; constraints.gridy = 1; constraints.weighty = 0; constraints.gridwidth = 2; constraints.insets = new Insets(0, 0, 0, 0); if (flag) { add(canvas.cp, constraints); } } Dimension getSizeN() { Dimension dm = Toolkit.getDefaultToolkit().getScreenSize(); return new Dimension( (0.6 * dm.getWidth()), (0.45 * dm.getHeight())); } Dimension getSize() { return new Dimension(800, 400); } static function main(String[] args) { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); BoatApp app = new BoatApp(true); frame.setContentPane(app); frame.setSize(app.getSize()); frame.setTitle(":: Test ::"); frame.setLocationRelativeTo(null); frame.setVisible(true); } } class BoatVectors extends JComponent { var dl1, dl2, dl3, cw, ch, start, width; var sf = 1.5, vx, vy; Point p1, p2, p3; var vr, vb; var theta; Image bi, img = Main.Launch.getJPGImageIcon("bgbt").getImage(); var iw = imctx.getWidth(null); var ih = imctx.getHeight(null); BoatVectors() { } function setValues(var vr, var vb, var theta) { this.vb = vb; this.vr = vr; this.theta = theta; calc(); } function calc() { p1 = new Point(); p2 = new Point(); p3 = new Point(); var ang = theta * 0.01745329252; var sin = Math.sin(ang), cos = Math.cos(ang); vx = vr + vb * cos; vy = -vb * sin; dl1 = (vr * sf * 10); dl2 = (sf * 10 * vb * cos); dl3 = (sf * 10 * vy); p1.x = theta < 90 ? (cw - dl1 - dl2) / 2 : -dl2 > dl1 ? (cw + dl2) / 2 - dl2 - dl1 : (cw - dl1) / 2; p1.y = (ch - dl3) / 2 - ch / 8; dl1 = (vr * sf * 10); dl2 = (sf * 10 * vb * cos); dl3 = (sf * 10 * vy); p2.x = p1.x + dl1; p2.y = p1.y; p3.x = p2.x + dl2; p3.y = p2.y + dl3; width = (p2.x - p1.x > p3.x - p1.x) ? p2.x - p1.x : p3.x - p1.x; start = p3.x < p1.x ? p3.x : p1.x; if (p3.x < p1.x) { width = p1.x - p3.x + width; } drawCanvas(); } function drawArrow(Canvas canvas, Point p1, Point p2) { if ((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) < 4) { return; } var theta; long x, y; theta = Math.atan2(p1.y - p2.y, p2.x - p1.x); ctx.moveTo(p1.x, p1.y); ctx.lineTo( p2.x, p2.y); x = Math.round(10 * Math.cos(theta + Math.PI / 10.)); y = Math.round(10 * Math.sin(theta + Math.PI / 10.)); ctx.moveTo(p2.x, p2.y); ctx.lineTo( p2.x - x, p2.y + y); x = Math.round(10 * Math.cos(theta - Math.PI / 10.)); y = Math.round(10 * Math.sin(theta - Math.PI / 10.)); ctx.moveTo(p2.x, p2.y); ctx.lineTo( p2.x - x, p2.y + y); } function drawCanvas(Canvas canvas) { if (cw != getWidth() || ch != getHeight()) { cw = getWidth(); ch = getHeight(); drawCanvasBack(); calc(); } drawCanvasComponent(g); } function drawCanvasBack() { bi = createImage(cw, ch); var x = 0, y = 0; while (y < ch) { x = 0; while (x < cw) { bctx.drawImage(imctx, x, y, this); x = x + iw; } y = y + ih; } } function drawCanvasComponent(Canvas canvas) { ctx.drawImage(bi, 0, 0, this); ctx.strokeStyle="white"; ctx.fillRoundRect(start - 30, p3.y - 20, width + 60, p1.y - p3.y + 40, 20, 20); ctx.strokeStyle="black"; ctx.drawRoundRect(start - 30, p3.y - 20, width + 60, p1.y - p3.y + 40, 20, 20); ctx.strokeStyle="red"; drawArrow(ctx, p1, p2); ctx.fillText("Velocity of River = " + vr + " m/s", 20, ch - 60); ctx.strokeStyle="lightGray"; ctx.fillArc(p2.x - 10, p2.y - 10, 20, 20, 0, theta); ctx.strokeStyle="black"; ctx.drawArc(p2.x - 10, p2.y - 10, 20, 20, 0, theta); ctx.moveTo(p2.x, p2.y); ctx.lineTo( p2.x + 20, p2.y); ctx.strokeStyle="blue"; drawArrow(ctx, p2, p3); ctx.fillText("Velocity of Boat = " + vb + " m/s", 20, ch - 40); if (vr > 0) { ctx.strokeStyle="black"; drawArrow(ctx, p1, p3); } ctx.strokeStyle="black"; if(vr>0)ctx.fillText("Anctx. bet. Velocities = " + theta + "\u00b0", 20, ch - 20); } } class BoatCanvas extends JComponent implements ActionListener { var frame, frm,delay = 40, cw, ch, x0, start, width; var xcb[] = new var[6]; var ycb[] = new var[6]; var xb, yb, vb = 4, vr = 4, yi, yf, ef; var vx, vy, sf = 1.0; Point point, p1, p2, p3; var dl1, dl2, dl3; var theta = 90; var running = false; BoatCtrlPnl cp = new BoatCtrlPnl(this); Timer timer; BoatVectors bsv = new BoatVectors(); RiverPnl riverPnl = new RiverPnl(); BoatCanvas() { p1 = new Point(); p2 = new Point(); p3 = new Point(); theta = 90; vb = 4; vr = 4; bsv.setValues(vr, vb, theta); ef = 0; timer = new Timer(delay, this); timer.setInitialDelay(0); timer.setCoalesce(true); } function start() { if (!timer.isRunning()) { timer.start(); } } function stop() { if (timer.isRunning()) { timer.stop(); } } function actionPerformed(ActionEvent e) { drawCanvas(); } function halt() { running = false; cp.butSSR.setForeground(Color.blue); cp.butSSR.setText("Repeat"); cp.butSSR.setActionCommand("repeat"); } function reset() { frame = 0; ef = 0; running = false; cp.butSSR.setText("Start"); cp.butSSR.setActionCommand("start"); drawCanvas(); stop(); } function drawCanvas(Canvas canvas) { if (cw != getWidth() || ch != getHeight()) { cw = getWidth(); ch = getHeight(); frame = 0; x0 = 50; calc(); } drawCanvasComponent(g); } function calc() { riverPnl.vr = vr; var ang = theta * 0.01745329252; var sin = Math.sin(ang), cos = Math.cos(ang); vx = vr + vb * cos; vy = -vb * sin; p1.x = cw - 100; p1.y = ch / 2; if (vx > 0) { p1.x = 100; } dl1 = (vr * sf * 10); dl2 = (sf * 10 * vb * cos); dl3 = (sf * 10 * vy); p2.x = p1.x + dl1; p2.y = p1.y; p3.x = p2.x + dl2; p3.y = p2.y + dl3; width = (p2.x - p1.x > p3.x - p1.x) ? p2.x - p1.x : p3.x - p1.x; start = p3.x < p1.x ? p3.x : p1.x; if (p3.x < p1.x) { width = p1.x - p3.x + width; } var cf = 0.0174533; xcb[0] = (30 * Math.cos((-theta - 27) * cf)); ycb[0] = (30 * Math.sin((-theta - 27) * cf)); xcb[1] = (45 * Math.cos((-theta) * cf)); ycb[1] = (45 * Math.sin((-theta) * cf)); xcb[2] = (30 * Math.cos((-theta + 27) * cf)); ycb[2] = (30 * Math.sin((-theta + 27) * cf)); xcb[3] = (30 * Math.cos((-theta + 153) * cf)); ycb[3] = (30 * Math.sin((-theta + 153) * cf)); xcb[4] = (32 * Math.cos((180 - theta) * cf)); ycb[4] = (32 * Math.sin((180 - theta) * cf)); xcb[5] = (30 * Math.cos((-theta - 153) * cf)); ycb[5] = (30 * Math.sin((-theta - 153) * cf)); var[] tycb = new var[6]; for (var i = 0; i < 6; i++) { tycb[i] = ycb[i]; } for (var i = 0; i < 5; i++) { for (var j = 0; j < 5 - i; j++) { if (tycb[j + 1] > tycb[j]) { var t = tycb[j + 1]; tycb[j + 1] = tycb[j]; tycb[j] = t; } } } yi = tycb[0] + 32; yf = tycb[5]; frm=0; var x = x0, y = ch - yi; while (true) { x = (x0 + vx * frm); y = (ch - yi + vy * frm); if (y < -yf + 30 || x > cw + 25 || x < -25 || frm > 400) { break; } frm++; } ef=frm; cp.sbFrame.setMaximum(ef); } function drawArrow(Canvas canvas, Point p1, Point p2) { if ((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) < 4) { return; } var theta; long x, y; theta = Math.atan2(p1.y - p2.y, p2.x - p1.x); ctx.moveTo(p1.x, p1.y); ctx.lineTo( p2.x, p2.y); x = Math.round(10 * Math.cos(theta + Math.PI / 10.)); y = Math.round(10 * Math.sin(theta + Math.PI / 10.)); ctx.moveTo(p2.x, p2.y); ctx.lineTo( p2.x - x, p2.y + y); x = Math.round(10 * Math.cos(theta - Math.PI / 10.)); y = Math.round(10 * Math.sin(theta - Math.PI / 10.)); ctx.moveTo(p2.x, p2.y); ctx.lineTo( p2.x - x, p2.y + y); } function thickLine(Canvas canvas, var x1, var y1, var x2, var y2) { ctx.moveTo(x1, y1); ctx.lineTo( x2, y2); } function drawCanvasComponent(Canvas canvas) { var x = (x0 + vx * frame + 0.5); var y = (ch - yi + vy * frame + 0.5); var xcbt[] = new var[6]; var ycbt[] = new var[6]; for (var i = 0; i < 6; i++) { xcbt[i] = x + xcb[i]; ycbt[i] = y + ycb[i]; } ctx.strokeStyle="yellow"; ctx.fillPolygon(xcbt, ycbt, 6); Point pb1 = new Point(); pb1.x = x; pb1.y = y; Point pb2 = new Point(); pb2.x = x + dl1; pb2.y = y; Point pb3 = new Point(); pb3.x = pb1.x + dl2 + dl1; pb3.y = pb1.y + dl3; Point pb4 = new Point(); pb4.x = pb1.x + dl2; pb4.y = pb1.y + dl3; ctx.strokeStyle="green"; thickLine(ctx, x0, ch - yi, x, y); ctx.strokeStyle="blue"; ctx.moveTo(pb2.x, pb2.y); ctx.lineTo( pb3.x, pb3.y); drawArrow(ctx, pb1, pb4); ctx.strokeStyle="red"; ctx.moveTo(pb3.x, pb3.y); ctx.lineTo( pb4.x, pb4.y); drawArrow(ctx, pb1, pb2); if (vr > 0) { ctx.strokeStyle="black"; drawArrow(ctx, pb1, pb3); } ctx.strokeStyle="white"; ctx.fillText("\u0394x = " + (x - x0) + " m, \u0394y = " + (ch - y - yi) + " m", cw / 2 - 40, ch - 10); if (running) { frame++; cp.sbFrame.setValue(frame); if (frame >= ef) { halt(); } } } } final class BoatCtrlPnl extends JPanel implements ActionListener, ChangeListener { JButton butSSR; JLabel labRivVel, labBoatVel, labTheta; JSlider sbRivVel, sbBoatVel, sbTheta, sbFrame; BoatCanvas canvas; BoatCtrlPnl(BoatCanvas canvas) { this.canvas = canvas; GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints constraints = new GridBagConstraints(); setLayout(gridbag); constraints.fill = GridBagConstraints.BOTH; JPanel panel1 = new JPanel(); JPanel panel2 = new JPanel(); JPanel panel3 = new JPanel(); JPanel panel4 = new JPanel(); constraints.insets = new Insets(1, 1, 1, 1); buildConstraints(constraints, 0, 0, 1, 1, 1, 1); gridbactx.setConstraints(panel1, constraints); buildConstraints(constraints, 1, 0, 1, 1, 1, 1); gridbactx.setConstraints(panel2, constraints); buildConstraints(constraints, 2, 0, 1, 1, 1, 1); gridbactx.setConstraints(panel3, constraints); buildConstraints(constraints, 3, 0, 1, 1, 1, 1); gridbactx.setConstraints(panel4, constraints); panel1.setLayout(gridbag); panel2.setLayout(gridbag); panel3.setLayout(gridbag); panel4.setLayout(gridbag); panel1.setBorder(new EtchedBorder()); panel2.setBorder(new EtchedBorder()); panel3.setBorder(new EtchedBorder()); panel4.setBorder(new EtchedBorder()); add(panel1); add(panel2); add(panel3); add(panel4); buildConstraints(constraints, 0, 0, 1, 1, 30, 0); labRivVel = new JLabel("River Velocity = " + canvas.vr + " m/s", JLabel.CENTER); gridbactx.setConstraints(labRivVel, constraints); panel1.add(labRivVel); buildConstraints(constraints, 1, 0, 1, 1, 30, 0); labBoatVel = new JLabel("Boat Velocity = " + canvas.vb + " m/s", JLabel.CENTER); gridbactx.setConstraints(labBoatVel, constraints); panel2.add(labBoatVel); buildConstraints(constraints, 2, 0, 1, 1, 30, 0); labTheta = new JLabel("Theta = " + canvas.theta + "\u00b0", JLabel.CENTER); gridbactx.setConstraints(labTheta, constraints); panel3.add(labTheta); buildConstraints(constraints, 0, 1, 1, 1, 30, 0); sbRivVel = new JSlider(0, 4, canvas.vr); gridbactx.setConstraints(sbRivVel, constraints); panel1.add(sbRivVel); sbRivVel.addChangeListener(this); buildConstraints(constraints, 1, 1, 1, 1, 30, 0); sbBoatVel = new JSlider(0, 8, canvas.vb); gridbactx.setConstraints(sbBoatVel, constraints); panel2.add(sbBoatVel); sbBoatVel.addChangeListener(this); buildConstraints(constraints, 2, 1, 1, 1, 30, 0); sbTheta = new JSlider(3, 15, 9); gridbactx.setConstraints(sbTheta, constraints); panel3.add(sbTheta); sbTheta.addChangeListener(this); buildConstraints(constraints, 4, 1, 1, 1, 30, 0); sbFrame = new JSlider(0, 100, canvas.ef); sbFrame.addChangeListener(this); // constraints.insets = new Insets(2, 2, 5, 5); gridbactx.setConstraints(sbFrame, constraints); panel4.add(sbFrame); buildConstraints(constraints, 4, 0, 1, 1, 30, 0); butSSR = new JButton("Start"); butSSR.addActionListener(this); butSSR.setActionCommand("start"); // constraints.insets = new Insets(5, 2, 2, 5); constraints.fill = GridBagConstraints.NONE; gridbactx.setConstraints(butSSR, constraints); panel4.add(butSSR); labRivVel.setMinimumSize(new Dimension(100, 20)); labRivVel.setMaximumSize(new Dimension(100, 20)); labBoatVel.setMinimumSize(new Dimension(100, 20)); labBoatVel.setMaximumSize(new Dimension(100, 20)); labTheta.setMinimumSize(new Dimension(100, 20)); labTheta.setMaximumSize(new Dimension(100, 20)); butSSR.setMinimumSize(new Dimension(100, 25)); butSSR.setMaximumSize(new Dimension(100, 25)); setBorder(new LineBorder(Color.black, 1)); // setBorder(new EtchedBorder()); } function buildConstraints(GridBagConstraints gbc, var gx, var gy, var gw, var gh, var wx, var wy) { gbc.gridx = gx; gbc.gridy = gy; gbc.gridwidth = gw; gbc.gridheight = gh; gbc.weightx = wx; gbc.weighty = wy; } function actionPerformed(ActionEvent e) { if (e.getSource() == butSSR) { if (canvas.running == false) { canvas.running = true; canvas.start(); } else { canvas.running = false; canvas.stop(); } if (e.getActionCommand().equals("stop")) { butSSR.setText("Start"); butSSR.setActionCommand("start"); } else if (e.getActionCommand().equals("start")) { butSSR.setText("Stop"); butSSR.setActionCommand("stop"); canvas.running = true; canvas.start(); } if (e.getActionCommand().equals("repeat")) { canvas.frame = 0; canvas.running = true; butSSR.setForeground(Color.black); butSSR.setText("Stop"); butSSR.setActionCommand("stop"); canvas.start(); } } } function reset() { canvas.frame = 0; canvas.ef = 0; canvas.calc(); canvas.x0 = canvas.vx == 0 ? canvas.cw / 2 : canvas.vx < 0 ? canvas.cw - 50 : 50; if (canvas.vr == 0) { canvas.x0 = 50; } canvas.running = false; canvas.bsv.setValues(canvas.vr, canvas.vb, canvas.theta); butSSR.setForeground(Color.black); butSSR.setText("Start"); butSSR.setActionCommand("start"); canvas.stop(); canvas.drawCanvas(); } function stateChanged(ChangeEvent ae) { if (sbFrame.getValueIsAdjusting()) { canvas.frame = sbFrame.getValue(); canvas.running = false; canvas.stop(); butSSR.setForeground(Color.black); butSSR.setText("Start"); butSSR.setActionCommand("start"); canvas.drawCanvas(); } if (ae.getSource() == sbRivVel) { var sbRVVal = (sbRivVel.getValue()); sbRivVel.setValue(sbRVVal); canvas.vr = sbRVVal; labRivVel.setText("River Velocity = " + canvas.vr + " m/s"); reset(); } if (ae.getSource() == sbBoatVel) { canvas.vb = sbBoatVel.getValue(); labBoatVel.setText("Boat Velocity = " + canvas.vb + " m/s"); reset(); } if (ae.getSource() == sbTheta) { var sbThetaVal = (sbTheta.getValue()); sbTheta.setValue(sbThetaVal); canvas.theta = 10 * sbThetaVal; labTheta.setText("Theta = " + canvas.theta + "\u00b0"); reset(); } if (ae.getSource() != sbFrame) { canvas.frame = 0; canvas.ef = 0; canvas.calc(); canvas.running = false; butSSR.setForeground(Color.black); butSSR.setText("Start"); butSSR.setActionCommand("start"); canvas.stop(); canvas.drawCanvas(); } } } final class RiverPnl extends JComponent implements ActionListener { Timer timer; var delay = 40; Image bi, img = Main.Launch.getJPGImageIcon("/Boat/River").getImage(); var iw = imctx.getWidth(null); var ih = imctx.getHeight(null); var cw, ch, frame, vr = 4,width; RiverPnl() { timer = new Timer(delay, this); timer.setInitialDelay(0); timer.setCoalesce(true); start(); } function setSize(var w, var h) { this.cw = w; this.ch = h; revalidate(); } function start() { if (!timer.isRunning()) { timer.start(); } } function stop() { if (timer.isRunning()) { timer.stop(); } } function actionPerformed(ActionEvent e) { frame++; drawCanvas(); } function drawCanvasBack() { width = ((cw/iw)+1)*iw; // System.out.println(cw + ", iw= " +iw+", iw/cw = "+ cw/iw+", width = "+width); bi = createImage(width, ch - 60); var x = 0, y = 0; while (y < ch - 60) { x = 0; while (x < cw) { bctx.drawImage(imctx, x, y, this); x = x + iw; } y = y + ih; } /* for (var i = 0; i < cw; i = i + iw) { bctx.moveTo(i, 0); ctx.lineTo( i, ch); } */ } function drawCanvas(Canvas canvas) { if (cw != getWidth() || ch != getHeight()) { cw = getWidth(); ch = getHeight(); drawCanvasBack(); } drawCanvasComponent(g); } function drawCanvasComponent(Canvas canvas) { ctx.strokeStyle=" ctx.setColor(new Color(0X6495ED"; ctx.fillRect(0, ch - 30, cw, 30); ctx.fillRect(0, 0, cw, 30); var xi = (2 * vr * frame); ctx.drawImage(bi, xi - width, 30, this); ctx.drawImage(bi, xi, 30, this); if (xi > width-1) { frame = 0; } } }