用过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.*;
-
-
-
-
-
- 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();
- }
- }
分享到:
相关推荐
重点代码:new Arc2D.Float(200, 50, 100, 50, 0, 90, Arc2D.PIE); PIE 闭合类型,用于通过从弧段的起始点到完整椭圆的中心,再从圆心到弧段的结束点画直线来闭合的弧。
Arc2D文档– 10KB / 1400行代码(LOC)。 在移动,桌面和Web设备上超高效。 低内存(RAM)占用空间和较小的内核大小使Arc2D占据了坚实的优势。 Arc2D框架 :rhinoceros: Arc2D框架-一种不可知的,符合W3C ES6 / 7 ...
cocos2d IOS iphone ARC 最新原版,怎么让cocos2d 使用arc机制。
ArcScene三维制作ArcScene三维制作ArcScene三维制作ArcScene三维制作
:link: Arc2D 框架主页: : 与 Cloudflare Workers 站点一起部署的 Arc2D 框架 SPA 演示 :rocket: :link: 这是一个使用并使用Cloudflare Workers Sites 部署的简单单页应用程序 什么是 Cloudflare Workers 站点...
是从网上整理的关于ArcEngine的代码,里边有多个例子。有源码和相应的说明。
Arc2D主页– Arc2D文档–
ARC 自动迁移的常见问题 15 属性property 17 IBOutlet 18 readonly property 19 autorelease 、release 、retain 调用 19 dealloc 方法 20 AutoreleasePool 20 To l l- Free Bridging 21 Delegate 和 Weak ...
一般介绍cocos2d编程的好书,书中以cocos 2d 2.0版本为例介绍,同时在代码中使用arc,适合ios游戏开发人员阅读和学习。
关于ArcEngine 类库架构
arc_conv_r55解包工具
主要是一些关于ArcEngine接口详细说明,里面详细的介绍了一些关于ArcEngine,以及他的用法
arc_conv========Command-line visual novel toolkit written by w8m in pure ASM
水疗演示使用 Arc2D 框架轻松开发单页应用程序
对于ALLEGRO设计在出验证光绘文件阶段,在CAM350中导入光绘文件时经常有报错"Zero radius arc detected.Assuming linear interpolation",导致无法正常导入光绘文件。解决这个问题我是半猜半蒙,发生过几次这个问题,...
\ArcEngine开发——在64位操作系统下使用VS2010中开发ArcEngine应用程序的编译问题.
韩鹏的ARCENGINE 源韩鹏的ARCENGINE 源代码韩鹏的ARCENGINE 源代码代码
ARC CPU编程手册,对理解ARC CPU构架和编程有帮助。This document is intended for programmers of the ARCv2 ISA (Instruction-Set Architecture). The ARCv2 ISA comprises a mandatory set of baseline features,...
ArcEngine+C#实现ArcGIS的Swipe卷帘功能
ARC是一种古老的压缩文件格式,现在流行的winzip, winrar都已不支持该格式(winzip需外挂PKXARC后方支持)。这个PKXARC,就在附件中啦。