summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKore Nordmann <github@kore-nordmann.de>2007-10-23 09:53:02 +0000
committerKore Nordmann <github@kore-nordmann.de>2007-10-23 09:53:02 +0000
commit9d8a0e23a879caa50032bbafd5fd345732c4423b (patch)
treeeee1ab0d0ee0e4d00e4173f47d08b07f8813946a /src
parentc7cb2aa85e0f7b4584119cc96bb908799bdf1923 (diff)
downloadzetacomponents-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')
-rw-r--r--src/interfaces/driver.php41
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;
OpenPOWER on IntegriCloud