欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于Arc2D的角度问题 博客分类: Java 2D/3D 360Swing 

程序员文章站 2024-02-16 20:52:10
...

        用过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. }  
相关标签: 360 Swing