source-class-Com.Tecnick.Pdf.Graph.Raw

It appears that you are using AdBlocking software. The cost of running this website is covered by advertisements. If you like it please feel free to a small amount of money to secure the future of this website.
  1: <?php
  2: /**
  3:  * Raw.php
  4:  *
  5:  * @since       2011-05-23
  6:  * @category    Library
  7:  * @package     PdfGraph
  8:  * @author      Nicola Asuni <info@tecnick.com>
  9:  * @copyright   2011-2015 Nicola Asuni - Tecnick.com LTD
 10:  * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 11:  * @link        https://github.com/tecnickcom/tc-lib-pdf-graph
 12:  *
 13:  * This file is part of tc-lib-pdf-graph software library.
 14:  */
 15: 
 16: namespace Com\Tecnick\Pdf\Graph;
 17: 
 18: use \Com\Tecnick\Pdf\Graph\Exception as GraphException;
 19: 
 20: /**
 21:  * Com\Tecnick\Pdf\Graph\Raw
 22:  *
 23:  * @since       2011-05-23
 24:  * @category    Library
 25:  * @package     PdfGraph
 26:  * @author      Nicola Asuni <info@tecnick.com>
 27:  * @copyright   2011-2015 Nicola Asuni - Tecnick.com LTD
 28:  * @license     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 29:  * @link        https://github.com/tecnickcom/tc-lib-pdf-graph
 30:  */
 31: abstract class Raw extends \Com\Tecnick\Pdf\Graph\Transform
 32: {
 33:     /**
 34:      * Begin a new subpath by moving the current point to the specified coordinates,
 35:      * omitting any connecting line segment.
 36:      *
 37:      * @param float $posx Abscissa of point.
 38:      * @param float $posy Ordinate of point.
 39:      *
 40:      * @return string PDF command
 41:      */
 42:     public function getRawPoint($posx, $posy)
 43:     {
 44:         return sprintf(
 45:             '%F %F m'."\n",
 46:             ($posx * $this->kunit),
 47:             (($this->pageh - $posy) * $this->kunit)
 48:         );
 49:     }
 50: 
 51:     /**
 52:      * Append a straight line segment from the current point to the specified one.
 53:      * The new current point shall be the one specified.
 54:      *
 55:      * @param float $posx Abscissa of end point.
 56:      * @param float $posy Ordinate of end point.
 57:      *
 58:      * @return string PDF command
 59:      */
 60:     public function getRawLine($posx, $posy)
 61:     {
 62:         return sprintf(
 63:             '%F %F l'."\n",
 64:             ($posx * $this->kunit),
 65:             (($this->pageh - $posy) * $this->kunit)
 66:         );
 67:     }
 68: 
 69:     /**
 70:      * Append a rectangle to the current path as a complete subpath,
 71:      * with lower-left corner in the specified point and dimensions width and height in user units.
 72:      *
 73:      * @param float $posx   Abscissa of upper-left corner.
 74:      * @param float $posy   Ordinate of upper-left corner.
 75:      * @param float $width  Width.
 76:      * @param float $height Height.
 77:      *
 78:      * @return string PDF command
 79:      */
 80:     public function getRawRect($posx, $posy, $width, $height)
 81:     {
 82:         return sprintf(
 83:             '%F %F %F %F re'."\n",
 84:             ($posx * $this->kunit),
 85:             (($this->pageh - $posy) * $this->kunit),
 86:             ($width * $this->kunit),
 87:             (-$height * $this->kunit)
 88:         );
 89:     }
 90: 
 91:     /**
 92:      * Append a cubic Bezier curve to the current path.
 93:      * The curve shall extend from the current point to the point (posx3, posy3),
 94:      * using (posx1, posy1) and (posx2, posy2) as the Bezier control points.
 95:      * The new current point shall be (posx3, posy3).
 96:      *
 97:      * @param float $posx1 Abscissa of control point 1.
 98:      * @param float $posy1 Ordinate of control point 1.
 99:      * @param float $posx2 Abscissa of control point 2.
100:      * @param float $posy2 Ordinate of control point 2.
101:      * @param float $posx3 Abscissa of end point.
102:      * @param float $posy3 Ordinate of end point.
103:      *
104:      * @return string PDF command
105:      */
106:     public function getRawCurve($posx1, $posy1, $posx2, $posy2, $posx3, $posy3)
107:     {
108:         return sprintf(
109:             '%F %F %F %F %F %F c'."\n",
110:             ($posx1 * $this->kunit),
111:             (($this->pageh - $posy1) * $this->kunit),
112:             ($posx2 * $this->kunit),
113:             (($this->pageh - $posy2) * $this->kunit),
114:             ($posx3 * $this->kunit),
115:             (($this->pageh - $posy3) * $this->kunit)
116:         );
117:     }
118: 
119:     /**
120:      * Append a cubic Bezier curve to the current path.
121:      * The curve shall extend from the current point to the point (posx3, posy3),
122:      * using the current point and (posx2, posy2) as the Bezier control points.
123:      * The new current point shall be (posx3, posy3).
124:      *
125:      * @param float $posx2 Abscissa of control point 2.
126:      * @param float $posy2 Ordinate of control point 2.
127:      * @param float $posx3 Abscissa of end point.
128:      * @param float $posy3 Ordinate of end point.
129:      *
130:      * @return string PDF command
131:      */
132:     public function getRawCurveV($posx2, $posy2, $posx3, $posy3)
133:     {
134:         return sprintf(
135:             '%F %F %F %F v'."\n",
136:             ($posx2 * $this->kunit),
137:             (($this->pageh - $posy2) * $this->kunit),
138:             ($posx3 * $this->kunit),
139:             (($this->pageh - $posy3) * $this->kunit)
140:         );
141:     }
142: 
143:     /**
144:      * Append a cubic Bezier curve to the current path.
145:      * The curve shall extend from the current point to the point (posx3, posy3),
146:      * using (posx1, posy1) and (posx3, posy3) as the Bezier control points.
147:      * The new current point shall be (posx3, posy3).
148:      *
149:      * @param float $posx1 Abscissa of control point 1.
150:      * @param float $posy1 Ordinate of control point 1.
151:      * @param float $posx3 Abscissa of end point.
152:      * @param float $posy3 Ordinate of end point.
153:      *
154:      * @return string PDF command
155:      */
156:     public function getRawCurveY($posx1, $posy1, $posx3, $posy3)
157:     {
158:         return sprintf(
159:             '%F %F %F %F y'."\n",
160:             ($posx1 * $this->kunit),
161:             (($this->pageh - $posy1) * $this->kunit),
162:             ($posx3 * $this->kunit),
163:             (($this->pageh - $posy3) * $this->kunit)
164:         );
165:     }
166: 
167:     /**
168:      * Initialize angles for the elliptical arc.
169:      *
170:      * @param float $ags Angle in degrees at which starting drawing.
171:      * @param float $agf Angle in degrees at which stop drawing.
172:      * @param float $rdh Horizontal radius.
173:      * @param float $rdv Vertical radius (if = 0 then it is a circle).
174:      * @param bool  $ccw If true draws in counter-clockwise direction.
175:      * @param bool  $svg If true the angles are in svg mode (already calculated).
176:      */
177:     protected function setRawEllipticalArcAngles(&$ags, &$agf, $rdv, $rdh, $ccw, $svg)
178:     {
179:         $ags = $this->degToRad((float) $ags);
180:         $agf = $this->degToRad((float) $agf);
181:         if (!$svg) {
182:             $ags = atan2((sin($ags) / $rdv), (cos($ags) / $rdh));
183:             $agf = atan2((sin($agf) / $rdv), (cos($agf) / $rdh));
184:         }
185:         if ($ags < 0) {
186:             $ags += (2 * self::MPI);
187:         }
188:         if ($agf < 0) {
189:             $agf += (2 * self::MPI);
190:         }
191:         if ($ccw && ($ags > $agf)) {
192:             // reverse rotation
193:             $ags -= (2 * self::MPI);
194:         } elseif (!$ccw && ($ags < $agf)) {
195:             // reverse rotation
196:             $agf -= (2 * self::MPI);
197:         }
198:     }
199: 
200:     /**
201:      * Append an elliptical arc to the current path.
202:      * An ellipse is formed from n Bezier curves.
203:      *
204:      * @param float $posxc      Abscissa of center point.
205:      * @param float $posyc      Ordinate of center point.
206:      * @param float $rdh        Horizontal radius.
207:      * @param float $rdv        Vertical radius (if = 0 then it is a circle).
208:      * @param float $posxang    Angle between the X-axis and the major axis of the ellipse.
209:      * @param float $angs       Angle in degrees at which starting drawing.
210:      * @param float $angf       Angle in degrees at which stop drawing.
211:      * @param bool  $pie        If true do not mark the border point (used to draw pie sectors).
212:      * @param int   $ncv        Number of curves used to draw a 90 degrees portion of ellipse.
213:      * @param bool  $startpoint If true output a starting point.
214:      * @param bool  $ccw        If true draws in counter-clockwise direction.
215:      * @param bool  $svg        If true the angles are in svg mode (already calculated).
216:      * @param array $bbox       If provided, it will be filled with the bounding box coordinates
217:      *                          (x min, y min, x max, y max).
218:      *
219:      * @return string PDF command
220:      *
221:      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
222:      */
223:     public function getRawEllipticalArc(
224:         $posxc,
225:         $posyc,
226:         $rdh,
227:         $rdv,
228:         $posxang = 0,
229:         $angs = 0,
230:         $angf = 360,
231:         $pie = false,
232:         $ncv = 2,
233:         $startpoint = true,
234:         $ccw = true,
235:         $svg = false,
236:         &$bbox = array()
237:     ) {
238:         $out = '';
239:         if (($rdh <= 0) || ($rdv < 0)) {
240:             return '';
241:         }
242:         $bbox = array(PHP_INT_MAX, PHP_INT_MAX, 0, 0);
243:         if ($pie) {
244:             $out .= $this->getRawPoint($posxc, $posyc); // center of the arc
245:         }
246:         $posxang = $this->degToRad((float) $posxang);
247:         $ags = $angs;
248:         $agf = $angf;
249:         $this->setRawEllipticalArcAngles($ags, $agf, $rdv, $rdh, $ccw, $svg);
250:         $total_angle = ($agf - $ags);
251:         $ncv = max(2, $ncv);
252:         $ncv *= (2 * abs($total_angle) / self::MPI); // total arcs to draw
253:         $ncv = round($ncv) + 1;
254:         $arcang = ($total_angle / $ncv); // angle of each arc
255:         $posx0 = $posxc; // X center point in PDF coordinates
256:         $posy0 = ($this->pageh - $posyc); // Y center point in PDF coordinates
257:         $ang = $ags; // starting angle
258:         $alpha = sin($arcang) * ((sqrt(4 + (3 * pow(tan(($arcang) / 2), 2))) - 1) / 3);
259:         $cos_xang = cos($posxang);
260:         $sin_xang = sin($posxang);
261:         $cos_ang = cos($ang);
262:         $sin_ang = sin($ang);
263:         // first arc point
264:         $px1 = $posx0 + ($rdh * $cos_xang * $cos_ang) - ($rdv * $sin_xang * $sin_ang);
265:         $py1 = $posy0 + ($rdh * $sin_xang * $cos_ang) + ($rdv * $cos_xang * $sin_ang);
266:         // first Bezier control point
267:         $qx1 = ($alpha * ((-$rdh * $cos_xang * $sin_ang) - ($rdv * $sin_xang * $cos_ang)));
268:         $qy1 = ($alpha * ((-$rdh * $sin_xang * $sin_ang) + ($rdv * $cos_xang * $cos_ang)));
269:         if ($pie) {
270:             $out .= $this->getRawLine($px1, ($this->pageh - $py1)); // line from center to arc starting point
271:         } elseif ($startpoint) {
272:             $out .= $this->getRawPoint($px1, ($this->pageh - $py1)); // arc starting point
273:         }
274:         // draw arcs
275:         for ($idx = 1; $idx <= $ncv; ++$idx) {
276:             $ang = $ags + ($idx * $arcang); // starting angle
277:             if ($idx == $ncv) {
278:                 $ang = $agf;
279:             }
280:             $cos_ang = cos($ang);
281:             $sin_ang = sin($ang);
282:             // second arc point
283:             $px2 = $posx0 + ($rdh * $cos_xang * $cos_ang) - ($rdv * $sin_xang * $sin_ang);
284:             $py2 = $posy0 + ($rdh * $sin_xang * $cos_ang) + ($rdv * $cos_xang * $sin_ang);
285:             // second Bezier control point
286:             $qx2 = ($alpha * ((-$rdh * $cos_xang * $sin_ang) - ($rdv * $sin_xang * $cos_ang)));
287:             $qy2 = ($alpha * ((-$rdh * $sin_xang * $sin_ang) + ($rdv * $cos_xang * $cos_ang)));
288:             // draw arc
289:             $cx1 = ($px1 + $qx1);
290:             $cy1 = ($this->pageh - ($py1 + $qy1));
291:             $cx2 = ($px2 - $qx2);
292:             $cy2 = ($this->pageh - ($py2 - $qy2));
293:             $cx3 = $px2;
294:             $cy3 = ($this->pageh - $py2);
295:             $out .= $this->getRawCurve($cx1, $cy1, $cx2, $cy2, $cx3, $cy3);
296:             // get bounding box coordinates
297:             $bbox = array(
298:                 min($bbox[0], $cx1, $cx2, $cx3),
299:                 min($bbox[1], $cy1, $cy2, $cy3),
300:                 max($bbox[2], $cx1, $cx2, $cx3),
301:                 max($bbox[3], $cy1, $cy2, $cy3),
302:             );
303:             // move to next point
304:             $px1 = $px2;
305:             $py1 = $py2;
306:             $qx1 = $qx2;
307:             $qy1 = $qy2;
308:         }
309:         if ($pie) {
310:             $out .= $this->getRawLine($posxc, $posyc);
311:             // get bounding box coordinates
312:             $bbox = array(min($bbox[0], $posxc), min($bbox[1], $posyc), max($bbox[2], $posxc),  max($bbox[3], $posyc));
313:         }
314:         return $out;
315:     }
316: 
317:     /**
318:      * Returns the angle in radiants between two vectors with the same origin point.
319:      * Angles are counted counter-clock wise.
320:      *
321:      * @param int $posx1 X coordinate of first vector point.
322:      * @param int $posy1 Y coordinate of first vector point.
323:      * @param int $posx2 X coordinate of second vector point.
324:      * @param int $posy2 Y coordinate of second vector point.
325:      *
326:      * @return float Angle in radiants
327:      */
328:     public function getVectorsAngle($posx1, $posy1, $posx2, $posy2)
329:     {
330:         $dprod = (($posx1 * $posx2) + ($posy1 * $posy2));
331:         $dist1 = sqrt(($posx1 * $posx1) + ($posy1 * $posy1));
332:         $dist2 = sqrt(($posx2 * $posx2) + ($posy2 * $posy2));
333:         $distprod = ($dist1 * $dist2);
334:         if ($distprod == 0) {
335:             return 0;
336:         }
337:         $angle = acos(min(1, max(-1, ($dprod / $distprod))));
338:         if ((($posx1 * $posy2) - ($posx2 * $posy1)) < 0) {
339:             $angle *= -1;
340:         }
341:         return $angle;
342:     }
343: 
344:     /**
345:      * Converts the number in degrees to the radian equivalent.
346:      * We use this instead of $this->degToRad to avoid precision problems with hhvm.
347:      *
348:      * @param float $deg Angular value in degrees.
349:      *
350:      * @return float Angle in radiants
351:      */
352:     public function degToRad($deg)
353:     {
354:         return ($deg * self::MPI / 180);
355:     }
356: }
357: 
 

© 2004-2017 – Nicola Asuni - Tecnick.com - All rights reserved.
about - disclaimer - privacy