试图在Java中绘制带椭圆的时钟

时间:2014-03-29 15:00:53

标签: java

enter image description here

我希望有12个椭圆,所以它们代表全天候的5分钟间隔。但是每次我为路径迭代器更改linApproxLen时,它总是绘制太多的椭圆或9个椭圆。如何让这些椭圆代表5分钟?

private Ellipse2D ellipse = new Ellipse2D.Double();
public void setClockContour(int w, int h) 
{
 size = (w > h) ? h/6f : w/6f;
 ellipse.setFrame(w/2-size*2-4.5f,h/2-size*2-4.5f,size*4,size*4);
    double linApproxLen = 0.75 * size * 0.258819;              // sin(15 degree)
    PathIterator pi = ellipse.getPathIterator(null, linApproxLen);
    Point2D[] points = new Point2D[100];
    int num_pts = 0;
    while ( !pi.isDone() ) 
    {
        float[] pt = new float[6];
        switch ( pi.currentSegment(pt) ) {
            case FlatteningPathIterator.SEG_MOVETO:
            case FlatteningPathIterator.SEG_LINETO:
                points[num_pts] = new Point2D.Float(pt[0], pt[1]);
                num_pts++;
        }
        pi.next();
    }
    pts = new Point2D[num_pts];
    System.arraycopy(points, 0, pts, 0, num_pts);

}

1 个答案:

答案 0 :(得分:1)

我认为无论linApproxLen参数如何,该方法都不起作用。此参数仅指定"平坦度"这条线。虽然这肯定会影响返回的线段数,但实际数将至少取决于您绘制的椭圆的 radius 。因此,即使您在一种情况下设法返回12个点,更改半径(即,wh给出的大小)也会影响返回的点数。

计算圆形地层中12个点的位置特别容易。您可以使用相应角度的正弦和余弦计算圆上的位置。然后可以缩放或移动所得到的点以获得所需的形状。

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ClockCirclesTest
{
    public static void main(String[] args) 
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new GridLayout(1, 0));
        frame.getContentPane().add(new ClockCirclesPanel());
        frame.setSize(400,400);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

class ClockCirclesPanel extends JPanel
{
    @Override
    protected void paintComponent(Graphics gr)
    {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D)gr;
        g.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING, 
            RenderingHints.VALUE_ANTIALIAS_ON);

        int w = getWidth() / 2;
        int h = getHeight() / 2;
        Point2D points[] = computePoints(w, h, 12);

        int cx = getWidth() / 2;
        int cy = getHeight() / 2;
        g.translate(cx, cy);
        for (Point2D p : points)
        {
            g.draw(new Ellipse2D.Double(
                p.getX() - 5, p.getY() - 5,
                10, 10));
        }
    }

    private Point2D[] computePoints(double w, double h, int n)
    {
        Point2D points[] = new Point2D[n];
        double angleDeltaRad = Math.PI * 2 / n;
        for (int i=0; i<n; i++)
        {
            double angleRad = i * angleDeltaRad;
            double ca = Math.cos(angleRad);
            double sa = Math.sin(angleRad);
            double x = sa * w/2;
            double y = ca * h/2;
            points[i] = new Point2D.Double(x,y);
        }
        return points;
    }

}