2006-12-23
关于Arc2D的角度问题
关键字: Graphics2D Arc2D 角度用过JAVA 2D中的Arc2D类的就会发现,画出来的圆弧的角度与构造函数中的角度并不一致.通过查看Arc2D的源代码可以发现,Arc2D是这样生成圆弧的:首先使用给定的起始角度与跨越角度生成一个半径为1的标准单位圆弧,然后通过伸缩变换,将其转换为构造函数中指定的椭圆上的圆弧.显然,这样得到圆弧的起始角与跨度角与构造函数中的已经不一样了,除非这个椭圆本来就是个圆,或者其角度为90的倍数.
既然知道了Arc2D的生成原理,通过简单三角变换,我们很容易通过角度变换使用Arc2D生成我们需要的圆弧.下面的代码就是将圆弧的实际角度转换为Arc2D的参数角度:
java 代码
- public static double degreeTranslate(double width,double height,double degree){
- double radian =Math.toRadians(degree);
- double trans =Math.atan2(width*Math.sin(radian),height*Math.cos(radian));
- double angle =Math.toDegrees(trans);
- return angle>0?angle:360+angle;
- }
下面,我们通过一个完整的程序来显示这段代码的正确性:
java 代码
- import java.awt.*;
- import java.awt.event.*;
- import java.awt.geom.*;
- import javax.swing.*;
- /**
- *Arc2D中角度变换的测试程序
- *@author Eastsun
- *@Version 1.0
- */
- public class ArcT extends JFrame implements ActionListener,FocusListener{
- public static double degreeTranslate(double width,double height,double degree){
- double radian =Math.toRadians(degree);
- double trans =Math.atan2(width*Math.sin(radian),height*Math.cos(radian));
- double angle =Math.toDegrees(trans);
- return angle>0?angle:360+angle;
- }
- public static Arc2D createArc(double x,double y,double width,double height,double start,double extent,int type){
- double nStart =degreeTranslate(width,height,start);
- double nExtent =0;
- if(extent>=360||extent<=-360) nExtent =360;
- else{
- nExtent =degreeTranslate(width,height,start+extent)-nStart;
- if(extent<0&&nExtent>0) nExtent =nExtent -360;
- if(extent>0&&nExtent<0) nExtent =nExtent +360;
- }
- return new Arc2D.Double(x,y,width,height,nStart,nExtent,type);
- }
- private Arc2D arcA,arcB;
- private double start,extent;
- private JTextField startField,extentField;
- private Stroke strokeB =new BasicStroke(3.0f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER,10.0f,new float[]{5,20,5,10},0),
- strokeA =new BasicStroke(3.0f),
- strokeX =new BasicStroke(1.0f);
- public ArcT(){
- super("圆弧测试程序");
- JPanel drawPanel =new JPanel(){
- public void paintComponent(Graphics g){
- super.paintComponent(g);
- Graphics2D g2 =(Graphics2D)g;
- g2.setPaint(Color.white);
- g2.fillRect(0,0,getWidth(),getHeight());
- g2.setPaint(Color.black);
- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
- g2.setStroke(strokeA);
- g2.draw(arcA);
- g2.setPaint(Color.red);
- g2.setStroke(strokeB);
- g2.draw(arcB);
- g2.setStroke(strokeX);
- g2.setPaint(Color.black);
- g2.draw(new Line2D.Double(new Point(160,120),arcA.getStartPoint()));
- g2.draw(new Line2D.Double(new Point(160,120),arcA.getEndPoint()));
- g2.setPaint(Color.red);
- g2.draw(new Line2D.Double(new Point(160,120),arcB.getStartPoint()));
- g2.draw(new Line2D.Double(new Point(160,120),arcB.getEndPoint()));
- }
- };
- drawPanel.setPreferredSize(new Dimension(320,240));
- add(drawPanel,BorderLayout.CENTER);
- JPanel setPanel =new JPanel();
- setPanel.add(new JLabel("起始角度:"));
- startField =new JTextField("0.0",6);
- start =0;
- startField.addActionListener(this);
- startField.addFocusListener(this);
- setPanel.add(startField);
- setPanel.add(new JLabel("跨越角度:"));
- extentField =new JTextField("90.0",6);
- extent =90;
- extentField.addActionListener(this);
- extentField.addFocusListener(this);
- setPanel.add(extentField);
- arcA =createArc(20,15,280,210,start,extent,Arc2D.OPEN);
- arcB =new Arc2D.Double(20,15,280,210,start,extent,Arc2D.OPEN);
- add(setPanel,BorderLayout.SOUTH);
- pack();
- setResizable(false);
- setDefaultCloseOperation(EXIT_ON_CLOSE);
- setVisible(true);
- }
- private void setArcByTextField(JTextField textField){
- double value =0;
- try{
- value =Double.parseDouble(textField.getText().trim());
- }catch(Exception e){
- textField.setText(String.valueOf(textField==startField?start:extent));
- return;
- }
- if(textField==startField) start =value;
- else extent =value;
- arcA =createArc(20,15,280,210,start,extent,Arc2D.OPEN);
- arcB =new Arc2D.Double(20,15,280,210,start,extent,Arc2D.OPEN);
- repaint();
- }
- public void focusGained(FocusEvent e){}
- public void focusLost(FocusEvent e){
- setArcByTextField((JTextField)e.getComponent());
- }
- public void actionPerformed(ActionEvent e){
- setArcByTextField((JTextField)e.getSource());
- }
- public static void main(String[] args){
- new ArcT();
- }
- }
- 23:41
- 浏览 (672)
- 评论 (0)
- 分类: Java 2D/3D
- 相关推荐
发表评论
- 浏览: 75677 次
- 性别:

- 来自: 天津

- 详细资料
搜索本博客
我的相册
6.5beta.PNG
共 61 张
共 61 张
最新评论
-
澄清:Java中只有按值传递 ...
Eastsun 写道归根究底,其实就是一个对“按引用传递”这个概念理解的问题。 ...
-- by suerzxt -
一个将BIG5编码转换为GB23 ...
谢谢了。呵呵
-- by zhangts8888 -
Java与Scala中的闭包
我说说我对闭包的理解,看看片面不,我理解的闭包是一个处理的输入和输出类型项相同, ...
-- by bloodrate -
Java与Scala中的闭包
刚刚试验了下java7: class A{ static { => in ...
-- by hity -
不要随便和老外说中文!!
。。。。。。。太强大了。。。。居然被gigix碰到真人真事了。。。
-- by sg552






评论排行榜