PHP Classes

File: vertex.php

Recommend this page to a friend!
  Classes of Brenor Brophy   Polygon   vertex.php   Download  
File: vertex.php
Role: Class source
Content type: text/plain
Description: vertex and segment objects used by polygon
Class: Polygon
Perform geometric operations on polygons
Author: By
Last change: Just updated revision number in file. No changes to code.
Date: 13 years ago
Size: 11,333 bytes
 

Contents

Class file image Download
<?php /*------------------------------------------------------------------------------ ** File: vertex.php ** Description: PHP class for a polygon vertex. Used as the base object to ** build a class of polygons. ** Version: 1.6 ** Author: Brenor Brophy ** Email: brenor dot brophy at gmail dot com ** Homepage: www.brenorbrophy.com **------------------------------------------------------------------------------ ** COPYRIGHT (c) 2005-2010 BRENOR BROPHY ** ** The source code included in this package is free software; you can ** redistribute it and/or modify it under the terms of the GNU General Public ** License as published by the Free Software Foundation. This license can be ** read at: ** ** http://www.opensource.org/licenses/gpl-license.php ** ** This program is distributed in the hope that it will be useful, but WITHOUT ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **------------------------------------------------------------------------------ ** ** Based on the paper "Efficient Clipping of Arbitary Polygons" by Gunther ** Greiner (greiner at informatik dot uni-erlangen dot de) and Kai Hormann ** (hormann at informatik dot tu-clausthal dot de), ACM Transactions on Graphics ** 1998;17(2):71-83. ** ** Available at: ** ** http://www2.in.tu-clausthal.de/~hormann/papers/Greiner.1998.ECO.pdf ** ** Another useful site describing the algorithm and with some example ** C code by Ionel Daniel Stroe is at: ** ** http://davis.wpi.edu/~matt/courses/clipping/ ** ** The algorithm is extended by Brenor Brophy to allow polygons with ** arcs between vertices. ** ** Rev History ** ----------------------------------------------------------------------------- ** 1.0 08/25/2005 Initial Release ** 1.1 09/04/2005 Added software license language to header comments ** 1.2 09/07/2005 Minor fix to polygon.php - no change to this file ** 1.3 04/16/2006 Minor fix to polygon.php - no change to this file ** 1.4 03/19/2009 Minor change to comments in this file. Significant ** change to polygon.php ** 1.5 07/16/2009 No change to this file ** 1.6 15/05/2010 No change to this file */ class segment { /*------------------------------------------------------------------------------ ** This class contains the information about the segments between vetrices. In ** the original algorithm these were just lines. In this extended form they ** may also be arcs. By creating a separate object for the segment and then ** referencing to it forward & backward from the two vertices it links it is ** easy to track in various directions through the polygon linked list. */ var $xc, $yc; // Coordinates of the center of the arc var $d; // Direction of the arc, -1 = clockwise, +1 = anti-clockwise, // A 0 indicates this is a line /* ** Construct a segment */ function segment ($xc=0, $yc=0, $d=0) { $this->xc = $xc; $this->yc = $yc; $this->d = $d; } /* ** Return the contents of a segment */ function Xc () { return $this->xc ;} function Yc () { return $this->yc ;} function d () { return $this->d ;} /* ** Set Xc/Yc */ function setXc ($xc) { $this->xc = $xc; } function setYc ($yc) { $this->yc = $yc; } } // end of class segment class vertex { /*------------------------------------------------------------------------------ ** This class is almost exactly as described in the paper by Gunter/Greiner ** with some minor additions for segments. Basically it is a node in a doubly ** linked list with a few extra control variables used by the algorithm ** for boolean operations. The only methods in the class are used to encapsulate ** the properties. */ var $x, $y; // Coordinates of the vertex var $nextV, $prevV; // References to the next and previous vetices in the polygon var $nSeg, $pSeg; // References to next & previous segments var $nextPoly; // Reference to another polygon in a list var $intersect; // TRUE if vertex is an intersection (with another polgon) var $neighbor; // Ref to the corresponding intersection vertex in another polygon var $alpha; // Intersection points relative distance from previous vertex var $entry; // TRUE if intersection is an entry point to another polygon // FALSE if it is an exit point var $checked; // Boolean - TRUE if vertex has been checked var $id; // A random ID assigned to make the vertex unique /* ** Construct a vertex */ function vertex ($x, $y, $xc=0, $yc=0, $d=0, $nextV=NULL, $prevV=NULL, $nextPoly=NULL, $intersect = FALSE, $neighbor=NULL, $alpha=0, $entry=TRUE, $checked=FALSE) { $this->x = $x; $this->y = $y; $this->nextV = $nextV; $this->prevV = $prevV; $this->nextPoly = $nextPoly; $this->intersect = $intersect; $this->neighbor = $neighbor; $this->alpha = $alpha; $this->entry = $entry; $this->checked = $checked; $this->id = mt_rand(0,1000000); /* ** Create a new segment and set a reference to it. Segments are always ** placed after the vertex */ $this->nSeg =& new segment ($xc, $yc, $d); $this->pSeg = NULL; } /* ** Get id */ function id() { return $this->id; } /* ** Get/Set x/y */ function X() { return $this->x; } function setX($x) { $this->x = $x; } function Y() { return $this->y; } function setY($y) { $this->y = $y; } /* ** Return contents of a segment. Default is to always return the next ** segment, unless previous is specified. The special case is where ** the vertex is an intersection, in that case the contents of the ** neighbor vertex's next or prev segment is returned. Whether next ** or previous is returned depends upon the entry value of the vertex ** This method ensures that the correct segment data is returned when ** a result polygon is being constructed. ** ** For $g Next == TRUE and Prev == FALSE */ function Xc ($g = TRUE) { if ($this->isIntersect()) { if ($this->neighbor->isEntry()) return $this->neighbor->nSeg->Xc(); else return $this->neighbor->pSeg->Xc(); } else if ($g) return $this->nSeg->Xc(); else return $this->pSeg->Xc(); } function Yc ($g = TRUE) { if ($this->isIntersect()) { if ($this->neighbor->isEntry()) return $this->neighbor->nSeg->Yc(); else return $this->neighbor->pSeg->Yc(); } else if ($g) return $this->nSeg->Yc(); else return $this->pSeg->Yc(); } function d ($g = TRUE) { if ($this->isIntersect()) { if ($this->neighbor->isEntry()) return $this->neighbor->nSeg->d(); else return (-1*$this->neighbor->pSeg->d()); } else if ($g) return $this->nSeg->d(); else return (-1*$this->pSeg->d()); } /* ** Set Xc/Yc (Only for segment pointed to by Nseg) */ function setXc ($xc) { $this->nSeg->setXc($xc); } function setYc ($yc) { $this->nSeg->setYc($yc); } /* ** Set/Get the reference to the next vertex */ function setNext (&$nextV){ $this->nextV =& $nextV; } function &Next (){ return $this->nextV; } /* ** Set/Get the reference to the previous vertex */ function setPrev (&$prevV){ $this->prevV =& $prevV; } function &Prev (){ return $this->prevV; } /* ** Set/Get the reference to the next segment */ function setNseg (&$nSeg){ $this->nSeg =& $nSeg; } function &Nseg (){ return $this->nSeg; } /* ** Set/Get the reference to the previous segment */ function setPseg (&$pSeg){ $this->pSeg =& $pSeg; } function &Pseg (){ return $this->pSeg; } /* ** Set/Get reference to the next Polygon */ function setNextPoly (&$nextPoly){ $this->nextPoly =& $nextPoly; } function &NextPoly (){ return $this->nextPoly; } /* ** Set/Get reference to neighbor polygon */ function setNeighbor (&$neighbor){ $this->neighbor =& $neighbor; } function &Neighbor (){ return $this->neighbor; } /* ** Get alpha */ function Alpha (){ return $this->alpha; } /* ** Test for intersection */ function isIntersect (){ return $this->intersect; } /* ** Set/Test for checked flag */ function setChecked($check = TRUE) { $this->checked = $check; if ($this->neighbor && !$this->neighbor->isChecked()) $this->neighbor->setChecked(); } function isChecked () { return $this->checked; } /* ** Set/Test entry */ function setEntry ($entry = TRUE){ $this->entry = $entry; } function isEntry (){ return $this->entry; } /* ** Print Vertex used for debugging */ function print_vertex() { print("(".$this->x.")(".$this->y.") "); if ($this->nSeg->d() != 0) print(" c(".$this->nSeg->Xc().")(".$this->nSeg->Yc().")(".$this->nSeg->d().") "); if ($this->intersect) { print("Intersection with alpha=".$this->alpha." "); if ($this->entry) print(" Entry"); else print(" Exit");} if ($this->checked) print(" Checked"); else print(" Unchecked"); print("<br>"); } } //end of class vertex ?>