Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
7e6b52e8
Commit
7e6b52e8
authored
Oct 06, 2015
by
Henri Verbeet
Committed by
Alexandre Julliard
Oct 07, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
d2d1: Implement d2d_cdt_incircle() in a more robust way.
Signed-off-by:
Henri Verbeet
<
hverbeet@codeweavers.com
>
parent
e8b4d8e0
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
327 additions
and
9 deletions
+327
-9
geometry.c
dlls/d2d1/geometry.c
+327
-9
No files found.
dlls/d2d1/geometry.c
View file @
7e6b52e8
...
...
@@ -86,6 +86,12 @@ struct d2d_fp_two_vec2
float
y
[
2
];
};
struct
d2d_fp_fin
{
float
*
now
,
*
other
;
size_t
length
;
};
static
void
d2d_fp_two_sum
(
float
*
out
,
float
a
,
float
b
)
{
float
a_virt
,
a_round
,
b_virt
,
b_round
;
...
...
@@ -107,6 +113,16 @@ static void d2d_fp_fast_two_sum(float *out, float a, float b)
out
[
0
]
=
b
-
b_virt
;
}
static
void
d2d_fp_two_two_sum
(
float
*
out
,
const
float
*
a
,
const
float
*
b
)
{
float
sum
[
2
];
d2d_fp_two_sum
(
out
,
a
[
0
],
b
[
0
]);
d2d_fp_two_sum
(
sum
,
a
[
1
],
out
[
1
]);
d2d_fp_two_sum
(
&
out
[
1
],
sum
[
0
],
b
[
1
]);
d2d_fp_two_sum
(
&
out
[
2
],
sum
[
1
],
out
[
2
]);
}
static
void
d2d_fp_two_diff_tail
(
float
*
out
,
float
a
,
float
b
,
float
x
)
{
float
a_virt
,
a_round
,
b_virt
,
b_round
;
...
...
@@ -160,6 +176,17 @@ static void d2d_fp_two_product(float *out, float a, float b)
d2d_fp_two_product_presplit
(
out
,
a
,
b
,
b_split
);
}
static
void
d2d_fp_square
(
float
*
out
,
float
a
)
{
float
a_split
[
2
],
err1
,
err2
;
out
[
1
]
=
a
*
a
;
d2d_fp_split
(
a_split
,
a
);
err1
=
out
[
1
]
-
(
a_split
[
1
]
*
a_split
[
1
]);
err2
=
err1
-
((
a_split
[
1
]
+
a_split
[
1
])
*
a_split
[
0
]);
out
[
0
]
=
(
a_split
[
0
]
*
a_split
[
0
])
-
err2
;
}
static
float
d2d_fp_estimate
(
float
*
a
,
size_t
len
)
{
float
out
=
a
[
0
];
...
...
@@ -245,6 +272,33 @@ static void d2d_fp_fast_expansion_sum_zeroelim(float *out, size_t *out_len,
*
out_len
=
out_idx
;
}
static
void
d2d_fp_scale_expansion_zeroelim
(
float
*
out
,
size_t
*
out_len
,
const
float
*
a
,
size_t
a_len
,
float
b
)
{
float
product
[
2
],
sum
[
2
],
b_split
[
2
],
q
[
2
],
a_curr
;
size_t
a_idx
,
out_idx
;
d2d_fp_split
(
b_split
,
b
);
d2d_fp_two_product_presplit
(
q
,
a
[
0
],
b
,
b_split
);
out_idx
=
0
;
if
(
q
[
0
]
!=
0
.
0
f
)
out
[
out_idx
++
]
=
q
[
0
];
for
(
a_idx
=
1
;
a_idx
<
a_len
;
++
a_idx
)
{
a_curr
=
a
[
a_idx
];
d2d_fp_two_product_presplit
(
product
,
a_curr
,
b
,
b_split
);
d2d_fp_two_sum
(
sum
,
q
[
1
],
product
[
0
]);
if
(
sum
[
0
]
!=
0
.
0
f
)
out
[
out_idx
++
]
=
sum
[
0
];
d2d_fp_fast_two_sum
(
q
,
product
[
1
],
sum
[
1
]);
if
(
q
[
0
]
!=
0
.
0
f
)
out
[
out_idx
++
]
=
q
[
0
];
}
if
(
q
[
1
]
!=
0
.
0
f
||
!
out_idx
)
out
[
out_idx
++
]
=
q
[
1
];
*
out_len
=
out_idx
;
}
static
void
d2d_point_subtract
(
D2D1_POINT_2F
*
out
,
const
D2D1_POINT_2F
*
a
,
const
D2D1_POINT_2F
*
b
)
{
...
...
@@ -520,6 +574,153 @@ static BOOL d2d_cdt_leftof(const struct d2d_cdt *cdt, size_t p, const struct d2d
return
d2d_cdt_ccw
(
cdt
,
p
,
d2d_cdt_edge_origin
(
cdt
,
e
),
d2d_cdt_edge_destination
(
cdt
,
e
))
>
0
.
0
f
;
}
/* |ax ay|
* |bx by| */
static
void
d2d_fp_four_det2x2
(
float
*
out
,
float
ax
,
float
ay
,
float
bx
,
float
by
)
{
float
axby
[
2
],
aybx
[
2
];
d2d_fp_two_product
(
axby
,
ax
,
by
);
d2d_fp_two_product
(
aybx
,
ay
,
bx
);
d2d_fp_two_two_diff
(
out
,
axby
,
aybx
);
}
/* (a->x² + a->y²) * det2x2 */
static
void
d2d_fp_sub_det3x3
(
float
*
out
,
size_t
*
out_len
,
const
struct
d2d_fp_two_vec2
*
a
,
const
float
*
det2x2
)
{
size_t
axd_len
,
ayd_len
,
axxd_len
,
ayyd_len
;
float
axd
[
8
],
ayd
[
8
],
axxd
[
16
],
ayyd
[
16
];
d2d_fp_scale_expansion_zeroelim
(
axd
,
&
axd_len
,
det2x2
,
4
,
a
->
x
[
1
]);
d2d_fp_scale_expansion_zeroelim
(
axxd
,
&
axxd_len
,
axd
,
axd_len
,
a
->
x
[
1
]);
d2d_fp_scale_expansion_zeroelim
(
ayd
,
&
ayd_len
,
det2x2
,
4
,
a
->
y
[
1
]);
d2d_fp_scale_expansion_zeroelim
(
ayyd
,
&
ayyd_len
,
ayd
,
ayd_len
,
a
->
y
[
1
]);
d2d_fp_fast_expansion_sum_zeroelim
(
out
,
out_len
,
axxd
,
axxd_len
,
ayyd
,
ayyd_len
);
}
/* det_abt = det_ab * c[0]
* fin += c[0] * (az * b - bz * a + c[1] * det_ab * 2.0f) */
static
void
d2d_cdt_incircle_refine1
(
struct
d2d_fp_fin
*
fin
,
float
*
det_abt
,
size_t
*
det_abt_len
,
const
float
*
det_ab
,
float
a
,
const
float
*
az
,
float
b
,
const
float
*
bz
,
const
float
*
c
)
{
size_t
temp48_len
,
temp32_len
,
temp16a_len
,
temp16b_len
,
temp16c_len
,
temp8_len
;
float
temp48
[
48
],
temp32
[
32
],
temp16a
[
16
],
temp16b
[
16
],
temp16c
[
16
],
temp8
[
8
];
float
*
swap
;
d2d_fp_scale_expansion_zeroelim
(
det_abt
,
det_abt_len
,
det_ab
,
4
,
c
[
0
]);
d2d_fp_scale_expansion_zeroelim
(
temp16a
,
&
temp16a_len
,
det_abt
,
*
det_abt_len
,
2
.
0
f
*
c
[
1
]);
d2d_fp_scale_expansion_zeroelim
(
temp8
,
&
temp8_len
,
az
,
4
,
c
[
0
]);
d2d_fp_scale_expansion_zeroelim
(
temp16b
,
&
temp16b_len
,
temp8
,
temp8_len
,
b
);
d2d_fp_scale_expansion_zeroelim
(
temp8
,
&
temp8_len
,
bz
,
4
,
c
[
0
]);
d2d_fp_scale_expansion_zeroelim
(
temp16c
,
&
temp16c_len
,
temp8
,
temp8_len
,
-
a
);
d2d_fp_fast_expansion_sum_zeroelim
(
temp32
,
&
temp32_len
,
temp16a
,
temp16a_len
,
temp16b
,
temp16b_len
);
d2d_fp_fast_expansion_sum_zeroelim
(
temp48
,
&
temp48_len
,
temp16c
,
temp16c_len
,
temp32
,
temp32_len
);
d2d_fp_fast_expansion_sum_zeroelim
(
fin
->
other
,
&
fin
->
length
,
fin
->
now
,
fin
->
length
,
temp48
,
temp48_len
);
swap
=
fin
->
now
;
fin
->
now
=
fin
->
other
;
fin
->
other
=
swap
;
}
static
void
d2d_cdt_incircle_refine2
(
struct
d2d_fp_fin
*
fin
,
const
struct
d2d_fp_two_vec2
*
a
,
const
struct
d2d_fp_two_vec2
*
b
,
const
float
*
bz
,
const
struct
d2d_fp_two_vec2
*
c
,
const
float
*
cz
,
const
float
*
axt_det_bc
,
size_t
axt_det_bc_len
,
const
float
*
ayt_det_bc
,
size_t
ayt_det_bc_len
)
{
size_t
temp64_len
,
temp48_len
,
temp32a_len
,
temp32b_len
,
temp16a_len
,
temp16b_len
,
temp8_len
;
float
temp64
[
64
],
temp48
[
48
],
temp32a
[
32
],
temp32b
[
32
],
temp16a
[
16
],
temp16b
[
16
],
temp8
[
8
];
float
bct
[
8
],
bctt
[
4
],
temp4a
[
4
],
temp4b
[
4
],
temp2a
[
2
],
temp2b
[
2
];
size_t
bct_len
,
bctt_len
;
float
*
swap
;
/* bct = (b->x[0] * c->y[1] + b->x[1] * c->y[0]) - (c->x[0] * b->y[1] + c->x[1] * b->y[0]) */
/* bctt = b->x[0] * c->y[0] + c->x[0] * b->y[0] */
if
(
b
->
x
[
0
]
!=
0
.
0
f
||
b
->
y
[
0
]
!=
0
.
0
f
||
c
->
x
[
0
]
!=
0
.
0
f
||
c
->
y
[
0
]
!=
0
.
0
f
)
{
d2d_fp_two_product
(
temp2a
,
b
->
x
[
0
],
c
->
y
[
1
]);
d2d_fp_two_product
(
temp2b
,
b
->
x
[
1
],
c
->
y
[
0
]);
d2d_fp_two_two_sum
(
temp4a
,
temp2a
,
temp2b
);
d2d_fp_two_product
(
temp2a
,
c
->
x
[
0
],
-
b
->
y
[
1
]);
d2d_fp_two_product
(
temp2b
,
c
->
x
[
1
],
-
b
->
y
[
0
]);
d2d_fp_two_two_sum
(
temp4b
,
temp2a
,
temp2b
);
d2d_fp_fast_expansion_sum_zeroelim
(
bct
,
&
bct_len
,
temp4a
,
4
,
temp4b
,
4
);
d2d_fp_two_product
(
temp2a
,
b
->
x
[
0
],
c
->
y
[
0
]);
d2d_fp_two_product
(
temp2b
,
c
->
x
[
0
],
b
->
y
[
0
]);
d2d_fp_two_two_diff
(
bctt
,
temp2a
,
temp2b
);
bctt_len
=
4
;
}
else
{
bct
[
0
]
=
0
.
0
f
;
bct_len
=
1
;
bctt
[
0
]
=
0
.
0
f
;
bctt_len
=
1
;
}
if
(
a
->
x
[
0
]
!=
0
.
0
f
)
{
size_t
axt_bct_len
,
axt_bctt_len
;
float
axt_bct
[
16
],
axt_bctt
[
8
];
/* fin += a->x[0] * (axt_det_bc + bct * 2.0f * a->x[1]) */
d2d_fp_scale_expansion_zeroelim
(
temp16a
,
&
temp16a_len
,
axt_det_bc
,
axt_det_bc_len
,
a
->
x
[
0
]);
d2d_fp_scale_expansion_zeroelim
(
axt_bct
,
&
axt_bct_len
,
bct
,
bct_len
,
a
->
x
[
0
]);
d2d_fp_scale_expansion_zeroelim
(
temp32a
,
&
temp32a_len
,
axt_bct
,
axt_bct_len
,
2
.
0
f
*
a
->
x
[
1
]);
d2d_fp_fast_expansion_sum_zeroelim
(
temp48
,
&
temp48_len
,
temp16a
,
temp16a_len
,
temp32a
,
temp32a_len
);
d2d_fp_fast_expansion_sum_zeroelim
(
fin
->
other
,
&
fin
->
length
,
fin
->
now
,
fin
->
length
,
temp48
,
temp48_len
);
swap
=
fin
->
now
;
fin
->
now
=
fin
->
other
;
fin
->
other
=
swap
;
if
(
b
->
y
[
0
]
!=
0
.
0
f
)
{
/* fin += a->x[0] * cz * b->y[0] */
d2d_fp_scale_expansion_zeroelim
(
temp8
,
&
temp8_len
,
cz
,
4
,
a
->
x
[
0
]);
d2d_fp_scale_expansion_zeroelim
(
temp16a
,
&
temp16a_len
,
temp8
,
temp8_len
,
b
->
y
[
0
]);
d2d_fp_fast_expansion_sum_zeroelim
(
fin
->
other
,
&
fin
->
length
,
fin
->
now
,
fin
->
length
,
temp16a
,
temp16a_len
);
swap
=
fin
->
now
;
fin
->
now
=
fin
->
other
;
fin
->
other
=
swap
;
}
if
(
c
->
y
[
0
]
!=
0
.
0
f
)
{
/* fin -= a->x[0] * bz * c->y[0] */
d2d_fp_scale_expansion_zeroelim
(
temp8
,
&
temp8_len
,
bz
,
4
,
-
a
->
x
[
0
]);
d2d_fp_scale_expansion_zeroelim
(
temp16a
,
&
temp16a_len
,
temp8
,
temp8_len
,
c
->
y
[
0
]);
d2d_fp_fast_expansion_sum_zeroelim
(
fin
->
other
,
&
fin
->
length
,
fin
->
now
,
fin
->
length
,
temp16a
,
temp16a_len
);
swap
=
fin
->
now
;
fin
->
now
=
fin
->
other
;
fin
->
other
=
swap
;
}
/* fin += a->x[0] * (bct * a->x[0] + bctt * (2.0f * a->x[1] + a->x[0])) */
d2d_fp_scale_expansion_zeroelim
(
temp32a
,
&
temp32a_len
,
axt_bct
,
axt_bct_len
,
a
->
x
[
0
]);
d2d_fp_scale_expansion_zeroelim
(
axt_bctt
,
&
axt_bctt_len
,
bctt
,
bctt_len
,
a
->
x
[
0
]);
d2d_fp_scale_expansion_zeroelim
(
temp16a
,
&
temp16a_len
,
axt_bctt
,
axt_bctt_len
,
2
.
0
f
*
a
->
x
[
1
]);
d2d_fp_scale_expansion_zeroelim
(
temp16b
,
&
temp16b_len
,
axt_bctt
,
axt_bctt_len
,
a
->
x
[
0
]);
d2d_fp_fast_expansion_sum_zeroelim
(
temp32b
,
&
temp32b_len
,
temp16a
,
temp16a_len
,
temp16b
,
temp16b_len
);
d2d_fp_fast_expansion_sum_zeroelim
(
temp64
,
&
temp64_len
,
temp32a
,
temp32a_len
,
temp32b
,
temp32b_len
);
d2d_fp_fast_expansion_sum_zeroelim
(
fin
->
other
,
&
fin
->
length
,
fin
->
now
,
fin
->
length
,
temp64
,
temp64_len
);
swap
=
fin
->
now
;
fin
->
now
=
fin
->
other
;
fin
->
other
=
swap
;
}
if
(
a
->
y
[
0
]
!=
0
.
0
f
)
{
size_t
ayt_bct_len
,
ayt_bctt_len
;
float
ayt_bct
[
16
],
ayt_bctt
[
8
];
/* fin += a->y[0] * (ayt_det_bc + bct * 2.0f * a->y[1]) */
d2d_fp_scale_expansion_zeroelim
(
temp16a
,
&
temp16a_len
,
ayt_det_bc
,
ayt_det_bc_len
,
a
->
y
[
0
]);
d2d_fp_scale_expansion_zeroelim
(
ayt_bct
,
&
ayt_bct_len
,
bct
,
bct_len
,
a
->
y
[
0
]);
d2d_fp_scale_expansion_zeroelim
(
temp32a
,
&
temp32a_len
,
ayt_bct
,
ayt_bct_len
,
2
.
0
f
*
a
->
y
[
1
]);
d2d_fp_fast_expansion_sum_zeroelim
(
temp48
,
&
temp48_len
,
temp16a
,
temp16a_len
,
temp32a
,
temp32a_len
);
d2d_fp_fast_expansion_sum_zeroelim
(
fin
->
other
,
&
fin
->
length
,
fin
->
now
,
fin
->
length
,
temp48
,
temp48_len
);
swap
=
fin
->
now
;
fin
->
now
=
fin
->
other
;
fin
->
other
=
swap
;
/* fin += a->y[0] * (bct * a->y[0] + bctt * (2.0f * a->y[1] + a->y[0])) */
d2d_fp_scale_expansion_zeroelim
(
temp32a
,
&
temp32a_len
,
ayt_bct
,
ayt_bct_len
,
a
->
y
[
0
]);
d2d_fp_scale_expansion_zeroelim
(
ayt_bctt
,
&
ayt_bctt_len
,
bctt
,
bctt_len
,
a
->
y
[
0
]);
d2d_fp_scale_expansion_zeroelim
(
temp16a
,
&
temp16a_len
,
ayt_bctt
,
ayt_bctt_len
,
2
.
0
f
*
a
->
y
[
1
]);
d2d_fp_scale_expansion_zeroelim
(
temp16b
,
&
temp16b_len
,
ayt_bctt
,
ayt_bctt_len
,
a
->
y
[
0
]);
d2d_fp_fast_expansion_sum_zeroelim
(
temp32b
,
&
temp32b_len
,
temp16a
,
temp16a_len
,
temp16b
,
temp16b_len
);
d2d_fp_fast_expansion_sum_zeroelim
(
temp64
,
&
temp64_len
,
temp32a
,
temp32a_len
,
temp32b
,
temp32b_len
);
d2d_fp_fast_expansion_sum_zeroelim
(
fin
->
other
,
&
fin
->
length
,
fin
->
now
,
fin
->
length
,
temp64
,
temp64_len
);
swap
=
fin
->
now
;
fin
->
now
=
fin
->
other
;
fin
->
other
=
swap
;
}
}
/* Determine if point D is inside or outside the circle defined by points A,
* B, C. As explained in the paper by Guibas and Stolfi, this is equivalent to
* calculating the signed volume of the tetrahedron defined by projecting the
...
...
@@ -535,21 +736,138 @@ static BOOL d2d_cdt_leftof(const struct d2d_cdt *cdt, size_t p, const struct d2d
*
* |λ(A-D)|
* |λ(B-D)| > 0
* |λ(C-D)| */
* |λ(C-D)|
*
* This implementation is based on the paper "Adaptive Precision
* Floating-Point Arithmetic and Fast Robust Geometric Predicates" and
* associated (Public Domain) code by Jonathan Richard Shewchuk. */
static
BOOL
d2d_cdt_incircle
(
const
struct
d2d_cdt
*
cdt
,
size_t
a
,
size_t
b
,
size_t
c
,
size_t
d
)
{
static
const
float
err_bound_result
=
(
3
.
0
f
+
8
.
0
f
*
D2D_FP_EPS
)
*
D2D_FP_EPS
;
static
const
float
err_bound_a
=
(
10
.
0
f
+
96
.
0
f
*
D2D_FP_EPS
)
*
D2D_FP_EPS
;
static
const
float
err_bound_b
=
(
4
.
0
f
+
48
.
0
f
*
D2D_FP_EPS
)
*
D2D_FP_EPS
;
static
const
float
err_bound_c
=
(
44
.
0
f
+
576
.
0
f
*
D2D_FP_EPS
)
*
D2D_FP_EPS
*
D2D_FP_EPS
;
size_t
axt_det_bc_len
,
ayt_det_bc_len
,
bxt_det_ca_len
,
byt_det_ca_len
,
cxt_det_ab_len
,
cyt_det_ab_len
;
float
axt_det_bc
[
8
],
ayt_det_bc
[
8
],
bxt_det_ca
[
8
],
byt_det_ca
[
8
],
cxt_det_ab
[
8
],
cyt_det_ab
[
8
];
float
fin1
[
1152
],
fin2
[
1152
],
temp64
[
64
],
sub_det_a
[
32
],
sub_det_b
[
32
],
sub_det_c
[
32
];
float
det_bc
[
4
],
det_ca
[
4
],
det_ab
[
4
],
daz
[
4
],
dbz
[
4
],
dcz
[
4
],
temp2a
[
2
],
temp2b
[
2
];
size_t
temp64_len
,
sub_det_a_len
,
sub_det_b_len
,
sub_det_c_len
;
float
dbxdcy
,
dbydcx
,
dcxday
,
dcydax
,
daxdby
,
daydbx
;
const
D2D1_POINT_2F
*
p
=
cdt
->
vertices
;
const
struct
struct
d2d_fp_two_vec2
da
,
db
,
dc
;
float
permanent
,
err_bound
,
det
;
struct
d2d_fp_fin
fin
;
da
.
x
[
1
]
=
p
[
a
].
x
-
p
[
d
].
x
;
da
.
y
[
1
]
=
p
[
a
].
y
-
p
[
d
].
y
;
db
.
x
[
1
]
=
p
[
b
].
x
-
p
[
d
].
x
;
db
.
y
[
1
]
=
p
[
b
].
y
-
p
[
d
].
y
;
dc
.
x
[
1
]
=
p
[
c
].
x
-
p
[
d
].
x
;
dc
.
y
[
1
]
=
p
[
c
].
y
-
p
[
d
].
y
;
daz
[
3
]
=
da
.
x
[
1
]
*
da
.
x
[
1
]
+
da
.
y
[
1
]
*
da
.
y
[
1
];
dbxdcy
=
db
.
x
[
1
]
*
dc
.
y
[
1
];
dbydcx
=
db
.
y
[
1
]
*
dc
.
x
[
1
];
dbz
[
3
]
=
db
.
x
[
1
]
*
db
.
x
[
1
]
+
db
.
y
[
1
]
*
db
.
y
[
1
];
dcxday
=
dc
.
x
[
1
]
*
da
.
y
[
1
];
dcydax
=
dc
.
y
[
1
]
*
da
.
x
[
1
];
dcz
[
3
]
=
dc
.
x
[
1
]
*
dc
.
x
[
1
]
+
dc
.
y
[
1
]
*
dc
.
y
[
1
];
daxdby
=
da
.
x
[
1
]
*
db
.
y
[
1
];
daydbx
=
da
.
y
[
1
]
*
db
.
x
[
1
];
det
=
daz
[
3
]
*
(
dbxdcy
-
dbydcx
)
+
dbz
[
3
]
*
(
dcxday
-
dcydax
)
+
dcz
[
3
]
*
(
daxdby
-
daydbx
);
permanent
=
daz
[
3
]
*
(
fabsf
(
dbxdcy
)
+
fabsf
(
dbydcx
))
+
dbz
[
3
]
*
(
fabsf
(
dcxday
)
+
fabsf
(
dcydax
))
+
dcz
[
3
]
*
(
fabsf
(
daxdby
)
+
fabsf
(
daydbx
));
err_bound
=
err_bound_a
*
permanent
;
if
(
det
>
err_bound
||
-
det
>
err_bound
)
return
det
>
0
.
0
f
;
fin
.
now
=
fin1
;
fin
.
other
=
fin2
;
d2d_fp_four_det2x2
(
det_bc
,
db
.
x
[
1
],
db
.
y
[
1
],
dc
.
x
[
1
],
dc
.
y
[
1
]);
d2d_fp_sub_det3x3
(
sub_det_a
,
&
sub_det_a_len
,
&
da
,
det_bc
);
d2d_fp_four_det2x2
(
det_ca
,
dc
.
x
[
1
],
dc
.
y
[
1
],
da
.
x
[
1
],
da
.
y
[
1
]);
d2d_fp_sub_det3x3
(
sub_det_b
,
&
sub_det_b_len
,
&
db
,
det_ca
);
d2d_fp_four_det2x2
(
det_ab
,
da
.
x
[
1
],
da
.
y
[
1
],
db
.
x
[
1
],
db
.
y
[
1
]);
d2d_fp_sub_det3x3
(
sub_det_c
,
&
sub_det_c_len
,
&
dc
,
det_ab
);
d2d_fp_fast_expansion_sum_zeroelim
(
temp64
,
&
temp64_len
,
sub_det_a
,
sub_det_a_len
,
sub_det_b
,
sub_det_b_len
);
d2d_fp_fast_expansion_sum_zeroelim
(
fin
.
now
,
&
fin
.
length
,
temp64
,
temp64_len
,
sub_det_c
,
sub_det_c_len
);
det
=
d2d_fp_estimate
(
fin
.
now
,
fin
.
length
);
err_bound
=
err_bound_b
*
permanent
;
if
(
det
>=
err_bound
||
-
det
>=
err_bound
)
return
det
>
0
.
0
f
;
d2d_fp_two_diff_tail
(
&
da
.
x
[
0
],
p
[
a
].
x
,
p
[
d
].
x
,
da
.
x
[
1
]);
d2d_fp_two_diff_tail
(
&
da
.
y
[
0
],
p
[
a
].
y
,
p
[
d
].
y
,
da
.
y
[
1
]);
d2d_fp_two_diff_tail
(
&
db
.
x
[
0
],
p
[
b
].
x
,
p
[
d
].
x
,
db
.
x
[
1
]);
d2d_fp_two_diff_tail
(
&
db
.
y
[
0
],
p
[
b
].
y
,
p
[
d
].
y
,
db
.
y
[
1
]);
d2d_fp_two_diff_tail
(
&
dc
.
x
[
0
],
p
[
c
].
x
,
p
[
d
].
x
,
dc
.
x
[
1
]);
d2d_fp_two_diff_tail
(
&
dc
.
y
[
0
],
p
[
c
].
y
,
p
[
d
].
y
,
dc
.
y
[
1
]);
if
(
da
.
x
[
0
]
==
0
.
0
f
&&
db
.
x
[
0
]
==
0
.
0
f
&&
dc
.
x
[
0
]
==
0
.
0
f
&&
da
.
y
[
0
]
==
0
.
0
f
&&
db
.
y
[
0
]
==
0
.
0
f
&&
dc
.
y
[
0
]
==
0
.
0
f
)
return
det
>
0
.
0
f
;
err_bound
=
err_bound_c
*
permanent
+
err_bound_result
*
fabsf
(
det
);
det
+=
(
daz
[
3
]
*
((
db
.
x
[
1
]
*
dc
.
y
[
0
]
+
dc
.
y
[
1
]
*
db
.
x
[
0
])
-
(
db
.
y
[
1
]
*
dc
.
x
[
0
]
+
dc
.
x
[
1
]
*
db
.
y
[
0
]))
+
2
.
0
f
*
(
da
.
x
[
1
]
*
da
.
x
[
0
]
+
da
.
y
[
1
]
*
da
.
y
[
0
])
*
(
db
.
x
[
1
]
*
dc
.
y
[
1
]
-
db
.
y
[
1
]
*
dc
.
x
[
1
]))
+
(
dbz
[
3
]
*
((
dc
.
x
[
1
]
*
da
.
y
[
0
]
+
da
.
y
[
1
]
*
dc
.
x
[
0
])
-
(
dc
.
y
[
1
]
*
da
.
x
[
0
]
+
da
.
x
[
1
]
*
dc
.
y
[
0
]))
+
2
.
0
f
*
(
db
.
x
[
1
]
*
db
.
x
[
0
]
+
db
.
y
[
1
]
*
db
.
y
[
0
])
*
(
dc
.
x
[
1
]
*
da
.
y
[
1
]
-
dc
.
y
[
1
]
*
da
.
x
[
1
]))
+
(
dcz
[
3
]
*
((
da
.
x
[
1
]
*
db
.
y
[
0
]
+
db
.
y
[
1
]
*
da
.
x
[
0
])
-
(
da
.
y
[
1
]
*
db
.
x
[
0
]
+
db
.
x
[
1
]
*
da
.
y
[
0
]))
+
2
.
0
f
*
(
dc
.
x
[
1
]
*
dc
.
x
[
0
]
+
dc
.
y
[
1
]
*
dc
.
y
[
0
])
*
(
da
.
x
[
1
]
*
db
.
y
[
1
]
-
da
.
y
[
1
]
*
db
.
x
[
1
]));
if
(
det
>=
err_bound
||
-
det
>=
err_bound
)
return
det
>
0
.
0
f
;
if
(
db
.
x
[
0
]
!=
0
.
0
f
||
db
.
y
[
0
]
!=
0
.
0
f
||
dc
.
x
[
0
]
!=
0
.
0
f
||
dc
.
y
[
0
]
!=
0
.
0
f
)
{
d2d_fp_square
(
temp2a
,
da
.
x
[
1
]);
d2d_fp_square
(
temp2b
,
da
.
y
[
1
]);
d2d_fp_two_two_sum
(
daz
,
temp2a
,
temp2b
);
}
if
(
dc
.
x
[
0
]
!=
0
.
0
f
||
dc
.
y
[
0
]
!=
0
.
0
f
||
da
.
x
[
0
]
!=
0
.
0
f
||
da
.
y
[
0
]
!=
0
.
0
f
)
{
d2d_fp_square
(
temp2a
,
db
.
x
[
1
]);
d2d_fp_square
(
temp2b
,
db
.
y
[
1
]);
d2d_fp_two_two_sum
(
dbz
,
temp2a
,
temp2b
);
}
if
(
da
.
x
[
0
]
!=
0
.
0
f
||
da
.
y
[
0
]
!=
0
.
0
f
||
db
.
x
[
0
]
!=
0
.
0
f
||
db
.
y
[
0
]
!=
0
.
0
f
)
{
double
x
,
y
;
d2d_fp_square
(
temp2a
,
dc
.
x
[
1
]);
d2d_fp_square
(
temp2b
,
dc
.
y
[
1
]);
d2d_fp_two_two_sum
(
dcz
,
temp2a
,
temp2b
);
}
da
=
{
p
[
a
].
x
-
p
[
d
].
x
,
p
[
a
].
y
-
p
[
d
].
y
},
db
=
{
p
[
b
].
x
-
p
[
d
].
x
,
p
[
b
].
y
-
p
[
d
].
y
},
dc
=
{
p
[
c
].
x
-
p
[
d
].
x
,
p
[
c
].
y
-
p
[
d
].
y
};
return
(
da
.
x
*
da
.
x
+
da
.
y
*
da
.
y
)
*
(
db
.
x
*
dc
.
y
-
db
.
y
*
dc
.
x
)
+
(
db
.
x
*
db
.
x
+
db
.
y
*
db
.
y
)
*
(
dc
.
x
*
da
.
y
-
dc
.
y
*
da
.
x
)
+
(
dc
.
x
*
dc
.
x
+
dc
.
y
*
dc
.
y
)
*
(
da
.
x
*
db
.
y
-
da
.
y
*
db
.
x
)
>
0
.
0
;
if
(
da
.
x
[
0
]
!=
0
.
0
f
)
d2d_cdt_incircle_refine1
(
&
fin
,
axt_det_bc
,
&
axt_det_bc_len
,
det_bc
,
dc
.
y
[
1
],
dcz
,
db
.
y
[
1
],
dbz
,
da
.
x
);
if
(
da
.
y
[
0
]
!=
0
.
0
f
)
d2d_cdt_incircle_refine1
(
&
fin
,
ayt_det_bc
,
&
ayt_det_bc_len
,
det_bc
,
db
.
x
[
1
],
dbz
,
dc
.
x
[
1
],
dcz
,
da
.
y
);
if
(
db
.
x
[
0
]
!=
0
.
0
f
)
d2d_cdt_incircle_refine1
(
&
fin
,
bxt_det_ca
,
&
bxt_det_ca_len
,
det_ca
,
da
.
y
[
1
],
daz
,
dc
.
y
[
1
],
dcz
,
db
.
x
);
if
(
db
.
y
[
0
]
!=
0
.
0
f
)
d2d_cdt_incircle_refine1
(
&
fin
,
byt_det_ca
,
&
byt_det_ca_len
,
det_ca
,
dc
.
x
[
1
],
dcz
,
da
.
x
[
1
],
daz
,
db
.
y
);
if
(
dc
.
x
[
0
]
!=
0
.
0
f
)
d2d_cdt_incircle_refine1
(
&
fin
,
cxt_det_ab
,
&
cxt_det_ab_len
,
det_ab
,
db
.
y
[
1
],
dbz
,
da
.
y
[
1
],
daz
,
dc
.
x
);
if
(
dc
.
y
[
0
]
!=
0
.
0
f
)
d2d_cdt_incircle_refine1
(
&
fin
,
cyt_det_ab
,
&
cyt_det_ab_len
,
det_ab
,
da
.
x
[
1
],
daz
,
db
.
x
[
1
],
dbz
,
dc
.
y
);
if
(
da
.
x
[
0
]
!=
0
.
0
f
||
da
.
y
[
0
]
!=
0
.
0
f
)
d2d_cdt_incircle_refine2
(
&
fin
,
&
da
,
&
db
,
dbz
,
&
dc
,
dcz
,
axt_det_bc
,
axt_det_bc_len
,
ayt_det_bc
,
ayt_det_bc_len
);
if
(
db
.
x
[
0
]
!=
0
.
0
f
||
db
.
y
[
0
]
!=
0
.
0
f
)
d2d_cdt_incircle_refine2
(
&
fin
,
&
db
,
&
dc
,
dcz
,
&
da
,
daz
,
bxt_det_ca
,
bxt_det_ca_len
,
byt_det_ca
,
byt_det_ca_len
);
if
(
dc
.
x
[
0
]
!=
0
.
0
f
||
dc
.
y
[
0
]
!=
0
.
0
f
)
d2d_cdt_incircle_refine2
(
&
fin
,
&
dc
,
&
da
,
daz
,
&
db
,
dbz
,
cxt_det_ab
,
cxt_det_ab_len
,
cyt_det_ab
,
cyt_det_ab_len
);
return
fin
.
now
[
fin
.
length
-
1
]
>
0
.
0
f
;
}
static
void
d2d_cdt_splice
(
const
struct
d2d_cdt
*
cdt
,
const
struct
d2d_cdt_edge_ref
*
a
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment