⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 curveapplet.java

📁 Beginning Java 2, SDK 1.4 Edition Exercise Code samples for this book
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
// Chapter 18 Exercise 6 
/*
  Most of the work was done in the previous exercise solution. Here, all we need
  to do is ensure that moving markers does not make the curve discontinuous. 

  When a control marker is moved, we need to ensure that the control markers either
  side of a defining point remain be the same distance from the defining point 
  and the control markers and the defining point are collinear.
  
  When a defining point is moved, we must ensure that the control markers that apply
  to the segment(s) either side of the point are moved the same distance.
  One limitation on function here is that you can't change the first or last control
  points because they are hidden by the defining points. A simple send-to-back
  operation would fix this though.
*/
import javax.swing.JApplet;
import javax.swing.JComponent;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.FlowLayout;
import java.awt.BorderLayout;
import java.awt.Point;

import java.awt.geom.Point2D;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;

import javax.swing.event.MouseInputAdapter;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.BorderFactory;
import javax.swing.border.EtchedBorder;

import java.awt.event.MouseEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import java.util.Vector;

public class CurveApplet extends JApplet {
  // Initialize the applet
  public void init() {
    pane = new CurvePane();                       // Create pane containing curves
    Container content = getContentPane();         // Get the content pane

    // Add the pane displaying the curves to the content pane for the applet
    content.add(pane);                  // BorderLayout.CENTER is default position
    
    MouseHandler handler = new MouseHandler();    // Create the listener
    pane.addMouseListener(handler);               // Monitor mouse button presses
    pane.addMouseMotionListener(handler);         // as well as movement

    // Create the panel to hold the buttons
    JPanel buttonPane = new JPanel();
    buttonPane.setLayout(new FlowLayout());
    buttonPane.setBackground(Color.DARK_GRAY);
    buttonPane.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED,
                                                      Color.BLUE,
                                                      Color.CYAN));
    
    // Create and add the button to clear the display
    JButton button = new JButton("Clear Pane");
    button.setBorder(BorderFactory.createRaisedBevelBorder());
    button.addActionListener(new ActionListener(){    // Action listener for the button
      public void actionPerformed(ActionEvent e) {
        clearPane();
      }
    });
    buttonPane.add(button);
    
    // Create and add the button to end the definition of the curve
    button  = new JButton("End Curve");
    button.setBorder(BorderFactory.createRaisedBevelBorder());
    button.addActionListener(new ActionListener(){   // Action listener for the button
      public void actionPerformed(ActionEvent e) {
      curveComplete = true;
      pane.repaint();
      }
    });
    buttonPane.add(button);
    
    content.add(buttonPane, BorderLayout.SOUTH);
    
  }

  // Method to clear the screen ready for a new set of points
  private void clearPane() {
    pointMarkers = new Vector();   // Remove the point markers
    curveSegments = null;          // and the array of curve segments
    curveComplete = false;         // Reset curve complete flag
    repaint();
  }

  private void createCurves() {
    // Create the curves
    int n = pointMarkers.size();
    Point2D.Double[] points = new Point2D.Double[n];

    // Extract the points from the vector of Marker objects
    for(int i = 0 ; i<n ; i++)
      points[i] = ((Marker)(pointMarkers.elementAt(i))).getCenter();

    int m =  (n - 2);             // Number of coeffients for calculating control vectors     
    double[] f = new double[m+1]; // Array used to calculate coefficients, a
    f[0] = 1.0;
    f[1] = -4 + n%2 ;            // -3 when n is odd and -4 when n is even
    for(int j = 2 ; j<f.length ; j++)
      f[j] = -4.0*f[j-1] - f[j-2];

    // Calculate the coefficients. This array could be limited to 5 elements
    // since the values of elements of a beyond a[4] are very small.
    double[] a = new double[m];
    double factor = 1.0/f[f.length-1];
    for(int j = 0 ; j<a.length ; j++)
      a[j] = -f[m-j-1]*factor;
       
    // Calculate control vectors, one for each point. The control points
    // for the curve are calculated by adding and/or subtracting the control
    // vector from the corresponding curve point.
    controlVec = new Point2D.Double[n];
    controlVec[0] = new Point2D.Double(0.0, 0.0);
    controlVec[n-1] = controlVec[0];
    for(int i = 1 ; i<n-1; i++) {
      double x = 0.0;
      double y = 0.0;
      int n1 = 0;
      int n2 = 0;
      for(int k = 0 ; k<a.length ; k++) {
        n1 = (i+k+1)%n;
        n2 = Math.abs(i-k-1);
        x += a[k]*(points[n1].x - points[n2].x); 
        y += a[k]*(points[n1].y - points[n2].y); 
      }
      controlVec[i] = new Point2D.Double(x, y);
    }

    // Define the curve segments using the defining points and control points
    // created using the vectors in the controlVec array
    curveSegments = new CubicCurve2D.Double[n-1];
    controlMarkers = new Marker[2*curveSegments.length];
    Point2D.Double controlPt1 = null;
    Point2D.Double controlPt2 = null;
    int j = 0;
    for(int i = 0 ; i<curveSegments.length; i++) {
      curveSegments[i] = new CubicCurve2D.Double();
      controlPt1 = new Point2D.Double(points[i].x+controlVec[i].x,
                                      points[i].y+controlVec[i].y);
      controlPt2 = new Point2D.Double(points[i+1].x-controlVec[i+1].x,
                                      points[i+1].y-controlVec[i+1].y);
      curveSegments[i].setCurve(points[i], controlPt1, controlPt2, points[i+1]);
      controlMarkers[j++] = new Marker(controlPt1, Color.RED);
      controlMarkers[j++] = new Marker(controlPt2, Color.RED);
    }
  }

  // Class defining a pane on which to draw
  class CurvePane extends JComponent {
    // Constructor
    public void paint(Graphics g) {
      Graphics2D g2D = (Graphics2D)g;                   // Get a 2D device context
 
      // If there are any curves, draw them in green     
      if(curveSegments != null) {
        g2D.setColor(Color.GREEN);
        for (int i = 0; i<curveSegments.length ; i++)
          g2D.draw(curveSegments[i]);
      }

      // Draw the point markers
      for(int i = 0 ; i<pointMarkers.size() ; i++) {
        ((Marker)(pointMarkers.elementAt(i))).draw(g2D);
      }
    
      // If the curve is finished, draw the control markers and tangents
      if(curveComplete) {
        for(int i = 0 ; i<controlMarkers.length ; i++) 
          controlMarkers[i].draw(g2D);
  
        // Draw the tangent lines
        Line2D.Double tangent = null;
        g2D.setColor(Color.RED);
        for(int i = 0 ; i<curveSegments.length ; i++) {
          tangent = new Line2D.Double(curveSegments[i].getP1(),curveSegments[i].getCtrlP1());
          g2D.draw(tangent);
          tangent = new Line2D.Double(curveSegments[i].getP2(),curveSegments[i].getCtrlP2());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -