import java.applet.Applet; import java.awt.*; import java.awt.event.*; import Line.*; import Circle.*; public class vecnodyncirc extends Applet { /* All of the below values can be changed, and any changes will be updated further on in the code automatically. However, you must be sure that if the value is initialized as a double, the new value you assign it is also a double NOTE: Certain variables have minimum values which they shouldn't fall below. For example, the minimum x-value of the applet is 22, because the program is told not to draw anything that goes beyond that point. Therefore, if you set the initial x position to below 22, you will probably see nothing when the applet is run. The minimum and maximum x/y values are sxpos,sypos,lxpos, and lypos, and they should only be altered if you are trying to change the overall dimensions of the applet */ double x1 = 50.0; //Initial starting positions for double y1 = 100.0; //the two magnets. double x2 = 224.0; double y2 = 239.0; double bconst = .000; double q1 = -1.00; //Charges and masses for the two double q2 = 1.00; //magnets double m1 = 8.00; double m2 = 1000.00; double dt = 16.0; //Initial value for delta T int r1 = 20; //Radius of circles int r2 = 20; int dx = 20; //Initial value for delta X int sig = 1; //Initial sign value int numline = 17; //Number of magnetic field lines int ssval1 = numline; //Initial starting pos. for int ssval2 = dx/10; //the scrollbars int ssval3 = (int)q2; int width = 806; //Defines the dimensions of the int height = 496; //main canvas as variables so int ixpos = 22; //they can be easily changed int iypos = 37; int minx = 0; int maxx = 750; //Defines the min and max x and int miny = 30; //y values of the canvas, after int maxy = 470; //subtracting the north + south //borders boolean move = false; boolean drawline = false; /* The next 5 values are used to create and reference the invisible border that exists. */ int bord = 8; int sxpos = 0; int lxpos = 450; //int sxpos = (ixpos + bord); //int lxpos = (ixpos + width) - bord; int sypos = (iypos + bord); int lypos = (iypos + height) - bord; /* The rest of the variables have no preset values, so they are just initialized and then given values later on */ int xcoord, ycoord; double dist1; double dist2; double compx; double compy; double arrowlength; double arrowlength2 = 17.; double squarefunc; double angle = 30.; double radangle = angle*(Math.PI/180); double sinangle = Math.sin(radangle); double cosangle = Math.cos(radangle); double max = .0003; double r; long red; long green; long blue; double dx1; double dx2; double dy1; double dy2; Line one; // Defines a name for the Lines Circle cone, ctwo; // Defines names for the Circles /* Adds scrollbars, labels, and buttons, while at the same time assigning handles to them */ Scrollbar dxScroll = new Scrollbar(Scrollbar.HORIZONTAL,ssval2,1,1,5),q2Scroll = new Scrollbar(Scrollbar.HORIZONTAL,1,1,1,10); Label dxLabel = new Label("Speed = "+dx),q2Label = new Label("ratio charges =" +q2); Button signbutton = new Button("Reverse Sign"),resetbutton = new Button("Reset"); /* Saves the initial values as backups so they can easily be reset to the starting values if neccasery */ double bx1 = x1; double by1 = y1; double bx2 = x2; double by2 = y2; double bq1 = q1; double bq2 = q2; double bm1 = m1; double bm2 = m2; int bdx = dx; int br2 = r2; int br1 = r1; int bsig = sig; int bnumline = numline; public void init() { setBackground(Color.white); /*Sets up the background and foreground colors for both the buttons and the scrollbars */ signbutton.setForeground(Color.black); signbutton.setBackground(Color.lightGray); resetbutton.setForeground(Color.black); resetbutton.setBackground(Color.lightGray); dxScroll.setForeground(Color.black); dxScroll.setBackground(Color.lightGray); q2Scroll.setForeground(Color.black); q2Scroll.setBackground(Color.lightGray); /*Creates a new layout manager, and groups the buttons and scrollbars into panels, which are then placed on the North and South sectors of the applet. */ setLayout(new BorderLayout()); Panel p = new Panel(); p.setLayout(new FlowLayout(FlowLayout.CENTER)); p.add(signbutton); p.add(resetbutton); add("North",p); Panel t = new Panel(); t.setLayout(new FlowLayout(FlowLayout.CENTER)); t.add(dxScroll); t.add(dxLabel); t.add(q2Scroll); t.add(q2Label); add("South",t); /*Draws lines and circles using the syntax defined in their respective classes */ one = new Line(0.0,0.0,0.0,0.0); cone = new Circle(0,r1,(int)x1,(int)y1); ctwo = new Circle(0,r2,(int)x2,(int)y2); } public void update(Graphics g) { /*Overrides the update function to only redraw specified graphics */ if(move == true) { paint(g,one,cone, ctwo); move = false; } if(drawline == true) { drawline(g,one); } } public void paint(Graphics g) { paint(g,one,cone,ctwo); } public void paint(Graphics g,Line line,Circle circ, Circle circl) { /*Fills the main drawing canvas with black and then draws four white borders around the new drawn area. In order to make this fully customizable, the drawing uses variables defined in the beginning. */ g.setColor(Color.white); g.fillRect(ixpos,iypos,width,height); g.setColor(Color.white); g.fillRect(minx,miny,ixpos,(maxy-miny)); g.fillRect(ixpos,miny,width,(iypos - miny)); g.fillRect((ixpos + width),miny,(maxx - (ixpos + width)),(maxy - miny)); g.fillRect(ixpos,(iypos + height),width,(maxy - (iypos + height))); /* Does all of the calculations neccasery to make the magnets attract and repel eachother, and then draws the magnets */ x1 = circ.cx; y1 = circ.cy; circ.cx = (int)x1; circ.cy = (int)y1; circ.sx = (int)(x1 - r1/2); circ.sy = (int)(y1 - r1/2); x2 = circl.cx; y2 = circl.cy; circl.cx = (int)x2; circl.cy = (int)y2; circl.sx = (int)(x2 - r2/2); circl.sy = (int)(y2 - r2/2); /*Changes the color from black to a light blue, and then draws the magnetic field lines originating in the second magnet(m2+q2) using variables defined in the circle and line classes. */ g.setColor(new Color(26,103,244)); // draw vector field int ix=0; int iy=0; int numy; int numx; numx=2+ width/dx; numy=2+ height/dx; while(ix255) {red=255;} if(green>255) {green=255;} if(blue>255) {blue=255;} if(red<0) {red=0;} if(green<0) {green=0;} if(blue<0) {blue=0;} arrowlength = dx/6; line.ey = line.sy + (compy/line.emag) * dx/2.; line.ex = line.sx + dx*(compx/line.emag)/2.; dy1 = 1*(arrowlength*((sinangle*compx-cosangle*compy)/squarefunc)); dx1 = -1*(arrowlength*((cosangle*compx+sinangle*compy)/squarefunc)); dy2 = 1*(arrowlength*((-sinangle*compx-cosangle*compy)/squarefunc)); dx2 = -1*(arrowlength*((cosangle*compx-sinangle*compy)/squarefunc)); g.setColor(new Color((int)red,(int)green,(int)blue)); g.drawLine((int)line.sx, (int)line.sy, (int)line.ex, (int)line.ey); g.drawLine((int)line.ex, (int)line.ey, (int)(line.ex + dx1),(int)(line.ey + dy1)); g.drawLine((int)line.ex, (int)line.ey, (int)(line.ex + dx2),(int)(line.ey + dy2)); iy++; } ix++; iy=0; } g.setColor(Color.red); g.fillOval(circl.sx,circl.sy,r2,r2); if(q1<0) { g.setColor(Color.black); } g.fillOval(circ.sx,circ.sy,r1,r1); repaint(); } public void drawline(Graphics g,Line line) { line.sx = xcoord; line.sy = ycoord; dist1 = Math.sqrt(Math.pow(line.sx-x2, 2) + Math.pow(line.sy-y2, 2)); dist2 = Math.sqrt(Math.pow(line.sx-x1, 2) + Math.pow(line.sy-y1, 2)); int ilinc = 0; while(dist1 > 5.0 && dist2 > 5. && dist1 < 1000 && dist2 < 1000) { dist1 = Math.sqrt(Math.pow(line.sx-x2, 2) + Math.pow(line.sy-y2, 2)); dist2 = Math.sqrt(Math.pow(line.sx-x1, 2) + Math.pow(line.sy-y1, 2)); compx = q2*(line.sx - x2) / Math.pow(dist1,3) + q1*(line.sx - x1) / Math.pow(dist2,3); compy = q2*(line.sy - y2) / Math.pow(dist1,3) + q1*(line.sy - y1) / Math.pow(dist2,3)+bconst; line.emag = Math.sqrt(Math.pow(compx,2) + Math.pow(compy,2)); line.ey = line.sy + (compy/line.emag) * dx/5; line.ex = line.sx + dx*(compx/line.emag)/5; g.setColor(new Color(0,190,0)); g.drawLine((int)line.sx, (int)line.sy, (int)line.ex, (int)line.ey); // draw arrow head if (ilinc>10) { double vey,vex; vey = line.sy ; vex = line.sx ; dy1 = 1*(arrowlength2*((sinangle*compx-cosangle*compy)/line.emag)); dx1 = -1*(arrowlength2*((cosangle*compx+sinangle*compy)/line.emag)); dy2 = 1*(arrowlength2*((-sinangle*compx-cosangle*compy)/line.emag)); dx2 = -1*(arrowlength2*((cosangle*compx-sinangle*compy)/line.emag)); g.drawLine((int)vex, (int)vey, (int)(vex + dx1),(int)(vey + dy1)); g.drawLine((int)vex, (int)vey, (int)(vex + dx2),(int)(vey + dy2)); ilinc=0; } // line.sx = line.ex; line.sy = line.ey; ilinc++; } line.sx = xcoord; line.sy = ycoord; dist1 = Math.sqrt(Math.pow(line.sx-x2, 2) + Math.pow(line.sy-y2, 2)); dist2 = Math.sqrt(Math.pow(line.sx-x1, 2) + Math.pow(line.sy-y1, 2)); ilinc=0; while(dist1 > 5.0 && dist2 > 5. && dist1 < 1000 && dist2 < 1000) { dist1 = Math.sqrt(Math.pow(line.sx-x2, 2) + Math.pow(line.sy-y2, 2)); dist2 = Math.sqrt(Math.pow(line.sx-x1, 2) + Math.pow(line.sy-y1, 2)); compx = -1.*(q2*(line.sx - x2) / Math.pow(dist1,3) + q1*(line.sx - x1) / Math.pow(dist2,3)); compy = -1.*(q2*(line.sy - y2) / Math.pow(dist1,3) + q1*(line.sy - y1) / Math.pow(dist2,3)+bconst); line.emag = Math.sqrt(Math.pow(compx,2) + Math.pow(compy,2)); line.ey = line.sy + (compy/line.emag) * dx/5; line.ex = line.sx + dx*(compx/line.emag)/5; g.setColor(new Color(0,190,0)); g.drawLine((int)line.sx, (int)line.sy, (int)line.ex, (int)line.ey); // draw arrow head if (ilinc>10) { double vey,vex; vey = line.sy ; vex = line.sx ; dy1 = -1*(arrowlength2*((sinangle*compx-cosangle*compy)/line.emag)); dx1 = 1*(arrowlength2*((cosangle*compx+sinangle*compy)/line.emag)); dy2 = -1*(arrowlength2*((-sinangle*compx-cosangle*compy)/line.emag)); dx2 = 1*(arrowlength2*((cosangle*compx-sinangle*compy)/line.emag)); g.drawLine((int)vex, (int)vey, (int)(vex + dx1),(int)(vey + dy1)); g.drawLine((int)vex, (int)vey, (int)(vex + dx2),(int)(vey + dy2)); ilinc=0; } // line.sx = line.ex; line.sy = line.ey; ilinc++; } drawline = false; } public boolean mouseMove(Event e, int x, int y) { /*Defines the xcoord and ycoord variables in terms of the x/y values of the object being moved */ xcoord = x; ycoord = y; return true; } public boolean deterHit(Circle circ, int mx, int my) { /*Tells the program how to decide if an object is being selected or not. */ if (mx > circ.cx - r1 && mx < circ.cx + r1 && my > circ.cy - r1 && my < circ.cy + r1) { return true; } return false; } public boolean mouseDown(Event e, int x, int y) { if (deterHit(cone,x,y)) {cone.hit = 1; } if (deterHit(ctwo,x,y)) {ctwo.hit = 1; } else { xcoord = x; ycoord = y; drawline = true; move=false; repaint(); } return true; } public boolean mouseUp(Event e, int x, int y) { cone.hit = 0; ctwo.hit = 0; move = false; return true; } public boolean mouseDrag(Event e, int x, int y) { xcoord = x; ycoord = y; if (cone.hit == 1) {cone.cx = x; cone.cy = y; repaint(); } if (ctwo.hit == 1) {ctwo.cx = x; ctwo.cy = y; repaint(); } move = true; return true; } public boolean handleEvent(Event e) { Object target=e.target; if(target==dxScroll) { dx = 10*dxScroll.getValue(); dxLabel.setText("Speed = " + dx); move = true; repaint(); } else if(target==q2Scroll) { q2 = (double)q2Scroll.getValue(); q2Label.setText("ratio charges =" + q2); move = true; repaint(); } if (e.id==Event.ACTION_EVENT) { if(target==signbutton) { sig = (-1*sig); q1 = (-1.0 * q1); move = true; repaint(); } else if(target==resetbutton) { cone.hit = 0; ctwo.hit = 0; x1 = bx1; y1 = by1; x2 = bx2; y2 = by2; cone.cx = (int)bx1; cone.cy = (int)by1; ctwo.cx = (int)bx2; ctwo.cy = (int)by2; q1 = bq1; q2 = bq2; sig = bsig; numline = bnumline; dx = bdx; dxScroll.setValue(ssval2); q2Scroll.setValue(ssval3); dxLabel.setText("Delta X = " + dx); q2Label.setText("ratio charges =" + q2); move = true; repaint(); } } return super.handleEvent(e); } }