Cross Reference: Helpers.java
xref
: /
openjdk7
/
jdk
/
src
/
share
/
classes
/
sun
/
java2d
/
pisces
/
Helpers.java
Home
History
Annotate
Line#
Navigate
Download
Search
only in
./
2956
N/A
/*
3909
N/A
* Copyright (c) 2007, 2011, Oracle
and
/
or
its affiliates. All rights reserved.
2956
N/A
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2956
N/A
*
2956
N/A
* This code is free software; you can redistribute it
and
/
or
modify it
2956
N/A
* under the terms of the GNU General Public License version 2 only, as
2956
N/A
* published by the Free Software Foundation. Oracle designates this
2956
N/A
* particular file as subject to the "Classpath" exception as provided
2956
N/A
* by Oracle in the LICENSE file that accompanied this code.
2956
N/A
*
2956
N/A
* This code is distributed in the hope that it will be useful, but WITHOUT
2956
N/A
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2956
N/A
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2956
N/A
* version 2 for more details (a copy is included in the LICENSE file that
2956
N/A
* accompanied this code).
2956
N/A
*
2956
N/A
* You should have received a copy of the GNU General Public License version
2956
N/A
* 2 along with this work; if not, write to the Free Software Foundation,
2956
N/A
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2956
N/A
*
2956
N/A
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2956
N/A
* or visit www.oracle.com if you need additional information or have any
2956
N/A
* questions.
2956
N/A
*/
2956
N/A
2956
N/A
package
sun
.
java2d
.
pisces
;
2956
N/A
2956
N/A
import
java
.
util
.
Arrays
;
3444
N/A
import
static
java
.
lang
.
Math
.
PI
;
3444
N/A
import
static
java
.
lang
.
Math
.
cos
;
3444
N/A
import
static
java
.
lang
.
Math
.
sqrt
;
3444
N/A
import
static
java
.
lang
.
Math
.
cbrt
;
3444
N/A
import
static
java
.
lang
.
Math
.
acos
;
3444
N/A
2956
N/A
2956
N/A
final
class
Helpers
{
2956
N/A
private
Helpers
() {
2956
N/A
throw
new
Error
(
"This is a non instantiable class"
);
2956
N/A
}
2956
N/A
2956
N/A
static
boolean
within
(
final
float
x,
final
float
y,
final
float
err
) {
2956
N/A
final
float
d = y - x;
2956
N/A
return
(d <=
err
&& d >= -
err
);
2956
N/A
}
2956
N/A
2956
N/A
static
boolean
within
(
final
double
x,
final
double
y,
final
double
err
) {
2956
N/A
final
double
d = y - x;
2956
N/A
return
(d <=
err
&& d >= -
err
);
2956
N/A
}
2956
N/A
2956
N/A
static
int
quadraticRoots
(
final
float
a,
final
float
b,
2956
N/A
final
float
c,
float
[]
zeroes
,
final
int
off
)
2956
N/A
{
2956
N/A
int
ret
=
off
;
2956
N/A
float
t;
2956
N/A
if
(a !=
0f
) {
2956
N/A
final
float
dis
= b*b -
4
*a*c;
2956
N/A
if
(
dis
>
0
) {
2956
N/A
final
float
sqrtDis
= (
float
)
Math
.
sqrt
(
dis
);
2956
N/A
// depending on the sign of b we use a slightly different
2956
N/A
// algorithm than the traditional one to find one of the roots
2956
N/A
// so we can avoid adding numbers of different signs (which
2956
N/A
// might result in loss of precision).
2956
N/A
if
(b >=
0
) {
2956
N/A
zeroes
[
ret
++] = (
2
* c) / (-b -
sqrtDis
);
2956
N/A
zeroes
[
ret
++] = (-b -
sqrtDis
) / (
2
* a);
2956
N/A
}
else
{
2956
N/A
zeroes
[
ret
++] = (-b +
sqrtDis
) / (
2
* a);
2956
N/A
zeroes
[
ret
++] = (
2
* c) / (-b +
sqrtDis
);
2956
N/A
}
2956
N/A
}
else
if
(
dis
==
0f
) {
2956
N/A
t = (-b) / (
2
* a);
2956
N/A
zeroes
[
ret
++] = t;
2956
N/A
}
2956
N/A
}
else
{
2956
N/A
if
(b !=
0f
) {
2956
N/A
t = (-c) / b;
2956
N/A
zeroes
[
ret
++] = t;
2956
N/A
}
2956
N/A
}
2956
N/A
return
ret
-
off
;
2956
N/A
}
2956
N/A
3444
N/A
// find the roots of g(t) = d*t^3 + a*t^2 + b*t + c in [A,B)
3444
N/A
static
int
cubicRootsInAB
(
float
d,
float
a,
float
b,
float
c,
3444
N/A
float
[]
pts
,
final
int
off
,
2956
N/A
final
float
A,
final
float
B)
2956
N/A
{
3444
N/A
if
(d ==
0
) {
3444
N/A
int
num
=
quadraticRoots
(a, b, c,
pts
,
off
);
3444
N/A
return
filterOutNotInAB
(
pts
,
off
,
num
, A, B) -
off
;
2956
N/A
}
3444
N/A
// From Graphics Gems:
3444
N/A
//
http://tog.acm.org/resources/GraphicsGems/gems/Roots3And4.c
3444
N/A
// (also from awt.geom.CubicCurve2D. But here we don't need as
3444
N/A
// much accuracy and we don't want to create arrays so we use
3444
N/A
// our own customized version).
3444
N/A
3444
N/A
/* normal form: x^3 + ax^2 + bx + c = 0 */
3444
N/A
a /= d;
3444
N/A
b /= d;
3444
N/A
c /= d;
3444
N/A
3444
N/A
// substitute x = y - A/3 to eliminate quadratic term:
3444
N/A
// x^3 +Px + Q = 0
3444
N/A
//
3444
N/A
// Since we actually need P/3 and Q/2 for all of the
3444
N/A
// calculations that follow, we will calculate
3444
N/A
// p = P/3
3444
N/A
// q = Q/2
3444
N/A
// instead and use those values for simplicity of the code.
3444
N/A
double
sq_A
= a * a;
3444
N/A
double
p =
1.0
/
3
* (-
1.0
/
3
*
sq_A
+ b);
3444
N/A
double
q =
1.0
/
2
* (
2.0
/
27
* a *
sq_A
-
1.0
/
3
* a * b + c);
3444
N/A
3444
N/A
/* use Cardano's formula */
3444
N/A
3444
N/A
double
cb_p
= p * p * p;
3444
N/A
double
D = q * q +
cb_p
;
3444
N/A
3444
N/A
int
num
;
3444
N/A
if
(D <
0
) {
3444
N/A
// see:
http://en.wikipedia.org/wiki/Cubic_function
#Trigonometric_.28and_hyperbolic.29_method
3444
N/A
final
double
phi
=
1.0
/
3
*
acos
(-q /
sqrt
(-
cb_p
));
3444
N/A
final
double
t =
2
*
sqrt
(-p);
3444
N/A
3444
N/A
pts
[
off
+
0
] = (
float
)( t *
cos
(
phi
));
3444
N/A
pts
[
off
+
1
] = (
float
)(-t *
cos
(
phi
+
PI
/
3
));
3444
N/A
pts
[
off
+
2
] = (
float
)(-t *
cos
(
phi
-
PI
/
3
));
3444
N/A
num
=
3
;
3444
N/A
}
else
{
3444
N/A
final
double
sqrt_D
=
sqrt
(D);
3444
N/A
final
double
u =
cbrt
(
sqrt_D
- q);
3444
N/A
final
double
v = -
cbrt
(
sqrt_D
+ q);
3444
N/A
3444
N/A
pts
[
off
] = (
float
)(u + v);
3444
N/A
num
=
1
;
3444
N/A
3444
N/A
if
(
within
(D,
0
,
1e-8
)) {
3444
N/A
pts
[
off
+
1
] = -(
pts
[
off
] /
2
);
3444
N/A
num
=
2
;
3444
N/A
}
2956
N/A
}
2956
N/A
3444
N/A
final
float
sub
=
1.0f
/
3
* a;
2956
N/A
3444
N/A
for
(
int
i =
0
; i <
num
; ++i) {
3444
N/A
pts
[
off
+i ] -=
sub
;
2956
N/A
}
2956
N/A
3444
N/A
return
filterOutNotInAB
(
pts
,
off
,
num
, A, B) -
off
;
2956
N/A
}
2956
N/A
2956
N/A
// These use a hardcoded factor of 2 for increasing sizes. Perhaps this
2956
N/A
// should be provided as an argument.
2956
N/A
static
float
[]
widenArray
(
float
[]
in
,
final
int
cursize
,
final
int
numToAdd
) {
2956
N/A
if
(
in
.
length
>=
cursize
+
numToAdd
) {
2956
N/A
return
in
;
2956
N/A
}
2956
N/A
return
Arrays
.
copyOf
(
in
,
2
* (
cursize
+
numToAdd
));
2956
N/A
}
3444
N/A
2956
N/A
static
int
[]
widenArray
(
int
[]
in
,
final
int
cursize
,
final
int
numToAdd
) {
2956
N/A
if
(
in
.
length
>=
cursize
+
numToAdd
) {
2956
N/A
return
in
;
2956
N/A
}
2956
N/A
return
Arrays
.
copyOf
(
in
,
2
* (
cursize
+
numToAdd
));
2956
N/A
}
2956
N/A
2956
N/A
static
float
evalCubic
(
final
float
a,
final
float
b,
2956
N/A
final
float
c,
final
float
d,
2956
N/A
final
float
t)
2956
N/A
{
2956
N/A
return
t * (t * (t * a + b) + c) + d;
2956
N/A
}
2956
N/A
2956
N/A
static
float
evalQuad
(
final
float
a,
final
float
b,
2956
N/A
final
float
c,
final
float
t)
2956
N/A
{
2956
N/A
return
t * (t * a + b) + c;
2956
N/A
}
2956
N/A
2956
N/A
// returns the index 1 past the last valid element remaining after filtering
2956
N/A
static
int
filterOutNotInAB
(
float
[]
nums
,
final
int
off
,
final
int
len
,
2956
N/A
final
float
a,
final
float
b)
2956
N/A
{
2956
N/A
int
ret
=
off
;
2956
N/A
for
(
int
i =
off
; i <
off
+
len
; i++) {
3444
N/A
if
(
nums
[i] >= a &&
nums
[i] < b) {
2956
N/A
nums
[
ret
++] =
nums
[i];
2956
N/A
}
2956
N/A
}
2956
N/A
return
ret
;
2956
N/A
}
2956
N/A
2956
N/A
static
float
polyLineLength
(
float
[]
poly
,
final
int
off
,
final
int
nCoords
) {
2956
N/A
assert
nCoords
%
2
==
0
&&
poly
.
length
>=
off
+
nCoords
:
""
;
2956
N/A
float
acc
=
0
;
2956
N/A
for
(
int
i =
off
+
2
; i <
off
+
nCoords
; i +=
2
) {
2956
N/A
acc
+=
linelen
(
poly
[i],
poly
[i+
1
],
poly
[i-
2
],
poly
[i-
1
]);
2956
N/A
}
2956
N/A
return
acc
;
2956
N/A
}
2956
N/A
2956
N/A
static
float
linelen
(
float
x1
,
float
y1
,
float
x2
,
float
y2
) {
3444
N/A
final
float
dx
=
x2
-
x1
;
3444
N/A
final
float
dy
=
y2
-
y1
;
3444
N/A
return
(
float
)
Math
.
sqrt
(
dx
*
dx
+
dy
*
dy
);
2956
N/A
}
2956
N/A
2956
N/A
static
void
subdivide
(
float
[]
src
,
int
srcoff
,
float
[]
left
,
int
leftoff
,
2956
N/A
float
[]
right
,
int
rightoff
,
int
type
)
2956
N/A
{
2956
N/A
switch
(
type
) {
2956
N/A
case
6
:
2956
N/A
Helpers
.
subdivideQuad
(
src
,
srcoff
,
left
,
leftoff
,
right
,
rightoff
);
2956
N/A
break
;
2956
N/A
case
8
:
2956
N/A
Helpers
.
subdivideCubic
(
src
,
srcoff
,
left
,
leftoff
,
right
,
rightoff
);
2956
N/A
break
;
2956
N/A
default
:
2956
N/A
throw
new
InternalError
(
"Unsupported curve type"
);
2956
N/A
}
2956
N/A
}
2956
N/A
2956
N/A
static
void
isort
(
float
[] a,
int
off
,
int
len
) {
2956
N/A
for
(
int
i =
off
+
1
; i <
off
+
len
; i++) {
2956
N/A
float
ai
= a[i];
2956
N/A
int
j = i -
1
;
2956
N/A
for
(; j >=
off
&& a[j] >
ai
; j--) {
2956
N/A
a[j+
1
] = a[j];
2956
N/A
}
2956
N/A
a[j+
1
] =
ai
;
2956
N/A
}
2956
N/A
}
2956
N/A
2956
N/A
// Most of these are copied from classes in java.awt.geom because we need
2956
N/A
// float versions of these functions, and Line2D, CubicCurve2D,
2956
N/A
// QuadCurve2D don't provide them.
2956
N/A
/**
2956
N/A
* Subdivides the cubic curve specified by the coordinates
2956
N/A
* stored in the <code>src</code> array at indices <code>srcoff</code>
2956
N/A
* through (<code>srcoff</code> + 7) and stores the
2956
N/A
* resulting two subdivided curves into the two result arrays at the
2956
N/A
* corresponding indices.
2956
N/A
* Either or both of the <code>left</code> and <code>right</code>
2956
N/A
* arrays may be <code>null</code> or a reference to the same array
2956
N/A
* as the <code>src</code> array.
2956
N/A
* Note that the last point in the first subdivided curve is the
2956
N/A
* same as the first point in the second subdivided curve. Thus,
2956
N/A
* it is possible to pass the same array for <code>left</code>
2956
N/A
* and <code>right</code> and to use offsets, such as <code>rightoff</code>
2956
N/A
* equals (<code>leftoff</code> + 6), in order
2956
N/A
* to avoid allocating extra storage for this common point.
2956
N/A
*
@param
src
the array holding the coordinates for the source curve
2956
N/A
*
@param
srcoff
the offset into the array of the beginning of the
2956
N/A
* the 6 source coordinates
2956
N/A
*
@param
left
the array for storing the coordinates for the first
2956
N/A
* half of the subdivided curve
2956
N/A
*
@param
leftoff
the offset into the array of the beginning of the
2956
N/A
* the 6 left coordinates
2956
N/A
*
@param
right
the array for storing the coordinates for the second
2956
N/A
* half of the subdivided curve
2956
N/A
*
@param
rightoff
the offset into the array of the beginning of the
2956
N/A
* the 6 right coordinates
2956
N/A
*
@since
1.7
2956
N/A
*/
2956
N/A
static
void
subdivideCubic
(
float
src
[],
int
srcoff
,
2956
N/A
float
left
[],
int
leftoff
,
2956
N/A
float
right
[],
int
rightoff
)
2956
N/A
{
2956
N/A
float
x1
=
src
[
srcoff
+
0
];
2956
N/A
float
y1
=
src
[
srcoff
+
1
];
2956
N/A
float
ctrlx1
=
src
[
srcoff
+
2
];
2956
N/A
float
ctrly1
=
src
[
srcoff
+
3
];
2956
N/A
float
ctrlx2
=
src
[
srcoff
+
4
];
2956
N/A
float
ctrly2
=
src
[
srcoff
+
5
];
2956
N/A
float
x2
=
src
[
srcoff
+
6
];
2956
N/A
float
y2
=
src
[
srcoff
+
7
];
2956
N/A
if
(
left
!=
null
) {
2956
N/A
left
[
leftoff
+
0
] =
x1
;
2956
N/A
left
[
leftoff
+
1
] =
y1
;
2956
N/A
}
2956
N/A
if
(
right
!=
null
) {
2956
N/A
right
[
rightoff
+
6
] =
x2
;
2956
N/A
right
[
rightoff
+
7
] =
y2
;
2956
N/A
}
2956
N/A
x1
= (
x1
+
ctrlx1
) /
2.0f
;
2956
N/A
y1
= (
y1
+
ctrly1
) /
2.0f
;
2956
N/A
x2
= (
x2
+
ctrlx2
) /
2.0f
;
2956
N/A
y2
= (
y2
+
ctrly2
) /
2.0f
;
2956
N/A
float
centerx
= (
ctrlx1
+
ctrlx2
) /
2.0f
;
2956
N/A
float
centery
= (
ctrly1
+
ctrly2
) /
2.0f
;
2956
N/A
ctrlx1
= (
x1
+
centerx
) /
2.0f
;
2956
N/A
ctrly1
= (
y1
+
centery
) /
2.0f
;
2956
N/A
ctrlx2
= (
x2
+
centerx
) /
2.0f
;
2956
N/A
ctrly2
= (
y2
+
centery
) /
2.0f
;
2956
N/A
centerx
= (
ctrlx1
+
ctrlx2
) /
2.0f
;
2956
N/A
centery
= (
ctrly1
+
ctrly2
) /
2.0f
;
2956
N/A
if
(
left
!=
null
) {
2956
N/A
left
[
leftoff
+
2
] =
x1
;
2956
N/A
left
[
leftoff
+
3
] =
y1
;
2956
N/A
left
[
leftoff
+
4
] =
ctrlx1
;
2956
N/A
left
[
leftoff
+
5
] =
ctrly1
;
2956
N/A
left
[
leftoff
+
6
] =
centerx
;
2956
N/A
left
[
leftoff
+
7
] =
centery
;
2956
N/A
}
2956
N/A
if
(
right
!=
null
) {
2956
N/A
right
[
rightoff
+
0
] =
centerx
;
2956
N/A
right
[
rightoff
+
1
] =
centery
;
2956
N/A
right
[
rightoff
+
2
] =
ctrlx2
;
2956
N/A
right
[
rightoff
+
3
] =
ctrly2
;
2956
N/A
right
[
rightoff
+
4
] =
x2
;
2956
N/A
right
[
rightoff
+
5
] =
y2
;
2956
N/A
}
2956
N/A
}
2956
N/A
2956
N/A
2956
N/A
static
void
subdivideCubicAt
(
float
t,
float
src
[],
int
srcoff
,
2956
N/A
float
left
[],
int
leftoff
,
2956
N/A
float
right
[],
int
rightoff
)
2956
N/A
{
2956
N/A
float
x1
=
src
[
srcoff
+
0
];
2956
N/A
float
y1
=
src
[
srcoff
+
1
];
2956
N/A
float
ctrlx1
=
src
[
srcoff
+
2
];
2956
N/A
float
ctrly1
=
src
[
srcoff
+
3
];
2956
N/A
float
ctrlx2
=
src
[
srcoff
+
4
];
2956
N/A
float
ctrly2
=
src
[
srcoff
+
5
];
2956
N/A
float
x2
=
src
[
srcoff
+
6
];
2956
N/A
float
y2
=
src
[
srcoff
+
7
];
2956
N/A
if
(
left
!=
null
) {
2956
N/A
left
[
leftoff
+
0
] =
x1
;
2956
N/A
left
[
leftoff
+
1
] =
y1
;
2956
N/A
}
2956
N/A
if
(
right
!=
null
) {
2956
N/A
right
[
rightoff
+
6
] =
x2
;
2956
N/A
right
[
rightoff
+
7
] =
y2
;
2956
N/A
}
2956
N/A
x1
=
x1
+ t * (
ctrlx1
-
x1
);
2956
N/A
y1
=
y1
+ t * (
ctrly1
-
y1
);
2956
N/A
x2
=
ctrlx2
+ t * (
x2
-
ctrlx2
);
2956
N/A
y2
=
ctrly2
+ t * (
y2
-
ctrly2
);
2956
N/A
float
centerx
=
ctrlx1
+ t * (
ctrlx2
-
ctrlx1
);
2956
N/A
float
centery
=
ctrly1
+ t * (
ctrly2
-
ctrly1
);
2956
N/A
ctrlx1
=
x1
+ t * (
centerx
-
x1
);
2956
N/A
ctrly1
=
y1
+ t * (
centery
-
y1
);
2956
N/A
ctrlx2
=
centerx
+ t * (
x2
-
centerx
);
2956
N/A
ctrly2
=
centery
+ t * (
y2
-
centery
);
2956
N/A
centerx
=
ctrlx1
+ t * (
ctrlx2
-
ctrlx1
);
2956
N/A
centery
=
ctrly1
+ t * (
ctrly2
-
ctrly1
);
2956
N/A
if
(
left
!=
null
) {
2956
N/A
left
[
leftoff
+
2
] =
x1
;
2956
N/A
left
[
leftoff
+
3
] =
y1
;
2956
N/A
left
[
leftoff
+
4
] =
ctrlx1
;
2956
N/A
left
[
leftoff
+
5
] =
ctrly1
;
2956
N/A
left
[
leftoff
+
6
] =
centerx
;
2956
N/A
left
[
leftoff
+
7
] =
centery
;
2956
N/A
}
2956
N/A
if
(
right
!=
null
) {
2956
N/A
right
[
rightoff
+
0
] =
centerx
;
2956
N/A
right
[
rightoff
+
1
] =
centery
;
2956
N/A
right
[
rightoff
+
2
] =
ctrlx2
;
2956
N/A
right
[
rightoff
+
3
] =
ctrly2
;
2956
N/A
right
[
rightoff
+
4
] =
x2
;
2956
N/A
right
[
rightoff
+
5
] =
y2
;
2956
N/A
}
2956
N/A
}
2956
N/A
2956
N/A
static
void
subdivideQuad
(
float
src
[],
int
srcoff
,
2956
N/A
float
left
[],
int
leftoff
,
2956
N/A
float
right
[],
int
rightoff
)
2956
N/A
{
2956
N/A
float
x1
=
src
[
srcoff
+
0
];
2956
N/A
float
y1
=
src
[
srcoff
+
1
];
2956
N/A
float
ctrlx
=
src
[
srcoff
+
2
];
2956
N/A
float
ctrly
=
src
[
srcoff
+
3
];
2956
N/A
float
x2
=
src
[
srcoff
+
4
];
2956
N/A
float
y2
=
src
[
srcoff
+
5
];
2956
N/A
if
(
left
!=
null
) {
2956
N/A
left
[
leftoff
+
0
] =
x1
;
2956
N/A
left
[
leftoff
+
1
] =
y1
;
2956
N/A
}
2956
N/A
if
(
right
!=
null
) {
2956
N/A
right
[
rightoff
+
4
] =
x2
;
2956
N/A
right
[
rightoff
+
5
] =
y2
;
2956
N/A
}
2956
N/A
x1
= (
x1
+
ctrlx
) /
2.0f
;
2956
N/A
y1
= (
y1
+
ctrly
) /
2.0f
;
2956
N/A
x2
= (
x2
+
ctrlx
) /
2.0f
;
2956
N/A
y2
= (
y2
+
ctrly
) /
2.0f
;
2956
N/A
ctrlx
= (
x1
+
x2
) /
2.0f
;
2956
N/A
ctrly
= (
y1
+
y2
) /
2.0f
;
2956
N/A
if
(
left
!=
null
) {
2956
N/A
left
[
leftoff
+
2
] =
x1
;
2956
N/A
left
[
leftoff
+
3
] =
y1
;
2956
N/A
left
[
leftoff
+
4
] =
ctrlx
;
2956
N/A
left
[
leftoff
+
5
] =
ctrly
;
2956
N/A
}
2956
N/A
if
(
right
!=
null
) {
2956
N/A
right
[
rightoff
+
0
] =
ctrlx
;
2956
N/A
right
[
rightoff
+
1
] =
ctrly
;
2956
N/A
right
[
rightoff
+
2
] =
x2
;
2956
N/A
right
[
rightoff
+
3
] =
y2
;
2956
N/A
}
2956
N/A
}
2956
N/A
2956
N/A
static
void
subdivideQuadAt
(
float
t,
float
src
[],
int
srcoff
,
2956
N/A
float
left
[],
int
leftoff
,
2956
N/A
float
right
[],
int
rightoff
)
2956
N/A
{
2956
N/A
float
x1
=
src
[
srcoff
+
0
];
2956
N/A
float
y1
=
src
[
srcoff
+
1
];
2956
N/A
float
ctrlx
=
src
[
srcoff
+
2
];
2956
N/A
float
ctrly
=
src
[
srcoff
+
3
];
2956
N/A
float
x2
=
src
[
srcoff
+
4
];
2956
N/A
float
y2
=
src
[
srcoff
+
5
];
2956
N/A
if
(
left
!=
null
) {
2956
N/A
left
[
leftoff
+
0
] =
x1
;
2956
N/A
left
[
leftoff
+
1
] =
y1
;
2956
N/A
}
2956
N/A
if
(
right
!=
null
) {
2956
N/A
right
[
rightoff
+
4
] =
x2
;
2956
N/A
right
[
rightoff
+
5
] =
y2
;
2956
N/A
}
2956
N/A
x1
=
x1
+ t * (
ctrlx
-
x1
);
2956
N/A
y1
=
y1
+ t * (
ctrly
-
y1
);
2956
N/A
x2
=
ctrlx
+ t * (
x2
-
ctrlx
);
2956
N/A
y2
=
ctrly
+ t * (
y2
-
ctrly
);
2956
N/A
ctrlx
=
x1
+ t * (
x2
-
x1
);
2956
N/A
ctrly
=
y1
+ t * (
y2
-
y1
);
2956
N/A
if
(
left
!=
null
) {
2956
N/A
left
[
leftoff
+
2
] =
x1
;
2956
N/A
left
[
leftoff
+
3
] =
y1
;
2956
N/A
left
[
leftoff
+
4
] =
ctrlx
;
2956
N/A
left
[
leftoff
+
5
] =
ctrly
;
2956
N/A
}
2956
N/A
if
(
right
!=
null
) {
2956
N/A
right
[
rightoff
+
0
] =
ctrlx
;
2956
N/A
right
[
rightoff
+
1
] =
ctrly
;
2956
N/A
right
[
rightoff
+
2
] =
x2
;
2956
N/A
right
[
rightoff
+
3
] =
y2
;
2956
N/A
}
2956
N/A
}
2956
N/A
2956
N/A
static
void
subdivideAt
(
float
t,
float
src
[],
int
srcoff
,
2956
N/A
float
left
[],
int
leftoff
,
2956
N/A
float
right
[],
int
rightoff
,
int
size
)
2956
N/A
{
2956
N/A
switch
(
size
) {
2956
N/A
case
8
:
2956
N/A
subdivideCubicAt
(t,
src
,
srcoff
,
left
,
leftoff
,
right
,
rightoff
);
2956
N/A
break
;
2956
N/A
case
6
:
2956
N/A
subdivideQuadAt
(t,
src
,
srcoff
,
left
,
leftoff
,
right
,
rightoff
);
2956
N/A
break
;
2956
N/A
}
2956
N/A
}
2956
N/A
}