diff options
author | Kore Nordmann <github@kore-nordmann.de> | 2007-10-23 09:53:02 +0000 |
---|---|---|
committer | Kore Nordmann <github@kore-nordmann.de> | 2007-10-23 09:53:02 +0000 |
commit | 9d8a0e23a879caa50032bbafd5fd345732c4423b (patch) | |
tree | eee1ab0d0ee0e4d00e4173f47d08b07f8813946a /src/interfaces | |
parent | c7cb2aa85e0f7b4584119cc96bb908799bdf1923 (diff) | |
download | zetacomponents-graph-9d8a0e23a879caa50032bbafd5fd345732c4423b.zip zetacomponents-graph-9d8a0e23a879caa50032bbafd5fd345732c4423b.tar.gz |
- Fixed issue #11640: Polygon size reducement failes for very thin four edged
polygones
Diffstat (limited to 'src/interfaces')
-rw-r--r-- | src/interfaces/driver.php | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/src/interfaces/driver.php b/src/interfaces/driver.php index dfd8e1a..5eb6f03 100644 --- a/src/interfaces/driver.php +++ b/src/interfaces/driver.php @@ -105,6 +105,7 @@ abstract class ezcGraphDriver // Build normalized vectors between polygon edge points $vectors = array(); + $vectorLength = array(); for ( $i = 0; $i < $pointCount; ++$i ) { $nextPoint = ( $i + 1 ) % $pointCount; @@ -112,7 +113,8 @@ abstract class ezcGraphDriver ->sub( $points[$i] ); // Throw exception if polygon is too small to reduce - if ( $vectors[$i]->length() < $size ) + $vectorLength[$i] = $vectors[$i]->length(); + if ( $vectorLength[$i] < $size ) { throw new ezcGraphReducementFailedException(); } @@ -215,17 +217,32 @@ abstract class ezcGraphDriver // point and the size as distance to move. // point + v + size / tan( angle / 2 ) * startVector $newPoint = clone $vectors[$next]; - $newPoints[$next] = - $v ->add( - $newPoint - ->scalar( - $size / - tan( - $lastVector->angle( $vectors[$next] ) / 2 - ) - ) - ) - ->add( $points[$next] ); + $v ->add( + $newPoint + ->scalar( + $size / + tan( + $lastVector->angle( $vectors[$next] ) / 2 + ) + ) + ); + + // A fast guess: If the movement of the point exceeds the length of + // the surrounding edge vectors the angle was to small to perform a + // valid size reducement. In this case we just fall back to the + // original point array. + // + // The correct way to check would be a test, if the calculated + // point is still in the original polygon, but a test for a point + // in a polygon is too expensive. + $movement = $v->length(); + if ( ( $movement > $vectorLength[$last] ) && + ( $movement > $vectorLength[$next] ) ) + { + $v->unify()->scalar( min( $vectorLength[$last], $vectorLength[$next] ) ); + } + + $newPoints[$next] = $v->add( $points[$next] ); } return $newPoints; |