mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-04-22 04:40:41 +02:00
Fixed algebra used by XrPenVerticesNeeded to avoid sqrt() of negative numbers.
This commit is contained in:
parent
a4b439eb69
commit
d4ba730ba2
7 changed files with 54 additions and 30 deletions
|
|
@ -1,3 +1,9 @@
|
|||
2003-02-06 Carl Worth <cworth@isi.edu>
|
||||
|
||||
* xrpen.c (_XrPenVerticesNeeded): Fixed to use determinant rather
|
||||
than eigenvalues to compute maximal scaling of radius. Now avoids
|
||||
embarrassing segfaults due to NaN from the eigenvalue computation.
|
||||
|
||||
2003-01-28 Carl Worth <cworth@isi.edu>
|
||||
|
||||
* xrtraps.c (_XrTrapsTessellateTriangle): Fixed to not re-order
|
||||
|
|
|
|||
|
|
@ -764,6 +764,9 @@ _XrTransformBoundingBox(XrTransform *transform,
|
|||
XrStatus
|
||||
_XrTransformComputeInverse(XrTransform *transform);
|
||||
|
||||
void
|
||||
_XrTransformComputeDeterminant(XrTransform *transform, double *det);
|
||||
|
||||
void
|
||||
_XrTransformEigenValues(XrTransform *transform, double *lambda1, double *lambda2);
|
||||
|
||||
|
|
|
|||
15
src/xrpen.c
15
src/xrpen.c
|
|
@ -188,20 +188,19 @@ _XrPenAddPoints(XrPen *pen, XPointFixed *pt, int num_pts)
|
|||
static int
|
||||
_XrPenVerticesNeeded(double radius, double tolerance, XrTransform *matrix)
|
||||
{
|
||||
double e1, e2, emax, theta;
|
||||
double expansion, theta;
|
||||
|
||||
_XrTransformEigenValues(matrix, &e1, &e2);
|
||||
/* The determinant represents the area expansion factor of the
|
||||
transform. In the worst case, this is entirely in one
|
||||
dimension, which is what we assume here. */
|
||||
|
||||
if (fabs(e1) > fabs(e2))
|
||||
emax = fabs(e1);
|
||||
else
|
||||
emax = fabs(e2);
|
||||
_XrTransformComputeDeterminant(matrix, &expansion);
|
||||
|
||||
if (tolerance > emax*radius) {
|
||||
if (tolerance > expansion*radius) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
theta = acos(1 - tolerance/(emax * radius));
|
||||
theta = acos(1 - tolerance/(expansion * radius));
|
||||
return ceil(M_PI / theta);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -244,14 +244,10 @@ XrStatus
|
|||
_XrTransformComputeInverse(XrTransform *transform)
|
||||
{
|
||||
/* inv(A) = 1/det(A) * adj(A) */
|
||||
double det;
|
||||
|
||||
double a, b, c, d, det;
|
||||
|
||||
a = transform->m[0][0]; b = transform->m[0][1];
|
||||
c = transform->m[1][0]; d = transform->m[1][1];
|
||||
|
||||
det = a*d - b*c;
|
||||
|
||||
_XrTransformComputeDeterminant(transform, &det);
|
||||
|
||||
if (det == 0)
|
||||
return XrStatusInvalidMatrix;
|
||||
|
||||
|
|
@ -261,6 +257,17 @@ _XrTransformComputeInverse(XrTransform *transform)
|
|||
return XrStatusSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
_XrTransformComputeDeterminant(XrTransform *transform, double *det)
|
||||
{
|
||||
double a, b, c, d;
|
||||
|
||||
a = transform->m[0][0]; b = transform->m[0][1];
|
||||
c = transform->m[1][0]; d = transform->m[1][1];
|
||||
|
||||
*det = a*d - b*c;
|
||||
}
|
||||
|
||||
void
|
||||
_XrTransformEigenValues(XrTransform *transform, double *lambda1, double *lambda2)
|
||||
{
|
||||
|
|
|
|||
3
xrint.h
3
xrint.h
|
|
@ -764,6 +764,9 @@ _XrTransformBoundingBox(XrTransform *transform,
|
|||
XrStatus
|
||||
_XrTransformComputeInverse(XrTransform *transform);
|
||||
|
||||
void
|
||||
_XrTransformComputeDeterminant(XrTransform *transform, double *det);
|
||||
|
||||
void
|
||||
_XrTransformEigenValues(XrTransform *transform, double *lambda1, double *lambda2);
|
||||
|
||||
|
|
|
|||
15
xrpen.c
15
xrpen.c
|
|
@ -188,20 +188,19 @@ _XrPenAddPoints(XrPen *pen, XPointFixed *pt, int num_pts)
|
|||
static int
|
||||
_XrPenVerticesNeeded(double radius, double tolerance, XrTransform *matrix)
|
||||
{
|
||||
double e1, e2, emax, theta;
|
||||
double expansion, theta;
|
||||
|
||||
_XrTransformEigenValues(matrix, &e1, &e2);
|
||||
/* The determinant represents the area expansion factor of the
|
||||
transform. In the worst case, this is entirely in one
|
||||
dimension, which is what we assume here. */
|
||||
|
||||
if (fabs(e1) > fabs(e2))
|
||||
emax = fabs(e1);
|
||||
else
|
||||
emax = fabs(e2);
|
||||
_XrTransformComputeDeterminant(matrix, &expansion);
|
||||
|
||||
if (tolerance > emax*radius) {
|
||||
if (tolerance > expansion*radius) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
theta = acos(1 - tolerance/(emax * radius));
|
||||
theta = acos(1 - tolerance/(expansion * radius));
|
||||
return ceil(M_PI / theta);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -244,14 +244,10 @@ XrStatus
|
|||
_XrTransformComputeInverse(XrTransform *transform)
|
||||
{
|
||||
/* inv(A) = 1/det(A) * adj(A) */
|
||||
double det;
|
||||
|
||||
double a, b, c, d, det;
|
||||
|
||||
a = transform->m[0][0]; b = transform->m[0][1];
|
||||
c = transform->m[1][0]; d = transform->m[1][1];
|
||||
|
||||
det = a*d - b*c;
|
||||
|
||||
_XrTransformComputeDeterminant(transform, &det);
|
||||
|
||||
if (det == 0)
|
||||
return XrStatusInvalidMatrix;
|
||||
|
||||
|
|
@ -261,6 +257,17 @@ _XrTransformComputeInverse(XrTransform *transform)
|
|||
return XrStatusSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
_XrTransformComputeDeterminant(XrTransform *transform, double *det)
|
||||
{
|
||||
double a, b, c, d;
|
||||
|
||||
a = transform->m[0][0]; b = transform->m[0][1];
|
||||
c = transform->m[1][0]; d = transform->m[1][1];
|
||||
|
||||
*det = a*d - b*c;
|
||||
}
|
||||
|
||||
void
|
||||
_XrTransformEigenValues(XrTransform *transform, double *lambda1, double *lambda2)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue