Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
009f710e
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
009f710e
编写于
1月 19, 2011
作者:
D
dlila
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
4493128: CubicCurve2D intersects method fails
Summary: Now using subdivision code in sun.awt.geom.Curve. Reviewed-by: flar
上级
ee1a5ea8
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
7 addition
and
197 deletion
+7
-197
src/share/classes/java/awt/geom/CubicCurve2D.java
src/share/classes/java/awt/geom/CubicCurve2D.java
+7
-197
未找到文件。
src/share/classes/java/awt/geom/CubicCurve2D.java
浏览文件 @
009f710e
...
...
@@ -1387,203 +1387,13 @@ public abstract class CubicCurve2D implements Shape, Cloneable {
return
false
;
}
// Trivially accept if either endpoint is inside the rectangle
// (not on its border since it may end there and not go inside)
// Record where they lie with respect to the rectangle.
// -1 => left, 0 => inside, 1 => right
double
x1
=
getX1
();
double
y1
=
getY1
();
int
x1tag
=
getTag
(
x1
,
x
,
x
+
w
);
int
y1tag
=
getTag
(
y1
,
y
,
y
+
h
);
if
(
x1tag
==
INSIDE
&&
y1tag
==
INSIDE
)
{
return
true
;
}
double
x2
=
getX2
();
double
y2
=
getY2
();
int
x2tag
=
getTag
(
x2
,
x
,
x
+
w
);
int
y2tag
=
getTag
(
y2
,
y
,
y
+
h
);
if
(
x2tag
==
INSIDE
&&
y2tag
==
INSIDE
)
{
return
true
;
}
double
ctrlx1
=
getCtrlX1
();
double
ctrly1
=
getCtrlY1
();
double
ctrlx2
=
getCtrlX2
();
double
ctrly2
=
getCtrlY2
();
int
ctrlx1tag
=
getTag
(
ctrlx1
,
x
,
x
+
w
);
int
ctrly1tag
=
getTag
(
ctrly1
,
y
,
y
+
h
);
int
ctrlx2tag
=
getTag
(
ctrlx2
,
x
,
x
+
w
);
int
ctrly2tag
=
getTag
(
ctrly2
,
y
,
y
+
h
);
// Trivially reject if all points are entirely to one side of
// the rectangle.
if
(
x1tag
<
INSIDE
&&
x2tag
<
INSIDE
&&
ctrlx1tag
<
INSIDE
&&
ctrlx2tag
<
INSIDE
)
{
return
false
;
// All points left
}
if
(
y1tag
<
INSIDE
&&
y2tag
<
INSIDE
&&
ctrly1tag
<
INSIDE
&&
ctrly2tag
<
INSIDE
)
{
return
false
;
// All points above
}
if
(
x1tag
>
INSIDE
&&
x2tag
>
INSIDE
&&
ctrlx1tag
>
INSIDE
&&
ctrlx2tag
>
INSIDE
)
{
return
false
;
// All points right
}
if
(
y1tag
>
INSIDE
&&
y2tag
>
INSIDE
&&
ctrly1tag
>
INSIDE
&&
ctrly2tag
>
INSIDE
)
{
return
false
;
// All points below
}
// Test for endpoints on the edge where either the segment
// or the curve is headed "inwards" from them
// Note: These tests are a superset of the fast endpoint tests
// above and thus repeat those tests, but take more time
// and cover more cases
if
(
inwards
(
x1tag
,
x2tag
,
ctrlx1tag
)
&&
inwards
(
y1tag
,
y2tag
,
ctrly1tag
))
{
// First endpoint on border with either edge moving inside
return
true
;
}
if
(
inwards
(
x2tag
,
x1tag
,
ctrlx2tag
)
&&
inwards
(
y2tag
,
y1tag
,
ctrly2tag
))
{
// Second endpoint on border with either edge moving inside
return
true
;
}
// Trivially accept if endpoints span directly across the rectangle
boolean
xoverlap
=
(
x1tag
*
x2tag
<=
0
);
boolean
yoverlap
=
(
y1tag
*
y2tag
<=
0
);
if
(
x1tag
==
INSIDE
&&
x2tag
==
INSIDE
&&
yoverlap
)
{
return
true
;
}
if
(
y1tag
==
INSIDE
&&
y2tag
==
INSIDE
&&
xoverlap
)
{
return
true
;
}
// We now know that both endpoints are outside the rectangle
// but the 4 points are not all on one side of the rectangle.
// Therefore the curve cannot be contained inside the rectangle,
// but the rectangle might be contained inside the curve, or
// the curve might intersect the boundary of the rectangle.
double
[]
eqn
=
new
double
[
4
];
double
[]
res
=
new
double
[
4
];
if
(!
yoverlap
)
{
// Both y coordinates for the closing segment are above or
// below the rectangle which means that we can only intersect
// if the curve crosses the top (or bottom) of the rectangle
// in more than one place and if those crossing locations
// span the horizontal range of the rectangle.
fillEqn
(
eqn
,
(
y1tag
<
INSIDE
?
y
:
y
+
h
),
y1
,
ctrly1
,
ctrly2
,
y2
);
int
num
=
solveCubic
(
eqn
,
res
);
num
=
evalCubic
(
res
,
num
,
true
,
true
,
null
,
x1
,
ctrlx1
,
ctrlx2
,
x2
);
// odd counts imply the crossing was out of [0,1] bounds
// otherwise there is no way for that part of the curve to
// "return" to meet its endpoint
return
(
num
==
2
&&
getTag
(
res
[
0
],
x
,
x
+
w
)
*
getTag
(
res
[
1
],
x
,
x
+
w
)
<=
0
);
}
// Y ranges overlap. Now we examine the X ranges
if
(!
xoverlap
)
{
// Both x coordinates for the closing segment are left of
// or right of the rectangle which means that we can only
// intersect if the curve crosses the left (or right) edge
// of the rectangle in more than one place and if those
// crossing locations span the vertical range of the rectangle.
fillEqn
(
eqn
,
(
x1tag
<
INSIDE
?
x
:
x
+
w
),
x1
,
ctrlx1
,
ctrlx2
,
x2
);
int
num
=
solveCubic
(
eqn
,
res
);
num
=
evalCubic
(
res
,
num
,
true
,
true
,
null
,
y1
,
ctrly1
,
ctrly2
,
y2
);
// odd counts imply the crossing was out of [0,1] bounds
// otherwise there is no way for that part of the curve to
// "return" to meet its endpoint
return
(
num
==
2
&&
getTag
(
res
[
0
],
y
,
y
+
h
)
*
getTag
(
res
[
1
],
y
,
y
+
h
)
<=
0
);
}
// The X and Y ranges of the endpoints overlap the X and Y
// ranges of the rectangle, now find out how the endpoint
// line segment intersects the Y range of the rectangle
double
dx
=
x2
-
x1
;
double
dy
=
y2
-
y1
;
double
k
=
y2
*
x1
-
x2
*
y1
;
int
c1tag
,
c2tag
;
if
(
y1tag
==
INSIDE
)
{
c1tag
=
x1tag
;
}
else
{
c1tag
=
getTag
((
k
+
dx
*
(
y1tag
<
INSIDE
?
y
:
y
+
h
))
/
dy
,
x
,
x
+
w
);
}
if
(
y2tag
==
INSIDE
)
{
c2tag
=
x2tag
;
}
else
{
c2tag
=
getTag
((
k
+
dx
*
(
y2tag
<
INSIDE
?
y
:
y
+
h
))
/
dy
,
x
,
x
+
w
);
}
// If the part of the line segment that intersects the Y range
// of the rectangle crosses it horizontally - trivially accept
if
(
c1tag
*
c2tag
<=
0
)
{
return
true
;
}
// Now we know that both the X and Y ranges intersect and that
// the endpoint line segment does not directly cross the rectangle.
//
// We can almost treat this case like one of the cases above
// where both endpoints are to one side, except that we may
// get one or three intersections of the curve with the vertical
// side of the rectangle. This is because the endpoint segment
// accounts for the other intersection in an even pairing. Thus,
// with the endpoint crossing we end up with 2 or 4 total crossings.
//
// (Remember there is overlap in both the X and Y ranges which
// means that the segment itself must cross at least one vertical
// edge of the rectangle - in particular, the "near vertical side"
// - leaving an odd number of intersections for the curve.)
//
// Now we calculate the y tags of all the intersections on the
// "near vertical side" of the rectangle. We will have one with
// the endpoint segment, and one or three with the curve. If
// any pair of those vertical intersections overlap the Y range
// of the rectangle, we have an intersection. Otherwise, we don't.
// c1tag = vertical intersection class of the endpoint segment
//
// Choose the y tag of the endpoint that was not on the same
// side of the rectangle as the subsegment calculated above.
// Note that we can "steal" the existing Y tag of that endpoint
// since it will be provably the same as the vertical intersection.
c1tag
=
((
c1tag
*
x1tag
<=
0
)
?
y1tag
:
y2tag
);
// Now we have to calculate an array of solutions of the curve
// with the "near vertical side" of the rectangle. Then we
// need to sort the tags and do a pairwise range test to see
// if either of the pairs of crossings spans the Y range of
// the rectangle.
//
// Note that the c2tag can still tell us which vertical edge
// to test against.
fillEqn
(
eqn
,
(
c2tag
<
INSIDE
?
x
:
x
+
w
),
x1
,
ctrlx1
,
ctrlx2
,
x2
);
int
num
=
solveCubic
(
eqn
,
res
);
num
=
evalCubic
(
res
,
num
,
true
,
true
,
null
,
y1
,
ctrly1
,
ctrly2
,
y2
);
// Now put all of the tags into a bucket and sort them. There
// is an intersection iff one of the pairs of tags "spans" the
// Y range of the rectangle.
int
tags
[]
=
new
int
[
num
+
1
];
for
(
int
i
=
0
;
i
<
num
;
i
++)
{
tags
[
i
]
=
getTag
(
res
[
i
],
y
,
y
+
h
);
}
tags
[
num
]
=
c1tag
;
Arrays
.
sort
(
tags
);
return
((
num
>=
1
&&
tags
[
0
]
*
tags
[
1
]
<=
0
)
||
(
num
>=
3
&&
tags
[
2
]
*
tags
[
3
]
<=
0
));
int
numCrossings
=
rectCrossings
(
x
,
y
,
w
,
h
);
// the intended return value is
// numCrossings != 0 || numCrossings == Curve.RECT_INTERSECTS
// but if (numCrossings != 0) numCrossings == INTERSECTS won't matter
// and if !(numCrossings != 0) then numCrossings == 0, so
// numCrossings != RECT_INTERSECT
return
numCrossings
!=
0
;
}
/**
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录