Overview

Packages

  • None
  • PieChart

Functions

  • imageSmoothArc
  • imageSmoothArcDrawSegment
  • Overview
  • Package
  • Function
  • Tree
  1: <?php
  2: /*
  3:     Copyright (c) 2006-2008 Ulrich Mierendorff
  4: 
  5:     Permission is hereby granted, free of charge, to any person obtaining a
  6:     copy of this software and associated documentation files (the "Software"),
  7:     to deal in the Software without restriction, including without limitation
  8:     the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9:     and/or sell copies of the Software, and to permit persons to whom the
 10:     Software is furnished to do so, subject to the following conditions:
 11: 
 12:     The above copyright notice and this permission notice shall be included in
 13:     all copies or substantial portions of the Software.
 14: 
 15:     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16:     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17:     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 18:     THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19:     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20:     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 21:     DEALINGS IN THE SOFTWARE.
 22:     
 23:     Changelog:
 24:     version 1.1
 25:         - improved the rendering speed by ~20%
 26:         
 27:         - Thanks to Matthias Mächler for fixing some small errors:
 28:             * uninitialized variables
 29:             * deprecated passing of $img reference in imageSmoothArc ()
 30:     
 31:     version 1.0
 32:         Release of rewritten script
 33: 
 34: */
 35: 
 36: function imageSmoothArcDrawSegment (&$img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY, $color, $start, $stop, $seg)
 37: {
 38:     // Originally written from scratch by Ulrich Mierendorff, 06/2006
 39:     // Rewritten and improved, 04/2007, 07/2007
 40:     
 41:     // Please do not use THIS function directly. Scroll down to imageSmoothArc(...).
 42:     
 43:     $fillColor = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], $color[3] );
 44:     
 45:     $xStart = abs($a * cos($start));
 46:     $yStart = abs($b * sin($start));
 47:     $xStop  = abs($a * cos($stop));
 48:     $yStop  = abs($b * sin($stop));
 49:     $dxStart = 0;
 50:     $dyStart = 0;
 51:     $dxStop = 0;
 52:     $dyStop = 0;
 53:     if ($xStart != 0)
 54:         $dyStart = $yStart/$xStart;
 55:     if ($xStop != 0)
 56:         $dyStop = $yStop/$xStop;
 57:     if ($yStart != 0)
 58:         $dxStart = $xStart/$yStart;
 59:     if ($yStop != 0)
 60:         $dxStop = $xStop/$yStop;
 61:     if (abs($xStart) >= abs($yStart)) {
 62:         $aaStartX = true;
 63:     } else {
 64:         $aaStartX = false;
 65:     }
 66:     if ($xStop >= $yStop) {
 67:         $aaStopX = true;
 68:     } else {
 69:         $aaStopX = false;
 70:     }
 71:     //$xp = +1; $yp = -1; $xa = +1; $ya = 0;
 72:     for ( $x = 0; $x < $a; $x += 1 ) {
 73:         /*$y = $b * sqrt( 1 - ($x*$x)/($a*$a) );
 74:         
 75:         $error = $y - (int)($y);
 76:         $y = (int)($y);
 77:         
 78:         $diffColor = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error );*/
 79:         
 80:         $_y1 = $dyStop*$x;
 81:         $_y2 = $dyStart*$x;
 82:         if ($xStart > $xStop)
 83:         {
 84:             $error1 = $_y1 - (int)($_y1);
 85:             $error2 = 1 - $_y2 + (int)$_y2;
 86:             $_y1 = $_y1-$error1;
 87:             $_y2 = $_y2+$error2;
 88:         }
 89:         else
 90:         {
 91:             $error1 = 1 - $_y1 + (int)$_y1;
 92:             $error2 = $_y2 - (int)($_y2);
 93:             $_y1 = $_y1+$error1;
 94:             $_y2 = $_y2-$error2;
 95:         }
 96:         /*
 97:         if ($aaStopX)
 98:             $diffColor1 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error1 );
 99:         if ($aaStartX)
100:             $diffColor2 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error2 );
101:         */
102:         
103:         if ($seg == 0 || $seg == 2)
104:         {
105:             $i = $seg;
106:             if (!($start > $i*M_PI/2 && $x > $xStart)) {
107:                 if ($i == 0) {
108:                     $xp = +1; $yp = -1; $xa = +1; $ya = 0;
109:                 } else {
110:                     $xp = -1; $yp = +1; $xa = 0; $ya = +1;
111:                 }
112:                 if ( $stop < ($i+1)*(M_PI/2) && $x <= $xStop ) {
113:                     $diffColor1 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error1 );
114:                     $y1 = $_y1; if ($aaStopX) imageSetPixel($img, $cx+$xp*($x)+$xa, $cy+$yp*($y1+1)+$ya, $diffColor1);
115:                     
116:                 } else {
117:                     $y = $b * sqrt( 1 - ($x*$x)/($a*$a) );
118:                     $error = $y - (int)($y);
119:                     $y = (int)($y);
120:                     $diffColor = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error );
121:                     $y1 = $y; if ($x < $aaAngleX ) imageSetPixel($img, $cx+$xp*$x+$xa, $cy+$yp*($y1+1)+$ya, $diffColor);
122:                 }
123:                 if ($start > $i*M_PI/2 && $x <= $xStart) {
124:                     $diffColor2 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error2 );
125:                     $y2 = $_y2; if ($aaStartX) imageSetPixel($img, $cx+$xp*$x+$xa, $cy+$yp*($y2-1)+$ya, $diffColor2);
126:                 } else {
127:                     $y2 = 0;
128:                 }
129:                 if ($y2 <= $y1) imageLine($img, $cx+$xp*$x+$xa, $cy+$yp*$y1+$ya , $cx+$xp*$x+$xa, $cy+$yp*$y2+$ya, $fillColor);
130:             }
131:         }
132:         
133:         if ($seg == 1 || $seg == 3)
134:         {
135:             $i = $seg;
136:             if (!($stop < ($i+1)*M_PI/2 && $x > $xStop)) {
137:                 if ($i == 1) {
138:                     $xp = -1; $yp = -1; $xa = 0; $ya = 0;
139:                 } else {
140:                     $xp = +1; $yp = +1; $xa = 1; $ya = 1;
141:                 }
142:                 if ( $start > $i*M_PI/2 && $x < $xStart ) {
143:                     $diffColor2 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error2 );
144:                     $y1 = $_y2; if ($aaStartX) imageSetPixel($img, $cx+$xp*$x+$xa, $cy+$yp*($y1+1)+$ya, $diffColor2);
145:                     
146:                 } else {
147:                     $y = $b * sqrt( 1 - ($x*$x)/($a*$a) );
148:                     $error = $y - (int)($y);
149:                     $y = (int) $y;
150:                     $diffColor = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error );
151:                     $y1 = $y; if ($x < $aaAngleX ) imageSetPixel($img, $cx+$xp*$x+$xa, $cy+$yp*($y1+1)+$ya, $diffColor);
152:                 }
153:                 if ($stop < ($i+1)*M_PI/2 && $x <= $xStop) {
154:                     $diffColor1 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error1 );
155:                     $y2 = $_y1; if ($aaStopX)  imageSetPixel($img, $cx+$xp*$x+$xa, $cy+$yp*($y2-1)+$ya, $diffColor1);
156:                 } else {
157:                     $y2 = 0;
158:                 }
159:                 if ($y2 <= $y1) imageLine($img, $cx+$xp*$x+$xa, $cy+$yp*$y1+$ya, $cx+$xp*$x+$xa, $cy+$yp*$y2+$ya, $fillColor);
160:             }
161:         }
162:     }
163:     
164:     ///YYYYY
165:     
166:     for ( $y = 0; $y < $b; $y += 1 ) {
167:         /*$x = $a * sqrt( 1 - ($y*$y)/($b*$b) );
168:         
169:         $error = $x - (int)($x);
170:         $x = (int)($x);
171:         
172:         $diffColor = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error );
173:         */
174:         $_x1 = $dxStop*$y;
175:         $_x2 = $dxStart*$y;
176:         if ($yStart > $yStop)
177:         {
178:             $error1 = $_x1 - (int)($_x1);
179:             $error2 = 1 - $_x2 + (int)$_x2;
180:             $_x1 = $_x1-$error1;
181:             $_x2 = $_x2+$error2;
182:         }
183:         else
184:         {
185:             $error1 = 1 - $_x1 + (int)$_x1;
186:             $error2 = $_x2 - (int)($_x2);
187:             $_x1 = $_x1+$error1;
188:             $_x2 = $_x2-$error2;
189:         }
190: /*
191:         if (!$aaStopX)
192:             $diffColor1 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error1 );
193:         if (!$aaStartX)
194:             $diffColor2 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error2 );
195: */
196:         
197:         if ($seg == 0 || $seg == 2)
198:         {
199:             $i = $seg;
200:             if (!($start > $i*M_PI/2 && $y > $yStop)) {
201:                 if ($i == 0) {
202:                     $xp = +1; $yp = -1; $xa = 1; $ya = 0;
203:                 } else {
204:                     $xp = -1; $yp = +1; $xa = 0; $ya = 1;
205:                 }
206:                 if ( $stop < ($i+1)*(M_PI/2) && $y <= $yStop ) {
207:                     $diffColor1 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error1 );
208:                     $x1 = $_x1; if (!$aaStopX) imageSetPixel($img, $cx+$xp*($x1-1)+$xa, $cy+$yp*($y)+$ya, $diffColor1);
209:                 } 
210:                 if ($start > $i*M_PI/2 && $y < $yStart) {
211:                     $diffColor2 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error2 );
212:                     $x2 = $_x2; if (!$aaStartX) imageSetPixel($img, $cx+$xp*($x2+1)+$xa, $cy+$yp*($y)+$ya, $diffColor2);
213:                 } else {
214:                     $x = $a * sqrt( 1 - ($y*$y)/($b*$b) );
215:                     $error = $x - (int)($x);
216:                     $x = (int)($x);
217:                     $diffColor = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error );
218:                     $x1 = $x; if ($y < $aaAngleY && $y <= $yStop ) imageSetPixel($img, $cx+$xp*($x1+1)+$xa, $cy+$yp*$y+$ya, $diffColor);
219:                 }
220:             }
221:         }
222:         
223:         if ($seg == 1 || $seg == 3)
224:         {
225:             $i = $seg;
226:             if (!($stop < ($i+1)*M_PI/2 && $y > $yStart)) {
227:                 if ($i == 1) {
228:                     $xp = -1; $yp = -1; $xa = 0; $ya = 0;
229:                 } else {
230:                     $xp = +1; $yp = +1; $xa = 1; $ya = 1;
231:                 }
232:                 if ( $start > $i*M_PI/2 && $y < $yStart ) {
233:                     $diffColor2 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error2 );
234:                     $x1 = $_x2; if (!$aaStartX) imageSetPixel($img, $cx+$xp*($x1-1)+$xa, $cy+$yp*$y+$ya,  $diffColor2);
235:                 } 
236:                 if ($stop < ($i+1)*M_PI/2 && $y <= $yStop) {
237:                     $diffColor1 = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error1 );
238:                     $x2 = $_x1; if (!$aaStopX)  imageSetPixel($img, $cx+$xp*($x2+1)+$xa, $cy+$yp*$y+$ya, $diffColor1);
239:                 } else {
240:                     $x = $a * sqrt( 1 - ($y*$y)/($b*$b) );
241:                     $error = $x - (int)($x);
242:                     $x = (int)($x);
243:                     $diffColor = imageColorExactAlpha( $img, $color[0], $color[1], $color[2], 127-(127-$color[3])*$error );
244:                     $x1 = $x; if ($y < $aaAngleY  && $y < $yStart) imageSetPixel($img,$cx+$xp*($x1+1)+$xa,  $cy+$yp*$y+$ya, $diffColor);
245:                 }
246:             }
247:         }
248:     }
249: }
250: 
251: function imageSmoothArc ( &$img, $cx, $cy, $w, $h, $color, $start, $stop)
252: {
253:     // Originally written from scratch by Ulrich Mierendorff, 06/2006
254:     // Rewritten and improved, 04/2007, 07/2007
255:     // compared to old version:
256:     // + Support for transparency added
257:     // + Improved quality of edges & antialiasing
258:     
259:     // note: This function does not represent the fastest way to draw elliptical
260:     // arcs. It was written without reading any papers on that subject. Better
261:     // algorithms may be twice as fast or even more.
262:     
263:     // what it cannot do: It does not support outlined arcs, only filled
264:     
265:     // Parameters:
266:     // $cx      - Center of ellipse, X-coord
267:     // $cy      - Center of ellipse, Y-coord
268:     // $w       - Width of ellipse ($w >= 2)
269:     // $h       - Height of ellipse ($h >= 2 )
270:     // $color   - Color of ellipse as a four component array with RGBA
271:     // $start   - Starting angle of the arc, no limited range!
272:     // $stop    - Stop     angle of the arc, no limited range!
273:     // $start _can_ be greater than $stop!
274:     // If any value is not in the given range, results are undefined!
275:     
276:     // This script does not use any special algorithms, everything is completely
277:     // written from scratch; see http://de.wikipedia.org/wiki/Ellipse for formulas.
278:     
279:     while ($start < 0)
280:         $start += 2*M_PI;
281:     while ($stop < 0)
282:         $stop += 2*M_PI;
283:     
284:     while ($start > 2*M_PI)
285:         $start -= 2*M_PI;
286:     
287:     while ($stop > 2*M_PI)
288:         $stop -= 2*M_PI;
289:     
290:     
291:     if ($start > $stop)
292:     {
293:         imageSmoothArc ( $img, $cx, $cy, $w, $h, $color, $start, 2*M_PI);
294:         imageSmoothArc ( $img, $cx, $cy, $w, $h, $color, 0, $stop);
295:         return;
296:     }
297:     
298:     $a = 1.0*round ($w/2);
299:     $b = 1.0*round ($h/2);
300:     $cx = 1.0*round ($cx);
301:     $cy = 1.0*round ($cy);
302:     
303:     $aaAngle = atan(($b*$b)/($a*$a)*tan(0.25*M_PI));
304:     $aaAngleX = $a*cos($aaAngle);
305:     $aaAngleY = $b*sin($aaAngle);
306:     
307:     $a -= 0.5; // looks better...
308:     $b -= 0.5;
309:     
310:     for ($i=0; $i<4;$i++)
311:     {
312:         if ($start < ($i+1)*M_PI/2)
313:         {
314:             if ($start > $i*M_PI/2)
315:             {
316:                 if ($stop > ($i+1)*M_PI/2)
317:                 {
318:                     imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY , $color, $start, ($i+1)*M_PI/2, $i);
319:                 }
320:                 else
321:                 {
322:                     imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY, $color, $start, $stop, $i);
323:                     break;
324:                 }
325:             }
326:             else
327:             {
328:                 if ($stop > ($i+1)*M_PI/2)
329:                 {
330:                     imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY, $color, $i*M_PI/2, ($i+1)*M_PI/2, $i);
331:                 }
332:                 else
333:                 {
334:                     imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY, $color, $i*M_PI/2, $stop, $i);
335:                     break;
336:                 }
337:             }
338:         }
339:     }
340: }
PieChart API documentation generated by ApiGen 2.8.0