Beispiel #1
0
 void drawLine(Graphics g, DrawObject L) {
   if (L == null) {
     return;
   }
   if ((sequencingOn) && (L.sequenceNum != currentSequenceNumDisplay)) {
     return;
   }
   Graphics2D g2 = (Graphics2D) g;
   g2.setStroke(L.drawStroke);
   int x1 = (int) ((L.x - minX) / (maxX - minX) * (D.width - 2 * inset));
   int y1 = (int) ((L.y - minY) / (maxY - minY) * (D.height - 2.0 * inset));
   int x2 = (int) ((L.x2 - minX) / (maxX - minX) * (D.width - 2 * inset));
   int y2 = (int) ((L.y2 - minY) / (maxY - minY) * (D.height - 2.0 * inset));
   if (L.isArrow) {
     drawArrow(
         (Graphics2D) g,
         inset + x1,
         D.height - y1 - inset,
         inset + x2,
         D.height - y2 - inset,
         1.0f,
         L.drawStroke);
   } else {
     g.drawLine(inset + x1, D.height - y1 - inset, inset + x2, D.height - y2 - inset);
   }
 }
  public void draw(Graphics g) {
    animate();

    g.setColor(Color.black);
    g.fillRect(0, 0, dim.width, dim.height);
    g.setColor(Color.white);

    numpaint++;
    DebugPrinter dbg = new DebugPrinter(g, 50, 60);
    dbg.print(
        "Spring-mass demo by yigal irani, drag balls or create new ones by clicking inside box");
    dbg.print("frame", numpaint);
    dbg.print("fps", 1 / timer.time_diff);

    Point top_left = point_by_vec(new Vec(-1, 1));
    g.draw3DRect(top_left.x, top_left.y, screen_dist(2), screen_dist(2), true);
    for (int i = 0; i < springs.size(); i++) {
      Spring spring = springs.get2(i);
      Point p1 = point_by_vec(balls.get2(spring.start).pos);
      Point p2 = point_by_vec(balls.get2(spring.end).pos);
      g.drawLine(p1.x, p1.y, p2.x, p2.y);
    }
    for (int i = 0; i < balls.size(); i++) {
      Ball ball = balls.get2(i);
      Point p = point_by_vec(ball.pos);
      int screen_radius = screen_dist(RADIUS);
      g.setColor(Color.blue);
      g.fillOval(p.x - screen_radius, p.y - screen_radius, screen_radius * 2, screen_radius * 2);

      g.setColor(Color.white);
      g.drawOval(p.x - screen_radius, p.y - screen_radius, screen_radius * 2, screen_radius * 2);

      g.drawString("" + i, p.x, p.y);
    }
  }
Beispiel #3
0
  /**
   * Called by the paint method to draw the graph and its graph items.
   *
   * @param g the graphics context.
   */
  public void paintComponent(Graphics g) {

    Dimension dim = getSize();
    Insets insets = getInsets();
    dataArea =
        new Rectangle(
            insets.left,
            insets.top,
            dim.width - insets.left - insets.right - 1,
            dim.height - insets.top - insets.bottom - 1);
    // background
    if (isOpaque()) {
      g.setColor(getBackground());
      g.fillRect(0, 0, dim.width, dim.height);
    }
    g.setColor(getForeground());
    // get axis tickmarks
    double xticks[] = xAxis.getTicks();
    double yticks[] = yAxis.getTicks();
    int yb = dataArea.y + dataArea.height;
    // draw grid
    if (showGrid) {
      g.setColor(gridColor != null ? gridColor : getBackground().darker());
      // vertical x grid lines
      for (int i = 0; i < xticks.length; i += 2) {
        int x = dataArea.x + (int) Math.round(xticks[i]);
        g.drawLine(x, dataArea.y, x, dataArea.y + dataArea.height);
      }
      // horizontal y grid lines
      for (int i = 0; i < yticks.length; i += 2) {
        int y = yb - (int) Math.round(yticks[i]);
        g.drawLine(dataArea.x, y, dataArea.x + dataArea.width, y);
      }
    }
    for (int i = 0; i < graphItems.size(); i++) {
      ((GraphItem) graphItems.elementAt(i)).draw(this, g, dataArea, xAxis, yAxis);
    }
    if (sPt != null && ePt != null) {
      g.setColor(getForeground());
      g.drawRect(
          Math.min(sPt.x, ePt.x), Math.min(sPt.y, ePt.y),
          Math.abs(ePt.x - sPt.x), Math.abs(ePt.y - sPt.y));
    }
  }
 public static void drawLine(Graphics g, int x1, int y1, int x2, int y2, int lineWidth) {
   if (lineWidth == 1) g.drawLine(x1, y1, x2, y2);
   else {
     double angle;
     double halfWidth = ((double) lineWidth) / 2.0;
     double deltaX = (double) (x2 - x1);
     double deltaY = (double) (y2 - y1);
     if (x1 == x2) angle = Math.PI;
     else angle = Math.atan(deltaY / deltaX) + Math.PI / 2;
     int xOffset = (int) (halfWidth * Math.cos(angle));
     int yOffset = (int) (halfWidth * Math.sin(angle));
     int[] xCorners = {x1 - xOffset, x2 - xOffset + 1, x2 + xOffset + 1, x1 + xOffset};
     int[] yCorners = {y1 - yOffset, y2 - yOffset, y2 + yOffset + 1, y1 + yOffset + 1};
     g.fillPolygon(xCorners, yCorners, 4);
   }
 }
Beispiel #5
0
  /** This internal method begins a new page and prints the header. */
  protected void newpage() {
    page = job.getGraphics(); // Begin the new page
    linenum = 0;
    charnum = 0; // Reset line and char number
    pagenum++; // Increment page number
    page.setFont(headerfont); // Set the header font.
    page.drawString(jobname, x0, headery); // Print job name left justified

    String s = "- " + pagenum + " -"; // Print the page number centered.
    int w = headermetrics.stringWidth(s);
    page.drawString(s, x0 + (this.width - w) / 2, headery);
    w = headermetrics.stringWidth(time); // Print date right justified
    page.drawString(time, x0 + width - w, headery);

    // Draw a line beneath the header
    int y = headery + headermetrics.getDescent() + 1;
    page.drawLine(x0, y, x0 + width, y);

    // Set the basic monospaced font for the rest of the page.
    page.setFont(font);
  }
Beispiel #6
0
 void drawScribbles(Graphics g) {
   if ((scribbles == null) || (scribbles.size() == 0)) {
     return;
   }
   DrawObject L = (DrawObject) scribbles.get(0);
   int scribbleCounter = L.scribbleNum;
   g.setColor(scribbleColor);
   ((Graphics2D) g).setStroke(new BasicStroke(2f));
   int prevX = L.scribbleX;
   int prevY = L.scribbleY;
   for (int i = 1; i < scribbles.size(); i++) {
     L = (DrawObject) scribbles.get(i);
     if (L.scribbleNum == scribbleCounter) {
       // Keep drawing.
       g.drawLine(prevX, prevY, L.scribbleX, L.scribbleY);
       prevX = L.scribbleX;
       prevY = L.scribbleY;
     } else {
       scribbleCounter = L.scribbleNum;
       prevX = L.scribbleX;
       prevY = L.scribbleY;
     }
   }
 }
Beispiel #7
0
  void drawEqnLine(Graphics g, DrawObject L) {
    if (L == null) {
      return;
    }
    if ((sequencingOn) && (L.sequenceNum != currentSequenceNumDisplay)) {
      return;
    }
    // First, special cases:
    if ((L.a == 0) && (L.b == 0)) {
      return;
    }
    double px = 0, py = 0, qx = 0, qy = 0;
    double leftX = px, rightX = qx, leftY = py, rightY = qy;
    if (L.a == 0) {
      // Case 2: a=0 => horizontal line.
      leftX = minX;
      rightX = maxX;
      py = -L.c / L.b;
      qy = -L.c / L.b;
      if ((py < minY) || (py > maxY)) {
        // Cannot display.
        return;
      }
      leftY = rightY = py;
    } else if (L.b == 0) {
      // Case 3: b=0 => vertical line.
      leftX = -L.c / L.a;
      rightX = -L.c / L.a;
      leftY = minY;
      rightY = maxY;
      if ((leftX < minX) || (leftX > maxX)) {
        return;
      }
    } else {
      // Case 4: regular.
      // Note: the line could intersect the drawable region in weird ways.
      px = (-L.c - L.b * minY) / L.a;
      qx = (-L.c - L.b * maxY) / L.a;
      py = (-L.c - L.a * minX) / L.b;
      qy = (-L.c - L.a * maxX) / L.b;
      // System.out.println ("px=" + px + " qx=" + qx + " py=" + py + " qy=" + qy);
      // Find leftmost point to draw.
      if ((py >= minY) && (py <= maxY)) {
        // Leftmost point is on the x=minX line.
        leftX = minX;
        leftY = py;
        // System.out.println ("case(a): leftmost on minX-line");
      } else {
        // Leftmost point is not on the x=minX line.
        // Find leftmost point intersecting with low or high
        if (px < qx) {
          leftX = px;
          leftY = minY;
          // System.out.println ("case(a.1): on minY-line");
        } else {
          leftX = qx;
          leftY = maxY;
          // System.out.println ("case(a.2): on maxY-line");
        }
      }

      // Now find rightmost point.
      if ((qy >= minY) && (qy <= maxY)) {
        // Rightmost point is on the x=maxX line.
        rightX = maxX;
        rightY = qy;
        // System.out.println ("case(b): rightmost on maxX-line");
      } else {
        if (px > qx) {
          rightX = px;
          rightY = minY;
          // System.out.println ("case(b.1): rightmost on minY-line");
        } else {
          rightX = qx;
          rightY = maxY;
          // System.out.println ("case(b.1): rightmost on maxY-line");
        }
      }
    }

    // System.out.println ("left:(" + leftX + "," + leftY + ")  right:(" + rightX + "," + rightY +
    // ")");

    int x1 = (int) ((leftX - minX) / (maxX - minX) * (D.width - 2 * inset));
    int y1 = (int) ((leftY - minY) / (maxY - minY) * (D.height - 2.0 * inset));
    int x2 = (int) ((rightX - minX) / (maxX - minX) * (D.width - 2 * inset));
    int y2 = (int) ((rightY - minY) / (maxY - minY) * (D.height - 2.0 * inset));
    Graphics2D g2 = (Graphics2D) g;
    g2.setStroke(L.drawStroke);
    g.drawLine(inset + x1, D.height - y1 - inset, inset + x2, D.height - y2 - inset);
  }
Beispiel #8
0
  public void paintComponent(Graphics g) {
    super.paintComponent(g);

    Graphics2D g2d = (Graphics2D) g;
    RenderingHints rh = g2d.getRenderingHints();
    rh.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    rh.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    g2d.setRenderingHints(rh);

    // Background.
    D = this.getSize();
    g.setColor(backgroundColor);
    g.fillRect(0, 0, D.width, D.height);
    Graphics2D g2 = (Graphics2D) g;
    g2.setStroke(lineStroke);

    // Axes, bounding box.
    g.setColor(Color.gray);
    g.drawLine(inset, D.height - inset, D.width - inset, D.height - inset);
    g.drawLine(D.width - inset, inset, D.width - inset, D.height - inset);
    g.drawLine(inset, inset, inset, D.height - inset);
    g.drawLine(inset, inset, D.width - inset, inset);

    double xDelta = (maxX - minX) / numIntervals;

    // X-ticks and labels.
    for (int i = 1; i <= numIntervals; i++) {
      double xTickd = i * xDelta;
      int xTick = (int) (xTickd / (maxX - minX) * (D.width - 2 * inset));
      g.drawLine(inset + xTick, D.height - inset - 5, inset + xTick, D.height - inset + 5);
      double x = minX + i * xDelta;
      g.drawString(df.format(x), xTick + inset - 5, D.height - inset + 20);
    }

    // Y-ticks
    double yDelta = (maxY - minY) / numIntervals;
    for (int i = 0; i < numIntervals; i++) {
      int yTick = (i + 1) * (int) ((D.height - 2 * inset) / (double) numIntervals);
      g.drawLine(inset - 5, D.height - yTick - inset, inset + 5, D.height - yTick - inset);
      double y = minY + (i + 1) * yDelta;
      g.drawString(df.format(y), 1, D.height - yTick - inset);
    }

    // Zoom+move
    Font savedFont = g.getFont();
    g.setFont(plusFont);
    g.drawString("+", D.width - 25, 20);
    g.setFont(minusFont);
    g.drawString("-", D.width - 25, 50);
    drawArrow(g2d, D.width - 70, 20, D.width - 70, 0, 1.0f, lineStroke); // Up
    drawArrow(g2d, D.width - 70, 30, D.width - 70, 50, 1.0f, lineStroke); // Down
    drawArrow(g2d, D.width - 65, 25, D.width - 45, 25, 1.0f, lineStroke); // Right
    drawArrow(g2d, D.width - 75, 25, D.width - 95, 25, 1.0f, lineStroke); // Left
    g.setFont(savedFont);

    // See if standard axes are in the middle.
    g.setColor(Color.gray);
    if ((minX < 0) && (maxX > 0) && (drawMiddleAxes)) {
      // Draw y-axis
      int x = (int) ((0 - minX) / (maxX - minX) * (D.width - 2 * inset));
      g.drawLine(inset + x, D.height - inset, inset + x, inset);
    }
    if ((minY < 0) && (maxY > 0) && (drawMiddleAxes)) {
      // Draw x-axis
      int y = (int) ((0 - minY) / (maxY - minY) * (D.height - 2.0 * inset));
      g.drawLine(inset, D.height - y - inset, D.width - inset, D.height - y - inset);
    }

    // Draw the objects.
    drawObjects(g, points, lines, ovals, rectangles, images, labels, eqnLines);
    if (animationMode) {
      drawObjects(g, animPoints, animLines, animOvals, animRectangles, null, labels, eqnLines);
      // No images in animation mode.
    }

    drawScribbles(g);
  }
Beispiel #9
0
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.WHITE);
    // Draws a white arrow and the principal axis
    g.drawLine(0, 200, 700, 200);
    g.drawLine(arrow_x, 200, arrow_x, arrow_y2);

    // Show coordinates of arrow tip
    arrowCoordinate_x = arrow_x - startingPosition;
    arrowCoordinate_x /= 10;
    arrowCoordinate_y = 200 - arrow_y2;
    arrowCoordinate_y /= 10;

    // Coordinates
    Optics.lbl_arrowCoordinates.setText(
        "<html>(d<sub>o</sub>, h<sub>o</sub>) = ("
            + arrowCoordinate_x
            + ", "
            + arrowCoordinate_y
            + ")</html>");

    if (arrow_y2 < 200) // if arrow is above principal axis
    {
      g.drawLine(arrow_x, arrow_y2, arrow_x - 7, arrow_y2 + 7);
      g.drawLine(arrow_x, arrow_y2, arrow_x + 7, arrow_y2 + 7);
    } else if (arrow_y2 > 200) // if arrow is below principal axis
    {
      g.drawLine(arrow_x, arrow_y2, arrow_x - 7, arrow_y2 - 7);
      g.drawLine(arrow_x, arrow_y2, arrow_x + 7, arrow_y2 - 7);
    }
    // Draws lines for the grid
    if (lenses) startingPosition = 350;
    else {
      radiusOfCurvature = 20 * focalLength;
      if (type == 0) startingPosition = 500;
      else startingPosition = 350;
    }
    {
      for (int i = startingPosition; i <= 700; i += 10) {
        if ((i - startingPosition) % (10 * focalLength) == 0) {
          g.setColor(Color.ORANGE);
          g.drawLine(i, 195, i, 205);
        } else {
          g.setColor(Color.WHITE);
          g.drawLine(i, 197, i, 203);
        }
      }
      for (int i = startingPosition; i >= 0; i -= 10) {
        if ((i - startingPosition) % (10 * focalLength) == 0 && i != 0) {
          g.setColor(Color.ORANGE);
          g.drawLine(i, 195, i, 205);
        } else {
          g.setColor(Color.WHITE);
          g.drawLine(i, 197, i, 203);
        }
      }
    }
    g.setColor(Color.WHITE);

    if (lenses) {
      if (type == 0) // If Converging
      {
        // Draws a converging lens
        g.drawArc(340, 50, 40, 300, 120, 120);
        g.drawArc(320, 50, 40, 300, 60, -120);
        // draws horizontal line from the tip of the arrow to the lens (line 1/3)
        g.setColor(Color.RED);
        g.drawLine(arrow_x, arrow_y2, 350, arrow_y2);
        // calculates necessary information to form equation of line from lens to focal point (line
        // 2/3)

        dy_1 = 200 - arrow_y2;

        if (arrow_x > 350) dx_1 = -10 * focalLength;
        else dx_1 = 10 * focalLength;
        slope_1 = dy_1 / dx_1;

        if (arrow_x > 350) y_intercept_1 = 200 - slope_1 * (350 - 10 * focalLength);
        else y_intercept_1 = 200 - slope_1 * (10 * focalLength + 350);
        // Calculates coordinates of points on the edge of screen (endpoints)
        if (arrow_x <= 350)
          y_screenIntersection_1 = (int) (Math.round(slope_1 * 700 + y_intercept_1));
        else y_screenIntersection_1 = (int) (Math.round(y_intercept_1));
        if (slope_1 != 0)
          if (arrow_y2 <= 200)
            x_screenIntersection_1 = (int) (Math.round((400 - y_intercept_1) / slope_1));
          else x_screenIntersection_1 = (int) (Math.round(-y_intercept_1 / slope_1));
        if (x_screenIntersection_1 >= 0
            && x_screenIntersection_1 <= 700) // If endpoint is on the x-edge
        if (arrow_y2 <= 200) g.drawLine(350, arrow_y2, x_screenIntersection_1, 400);
          else g.drawLine(350, arrow_y2, x_screenIntersection_1, 0);
        else if (arrow_x > 350) g.drawLine(350, arrow_y2, 0, y_screenIntersection_1);
        else
          g.drawLine(350, arrow_y2, 700, y_screenIntersection_1); // Else: endpoint is on the y-edge
      } else // Else: Diverging
      {
        // Draws a diverging lens
        g.drawArc(360, 50, 40, 300, 120, 120);
        g.drawArc(300, 50, 40, 300, 60, -120);
        g.drawLine(330, 68, 370, 68);
        g.drawLine(330, 330, 370, 330);

        // draws horizontal line from the tip of the arrow to the lens (line 1/3)
        g.setColor(Color.RED);
        g.drawLine(arrow_x, arrow_y2, 350, arrow_y2);

        // calculates necessary information to form equation of line from lens to focal point (line
        // 2/3)

        dy_1 = arrow_y2 - 200;

        if (arrow_x > 350) dx_1 = -10 * focalLength;
        else dx_1 = 10 * focalLength;
        slope_1 = dy_1 / dx_1;

        if (arrow_x > 350) y_intercept_1 = 200 - slope_1 * (10 * focalLength + 350);
        else y_intercept_1 = 200 - slope_1 * (350 - 10 * focalLength);
        // Calculates coordinates of points on the edge of screen (endpoints)
        if (arrow_x <= 350)
          y_screenIntersection_1 = (int) (Math.round(slope_1 * 700 + y_intercept_1));
        else y_screenIntersection_1 = (int) (Math.round(y_intercept_1));
        if (slope_1 != 0)
          if (arrow_y2 <= 200)
            x_screenIntersection_1 = (int) (Math.round(-y_intercept_1 / slope_1));
          else x_screenIntersection_1 = (int) (Math.round((400 - y_intercept_1) / slope_1));
        if (x_screenIntersection_1 >= 0
            && x_screenIntersection_1 <= 700) // If endpoint is on the x-edge
        if (arrow_y2 <= 200) g.drawLine(350, arrow_y2, x_screenIntersection_1, 0);
          else g.drawLine(350, arrow_y2, x_screenIntersection_1, 400);
        else // Else: endpoint is on the y-edge
        if (arrow_x > 350) g.drawLine(350, arrow_y2, 0, y_screenIntersection_1);
        else g.drawLine(350, arrow_y2, 700, y_screenIntersection_1);
      }
      // Line 3/3
      dy_2 = 200 - arrow_y2;
      dx_2 = 350 - arrow_x;
      slope_2 = dy_2 / dx_2;
      y_intercept_2 = 200 - slope_2 * 350;
      if (arrow_x <= 350)
        y_screenIntersection_2 = (int) (Math.round(slope_2 * 700 + y_intercept_2));
      else y_screenIntersection_2 = (int) (Math.round(y_intercept_2));
      if (slope_2 != 0)
        if (arrow_y2 <= 200)
          x_screenIntersection_2 = (int) (Math.round((400 - y_intercept_2) / slope_2));
        else x_screenIntersection_2 = (int) (Math.round(-y_intercept_2 / slope_2));

      if (x_screenIntersection_2 >= 0
          && x_screenIntersection_2 <= 700) // If endpoint is on the x-edge
      if (arrow_y2 <= 200) g.drawLine(arrow_x, arrow_y2, x_screenIntersection_2, 400);
        else g.drawLine(arrow_x, arrow_y2, x_screenIntersection_2, 0);
      else if (arrow_x <= 350)
        g.drawLine(
            arrow_x, arrow_y2, 700, y_screenIntersection_2); // Else: endpoint is on the y-edge
      else g.drawLine(arrow_x, arrow_y2, 0, y_screenIntersection_2);

      // POI between Line 2 & Line 3
      x_pointOfIntersection = (int) ((y_intercept_2 - y_intercept_1) / (slope_1 - slope_2));
      y_pointOfIntersection = (int) (slope_1 * x_pointOfIntersection + y_intercept_1);
      // Draw image
      g.setColor(Color.ORANGE);
      g.drawLine(x_pointOfIntersection, 200, x_pointOfIntersection, y_pointOfIntersection);
      if (y_pointOfIntersection < 200) {
        g.drawLine(
            x_pointOfIntersection,
            y_pointOfIntersection,
            x_pointOfIntersection - 7,
            y_pointOfIntersection + 7);
        g.drawLine(
            x_pointOfIntersection,
            y_pointOfIntersection,
            x_pointOfIntersection + 7,
            y_pointOfIntersection + 7);
      } else {
        g.drawLine(
            x_pointOfIntersection,
            y_pointOfIntersection,
            x_pointOfIntersection - 7,
            y_pointOfIntersection - 7);
        g.drawLine(
            x_pointOfIntersection,
            y_pointOfIntersection,
            x_pointOfIntersection + 7,
            y_pointOfIntersection - 7);
      }
      // Same side image line continuation
      if (((x_pointOfIntersection > 350 && arrow_x > 350)
              || (x_pointOfIntersection < 350 && arrow_x < 350))
          && (arrow_x != 350 - 10 * focalLength && arrow_x != 350 + 10 * focalLength
              || type == 1)) {
        g.setColor(Color.YELLOW);
        g.drawLine(x_pointOfIntersection, y_pointOfIntersection, 350, arrow_y2);
        if (type == 0) g.drawLine(x_pointOfIntersection, y_pointOfIntersection, arrow_x, arrow_y2);
      }

      // Mag calculations
      height_image = 200 - y_pointOfIntersection;
      height_object = 200 - arrow_y2;
      if (height_object != 0) magnification = height_image / height_object;

      if (magnification <= 9999 && magnification >= -9999)
        Optics.txt_magnification.setText("" + roundTwoDecimals(magnification));
      else if (magnification > 9999) {
        magnification = Double.POSITIVE_INFINITY;
        Optics.txt_magnification.setText("N/A");
      } else {
        magnification = Double.NEGATIVE_INFINITY;
        Optics.txt_magnification.setText("N/A");
      }
      // Characteristics
      g.setColor(Color.ORANGE);
      g.drawString("Image Characteristics:", 20, 300);
      if (type == 0) {
        if ((Math.abs(magnification) > 1 && Math.abs(magnification) < 9999))
          g.drawString("Magnification:  Enlarged", 20, 320);
        else if (arrow_x == 350 - 20 * focalLength
            || arrow_x == 350 + 20 * focalLength
            || (int) (Math.abs(magnification)) == 1) g.drawString("Magnification:  None", 20, 320);
        else if (Math.abs(magnification) < 1 && Math.abs(magnification) > 0)
          g.drawString("Magnification:  Diminished", 20, 320);
        else g.drawString("Magnification:  N/A", 20, 320);
        if (arrow_x == 350 - 10 * focalLength || arrow_x == 350 + 10 * focalLength)
          g.drawString("Orientation:      N/A", 20, 335);
        else if ((arrow_y2 < 200 && y_pointOfIntersection < 200)
            || (arrow_y2 > 200 && y_pointOfIntersection > 200))
          g.drawString("Orientation:      Upright", 20, 335);
        else g.drawString("Orientation:      Inverted", 20, 335);
        if (arrow_x == 350 - 10 * focalLength || arrow_x == 350 + 10 * focalLength)
          g.drawString("Type:                 N/A", 20, 350);
        else if ((x_pointOfIntersection < 350 && arrow_x < 350)
            || (x_pointOfIntersection > 350 && arrow_x > 350))
          g.drawString("Type:                 Virtual", 20, 350);
        else g.drawString("Type:                 Real", 20, 350);
      } else {
        g.drawString("Magnification:  Diminished", 20, 320);
        g.drawString("Orientation:      Upright", 20, 335);
        g.drawString("Type:                 Virtual", 20, 350);
      }

      height_image /= 10;

      if (height_image > 9999 || height_image < -9999)
        Optics.lbl_heightImage.setText("<html>h<sub>i</sub>= N/A</html>");
      else Optics.lbl_heightImage.setText("<html>h<sub>i</sub>= " + height_image + "</html>");

      distance_image = x_pointOfIntersection - 350;
      distance_image /= 10;
      if (distance_image > 9999 || distance_image < -9999)
        Optics.lbl_distanceImage.setText("<html>d<sub>i</sub>= N/A</html>");
      else Optics.lbl_distanceImage.setText("<html>d<sub>i</sub>= " + distance_image + "</html>");
    } else // Else: mirrors
    {

      if (type == 0) // If converging
      {
        // draws converging mirror
        g.drawArc(
            500 - 2 * radiusOfCurvature,
            200 - radiusOfCurvature,
            2 * radiusOfCurvature,
            2 * radiusOfCurvature,
            60,
            -120);
        // draws horizontal line from the tip of the arrow to the lens (line 1/4)
        g.setColor(Color.RED);
        x_arcIntersection_1 =
            (int)
                ((Math.sqrt(Math.abs(Math.pow(radiusOfCurvature, 2) - Math.pow(arrow_y2 - 200, 2))))
                    + (500 - radiusOfCurvature));
        g.drawLine(arrow_x, arrow_y2, x_arcIntersection_1, arrow_y2);

        // line 2/4
        dy_1 = arrow_y2 - 200;
        dx_1 = x_arcIntersection_1 - (500 - focalLength * 10);
        slope_1 = dy_1 / dx_1;
        y_intercept_1 = 200 - slope_1 * (500 - focalLength * 10);

        // Calculates coordinates of points on the edge of screen (endpoints)
        y_screenIntersection_1 = (int) (Math.round(y_intercept_1));
        if (slope_1 != 0)
          if (arrow_y2 <= 200)
            x_screenIntersection_1 = (int) (Math.round((400 - y_intercept_1) / slope_1));
          else x_screenIntersection_1 = (int) (Math.round(-y_intercept_1 / slope_1));
        if (x_screenIntersection_1 >= 0
            && x_screenIntersection_1 <= 700) // If endpoint is on the x-edge
        if (arrow_y2 <= 200) g.drawLine(x_arcIntersection_1, arrow_y2, x_screenIntersection_1, 400);
          else g.drawLine(x_arcIntersection_1, arrow_y2, x_screenIntersection_1, 0);
        else
          g.drawLine(
              x_arcIntersection_1,
              arrow_y2,
              0,
              y_screenIntersection_1); // Else: endpoint is on the y-edge
        // line 3/4
        if (!(arrow_x > 495 - focalLength * 10 && arrow_x < 505 - focalLength * 10)) {
          dy_2 = 200 - arrow_y2;
          dx_2 = (500 - 10 * focalLength) - arrow_x;
          slope_2 = dy_2 / dx_2;
          y_intercept_2 = arrow_y2 - slope_2 * arrow_x;
          quadratic_a = (float) (Math.pow(slope_2, 2) + 1);
          quadratic_b =
              (float)
                  (((2 * slope_2 * y_intercept_2)
                      - (400 * slope_2)
                      + ((radiusOfCurvature - 500) * 2)));
          quadratic_c =
              (float)
                  ((Math.pow(y_intercept_2, 2)
                      - Math.pow(radiusOfCurvature, 2)
                      - (400 * y_intercept_2)
                      + 40000
                      + Math.pow((radiusOfCurvature - 500), 2)));
          discriminant = (float) (Math.pow(quadratic_b, 2) - (4 * quadratic_a * quadratic_c));
          if (discriminant >= 0)
            x_arcIntersection_2 =
                (int)
                    (Math.max(
                        ((-quadratic_b + Math.sqrt(discriminant)) / (2 * quadratic_a)),
                        ((-quadratic_b - Math.sqrt(discriminant)) / (2 * quadratic_a))));
          else System.out.println("Error, imaginary root!");
          y_arcIntersection_2 = (int) (slope_2 * x_arcIntersection_2 + y_intercept_2);
          g.drawLine(arrow_x, arrow_y2, x_arcIntersection_2, y_arcIntersection_2);
          // System.out.println ("slope: " + slope_2 + "\n yintercept: " + y_intercept_2 + "\n
          // quadratic-a: " + quadratic_a + "\n quadratic-b: " + quadratic_b + "\n quadratic_c: " +
          // quadratic_c + "\n discriminant: " + discriminant + "\n xarcintersection2: " +
          // x_arcIntersection_2 + "\n yarcintersection2: " + y_arcIntersection_2);
          // line 4/4
          g.drawLine(x_arcIntersection_2, y_arcIntersection_2, 0, y_arcIntersection_2);

          // POI between line 2 and line 4
          x_pointOfIntersection = (int) ((y_arcIntersection_2 - y_intercept_1) / slope_1);
          y_pointOfIntersection = y_arcIntersection_2;
          g.setColor(Color.ORANGE);
          g.drawLine(x_pointOfIntersection, y_pointOfIntersection, x_pointOfIntersection, 200);

          if (y_pointOfIntersection < 200) {
            g.drawLine(
                x_pointOfIntersection,
                y_pointOfIntersection,
                x_pointOfIntersection - 7,
                y_pointOfIntersection + 7);
            g.drawLine(
                x_pointOfIntersection,
                y_pointOfIntersection,
                x_pointOfIntersection + 7,
                y_pointOfIntersection + 7);
          } else {
            g.drawLine(
                x_pointOfIntersection,
                y_pointOfIntersection,
                x_pointOfIntersection - 7,
                y_pointOfIntersection - 7);
            g.drawLine(
                x_pointOfIntersection,
                y_pointOfIntersection,
                x_pointOfIntersection + 7,
                y_pointOfIntersection - 7);
          }
          // Same side image line continuation
          if (arrow_x > 500 - 10 * focalLength) {
            g.setColor(Color.YELLOW);
            g.drawLine(x_pointOfIntersection, y_pointOfIntersection, x_arcIntersection_1, arrow_y2);
            g.drawLine(
                x_pointOfIntersection,
                y_pointOfIntersection,
                x_arcIntersection_2,
                y_arcIntersection_2);
          }
        }
      } else // Diverging
      {
        // draws converging mirror
        g.drawArc(
            350, 200 - radiusOfCurvature, 2 * radiusOfCurvature, 2 * radiusOfCurvature, 120, 120);
        // draws horizontal line from the tip of the arrow to the lens (line 1/4)
        g.setColor(Color.RED);
        x_arcIntersection_1 =
            (int)
                (-(Math.sqrt(Math.pow(radiusOfCurvature, 2) - Math.pow(arrow_y2 - 200, 2)))
                    + (350 + radiusOfCurvature));
        g.drawLine(arrow_x, arrow_y2, x_arcIntersection_1, arrow_y2);

        // line 2/4
        dy_1 = arrow_y2 - 200;
        dx_1 = x_arcIntersection_1 - (350 + focalLength * 10);
        slope_1 = dy_1 / dx_1;
        y_intercept_1 = 200 - slope_1 * (350 + focalLength * 10);

        // Calculates coordinates of points on the edge of screen (endpoints)
        y_screenIntersection_1 = (int) (Math.round(y_intercept_1));
        if (slope_1 != 0)
          if (arrow_y2 <= 200)
            x_screenIntersection_1 = (int) (Math.round(-y_intercept_1 / slope_1));
          else if (arrow_y2 > 200)
            x_screenIntersection_1 = (int) (Math.round(400 - y_intercept_1 / slope_1));
        if (x_screenIntersection_1 >= 0
            && x_screenIntersection_1 <= 700) // If endpoint is on the x-edge
        if (arrow_y2 <= 200) g.drawLine(x_arcIntersection_1, arrow_y2, x_screenIntersection_1, 0);
          else g.drawLine(x_arcIntersection_1, arrow_y2, x_screenIntersection_1, 400);
        else
          g.drawLine(
              x_arcIntersection_1,
              arrow_y2,
              0,
              y_screenIntersection_1); // Else: endpoint is on the y-edge
        // line 3/4

        dy_2 = 200 - arrow_y2;
        dx_2 = (350 + 10 * focalLength) - arrow_x;
        slope_2 = dy_2 / dx_2;
        y_intercept_2 = arrow_y2 - slope_2 * arrow_x;
        quadratic_a = (float) (Math.pow(slope_2, 2) + 1);
        quadratic_b =
            (float)
                ((2 * slope_2 * y_intercept_2) - (400 * slope_2) - (2 * radiusOfCurvature + 700));
        quadratic_c =
            (float)
                ((Math.pow(y_intercept_2, 2)
                    - Math.pow(radiusOfCurvature, 2)
                    - (400 * y_intercept_2)
                    + 40000
                    + Math.pow((radiusOfCurvature + 350), 2)));
        discriminant = (float) (Math.pow(quadratic_b, 2) - (4 * quadratic_a * quadratic_c));
        if (discriminant >= 0)
          x_arcIntersection_2 =
              (int)
                  (Math.min(
                      ((-quadratic_b + Math.sqrt(discriminant)) / (2 * quadratic_a)),
                      ((-quadratic_b - Math.sqrt(discriminant)) / (2 * quadratic_a))));
        else System.out.println("Error, imaginary root!");
        y_arcIntersection_2 = (int) (slope_2 * x_arcIntersection_2 + y_intercept_2);
        g.drawLine(arrow_x, arrow_y2, x_arcIntersection_2, y_arcIntersection_2);
        // System.out.println ("slope: " + slope_2 + "\n yintercept: " + y_intercept_2 + "\n
        // quadratic-a: " + quadratic_a + "\n quadratic-b: " + quadratic_b + "\n quadratic_c: " +
        // quadratic_c + "\n discriminant: " + discriminant + "\n xarcintersection2: " +
        // x_arcIntersection_2 + "\n yarcintersection2: " + y_arcIntersection_2);
        // line 4/4
        g.drawLine(x_arcIntersection_2, y_arcIntersection_2, 0, y_arcIntersection_2);

        // POI between line 2 and line 4
        x_pointOfIntersection = (int) ((y_arcIntersection_2 - y_intercept_1) / slope_1);
        y_pointOfIntersection = y_arcIntersection_2;
        g.setColor(Color.ORANGE);
        g.drawLine(x_pointOfIntersection, y_pointOfIntersection, x_pointOfIntersection, 200);

        if (y_pointOfIntersection < 200) {
          g.drawLine(
              x_pointOfIntersection,
              y_pointOfIntersection,
              x_pointOfIntersection - 7,
              y_pointOfIntersection + 7);
          g.drawLine(
              x_pointOfIntersection,
              y_pointOfIntersection,
              x_pointOfIntersection + 7,
              y_pointOfIntersection + 7);
        } else {
          g.drawLine(
              x_pointOfIntersection,
              y_pointOfIntersection,
              x_pointOfIntersection - 7,
              y_pointOfIntersection - 7);
          g.drawLine(
              x_pointOfIntersection,
              y_pointOfIntersection,
              x_pointOfIntersection + 7,
              y_pointOfIntersection - 7);
        }
        // Same side image line continuation
        g.setColor(Color.YELLOW);
        g.drawLine(x_pointOfIntersection, y_pointOfIntersection, x_arcIntersection_1, arrow_y2);
        g.drawLine(
            x_pointOfIntersection, y_pointOfIntersection, x_arcIntersection_2, y_arcIntersection_2);
      }

      // Mag calculations
      height_image = 200 - y_pointOfIntersection;
      height_object = 200 - arrow_y2;
      if (height_object != 0) magnification = height_image / height_object;

      if (magnification <= 9999 && magnification >= -9999)
        Optics.txt_magnification.setText("" + roundTwoDecimals(magnification));
      else if (magnification > 9999) {
        magnification = Double.POSITIVE_INFINITY;
        Optics.txt_magnification.setText("N/A");
      } else {
        magnification = Double.NEGATIVE_INFINITY;
        Optics.txt_magnification.setText("N/A");
      }
      // Characteristics
      g.setColor(Color.ORANGE);
      g.drawString("Image Characteristics:", 20, 300);
      if (type == 0) {

        if ((Math.abs(magnification) > 1 && Math.abs(magnification) < 9999)
            && arrow_x != 500 - 10 * focalLength) g.drawString("Magnification:  Enlarged", 20, 320);
        else if ((int) (Math.abs(magnification)) == 1)
          g.drawString("Magnification:  None", 20, 320);
        else if (Math.abs(magnification) < 1 && Math.abs(magnification) > 0)
          g.drawString("Magnification:  Diminished", 20, 320);
        else {
          g.drawString("Magnification:  N/A", 20, 320);
          Optics.txt_magnification.setText("N/A");
          Optics.lbl_distanceImage.setText("<html>d<sub>i</sub>= N/A</html>");
          Optics.lbl_heightImage.setText("<html>h<sub>i</sub>= N/A</html>");
        }
        if (arrow_x == 500 - 10 * focalLength) g.drawString("Orientation:      N/A", 20, 335);
        else if ((arrow_y2 < 200 && y_pointOfIntersection < 200)
            || (arrow_y2 > 200 && y_pointOfIntersection > 200))
          g.drawString("Orientation:      Upright", 20, 335);
        else g.drawString("Orientation:      Inverted", 20, 335);
        if (arrow_x == 500 - 10 * focalLength) g.drawString("Type:                 N/A", 20, 350);
        else if (x_pointOfIntersection < 500 && arrow_x < 500)
          g.drawString("Type:                 Real", 20, 350);
        else if (x_pointOfIntersection > 500 && arrow_x < 500)
          g.drawString("Type:                 Virtual", 20, 350);
      } else {
        g.drawString("Magnification:  Diminished", 20, 320);
        g.drawString("Orientation:      Upright", 20, 335);
        g.drawString("Type:                 Virtual", 20, 350);
      }

      height_image /= 10;

      if (height_image > 9999 || height_image < -9999 || arrow_x == 500 - 10 * focalLength)
        Optics.lbl_heightImage.setText("<html>h<sub>i</sub>= N/A</html>");
      else Optics.lbl_heightImage.setText("<html>h<sub>i</sub>= " + height_image + "</html>");
      if (type == 0) distance_image = x_pointOfIntersection - 500;
      else distance_image = x_pointOfIntersection - 350;
      distance_image /= 10;
      if (distance_image > 9999 || distance_image < -9999 || arrow_x == 500 - 10 * focalLength)
        Optics.lbl_distanceImage.setText("<html>d<sub>i</sub>= N/A</html>");
      else Optics.lbl_distanceImage.setText("<html>d<sub>i</sub>= " + distance_image + "</html>");
    }
  }