2006-12-23

关于Arc2D的角度问题

关键字: Graphics2D Arc2D 角度

        用过JAVA 2D中的Arc2D类的就会发现,画出来的圆弧的角度与构造函数中的角度并不一致.通过查看Arc2D的源代码可以发现,Arc2D是这样生成圆弧的:首先使用给定的起始角度与跨越角度生成一个半径为1的标准单位圆弧,然后通过伸缩变换,将其转换为构造函数中指定的椭圆上的圆弧.显然,这样得到圆弧的起始角与跨度角与构造函数中的已经不一样了,除非这个椭圆本来就是个圆,或者其角度为90的倍数.

        既然知道了Arc2D的生成原理,通过简单三角变换,我们很容易通过角度变换使用Arc2D生成我们需要的圆弧.下面的代码就是将圆弧的实际角度转换为Arc2D的参数角度:

java 代码
  1. public static double degreeTranslate(double width,double height,double degree){   
  2.      double radian =Math.toRadians(degree);   
  3.      double trans  =Math.atan2(width*Math.sin(radian),height*Math.cos(radian));   
  4.      double angle =Math.toDegrees(trans);   
  5.      return angle>0?angle:360+angle;   
  6.  }  

 

       下面,我们通过一个完整的程序来显示这段代码的正确性:

java 代码
  1. import java.awt.*;   
  2. import java.awt.event.*;   
  3. import java.awt.geom.*;   
  4. import javax.swing.*;   
  5. /**  
  6. *Arc2D中角度变换的测试程序  
  7. *@author Eastsun  
  8. *@Version 1.0  
  9. */  
  10. public class ArcT extends JFrame implements ActionListener,FocusListener{   
  11.     public static double degreeTranslate(double width,double height,double degree){   
  12.         double radian =Math.toRadians(degree);   
  13.         double trans  =Math.atan2(width*Math.sin(radian),height*Math.cos(radian));   
  14.         double angle =Math.toDegrees(trans);   
  15.         return angle>0?angle:360+angle;   
  16.     }   
  17.        
  18.     public static Arc2D createArc(double x,double y,double width,double height,double start,double extent,int type){   
  19.         double nStart =degreeTranslate(width,height,start);   
  20.         double nExtent =0;   
  21.         if(extent>=360||extent<=-360) nExtent =360;   
  22.         else{     
  23.             nExtent =degreeTranslate(width,height,start+extent)-nStart;   
  24.             if(extent<0&&nExtent>0) nExtent =nExtent -360;   
  25.             if(extent>0&&nExtent<0) nExtent =nExtent +360;   
  26.         }   
  27.         return new Arc2D.Double(x,y,width,height,nStart,nExtent,type);   
  28.     }   
  29.        
  30.     private Arc2D arcA,arcB;   
  31.     private double start,extent;   
  32.     private JTextField startField,extentField;   
  33.     private Stroke strokeB =new BasicStroke(3.0f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER,10.0f,new float[]{5,20,5,10},0),   
  34.                    strokeA =new BasicStroke(3.0f),   
  35.                    strokeX =new BasicStroke(1.0f);   
  36.                       
  37.     public ArcT(){   
  38.         super("圆弧测试程序");   
  39.         JPanel drawPanel =new JPanel(){   
  40.             public void paintComponent(Graphics g){   
  41.                 super.paintComponent(g);   
  42.                 Graphics2D g2 =(Graphics2D)g;   
  43.                 g2.setPaint(Color.white);   
  44.                 g2.fillRect(0,0,getWidth(),getHeight());   
  45.                 g2.setPaint(Color.black);   
  46.                 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);   
  47.                 g2.setStroke(strokeA);   
  48.                 g2.draw(arcA);   
  49.                 g2.setPaint(Color.red);   
  50.                 g2.setStroke(strokeB);   
  51.                 g2.draw(arcB);   
  52.                 g2.setStroke(strokeX);   
  53.                    
  54.                 g2.setPaint(Color.black);   
  55.                 g2.draw(new Line2D.Double(new Point(160,120),arcA.getStartPoint()));   
  56.                 g2.draw(new Line2D.Double(new Point(160,120),arcA.getEndPoint()));   
  57.                    
  58.                 g2.setPaint(Color.red);   
  59.                 g2.draw(new Line2D.Double(new Point(160,120),arcB.getStartPoint()));   
  60.                 g2.draw(new Line2D.Double(new Point(160,120),arcB.getEndPoint()));   
  61.             }   
  62.         };   
  63.         drawPanel.setPreferredSize(new Dimension(320,240));   
  64.         add(drawPanel,BorderLayout.CENTER);   
  65.            
  66.         JPanel setPanel =new JPanel();   
  67.         setPanel.add(new JLabel("起始角度:"));   
  68.         startField =new JTextField("0.0",6);   
  69.         start =0;   
  70.         startField.addActionListener(this);   
  71.         startField.addFocusListener(this);   
  72.         setPanel.add(startField);   
  73.            
  74.         setPanel.add(new JLabel("跨越角度:"));   
  75.         extentField =new JTextField("90.0",6);   
  76.         extent =90;   
  77.         extentField.addActionListener(this);   
  78.         extentField.addFocusListener(this);   
  79.         setPanel.add(extentField);   
  80.            
  81.         arcA =createArc(20,15,280,210,start,extent,Arc2D.OPEN);   
  82.         arcB =new Arc2D.Double(20,15,280,210,start,extent,Arc2D.OPEN);   
  83.         add(setPanel,BorderLayout.SOUTH);   
  84.            
  85.         pack();   
  86.         setResizable(false);   
  87.         setDefaultCloseOperation(EXIT_ON_CLOSE);   
  88.         setVisible(true);   
  89.            
  90.     }   
  91.     private void setArcByTextField(JTextField textField){   
  92.         double value =0;   
  93.         try{   
  94.             value =Double.parseDouble(textField.getText().trim());   
  95.         }catch(Exception e){   
  96.             textField.setText(String.valueOf(textField==startField?start:extent));   
  97.             return;   
  98.         }   
  99.         if(textField==startField) start =value;   
  100.         else                      extent =value;   
  101.         arcA =createArc(20,15,280,210,start,extent,Arc2D.OPEN);   
  102.         arcB =new Arc2D.Double(20,15,280,210,start,extent,Arc2D.OPEN);   
  103.         repaint();   
  104.     }   
  105.     public void focusGained(FocusEvent e){}   
  106.     public void focusLost(FocusEvent e){   
  107.         setArcByTextField((JTextField)e.getComponent());   
  108.     }   
  109.     public void actionPerformed(ActionEvent e){   
  110.         setArcByTextField((JTextField)e.getSource());   
  111.     }   
  112.     public static void main(String[] args){   
  113.         new ArcT();   
  114.     }   
  115. }  
评论
发表评论

您还没有登录,请登录后发表评论

Eastsun
搜索本博客
我的相册
1b680e5a-efae-3ec3-8ccd-970a4a72a056-thumb
6.5beta.PNG
共 61 张
最近加入圈子
存档
最新评论