@param WKBBuffer        $buffer
@param CoordinateSystem $cs

@return Polygon
431370
private function readPolygon(WKBBuffer $buffer, CoordinateSystem $cs) : Polygon
    {
        $numRings = $buffer->readUnsignedLong();

        $rings = [];

        for ($i = 0; $i < $numRings; $i++) {
            $rings[] = $this->readLineString($buffer, $cs);
        }

        return new Polygon($cs, ...$rings);
    }
1277530
public static DZcsd cs_ddone (DZcsd D, DZcs C, int [] w, boolean ok)
	{
	//	    cs_spfree (C) ;                     /* free temporary matrix */
	//	    cs_free (w) ;                       /* free workspace */
		return (ok ? D : null) ;    /* return result if OK, else free it */
	}
699874
function(offsetvector) {
            var newpolygons = [];

            var polygon1 = this;
            var direction = polygon1.plane.normal.dot(offsetvector);
            if (direction > 0) {
                polygon1 = polygon1.flipped();
            }
            newpolygons.push(polygon1);
            var polygon2 = polygon1.translate(offsetvector);
            var numvertices = this.vertices.length;
            for (var i = 0; i < numvertices; i++) {
                var sidefacepoints = [];
                var nexti = (i < (numvertices - 1)) ? i + 1 : 0;
                sidefacepoints.push(polygon1.vertices[i].pos);
                sidefacepoints.push(polygon2.vertices[i].pos);
                sidefacepoints.push(polygon2.vertices[nexti].pos);
                sidefacepoints.push(polygon1.vertices[nexti].pos);
                var sidefacepolygon = CSG.Polygon.createFromPoints(sidefacepoints, this.shared);
                newpolygons.push(sidefacepolygon);
            }
            polygon2 = polygon2.flipped();
            newpolygons.push(polygon2);
            return CSG.fromPolygons(newpolygons);
        }
1077213
function(shared) {
            var polygons = this.polygons.map(function(p) {
                return new CSG.Polygon(p.vertices, shared, p.plane);
            });
            var result = CSG.fromPolygons(polygons);
            result.properties = this.properties; // keep original properties
            result.isRetesselated = this.isRetesselated;
            result.isCanonicalized = this.isCanonicalized;
            return result;
        }
1354936
private function readMultiPolygonText(WKTParser $parser, CoordinateSystem $cs) : MultiPolygon
    {
        $parser->matchOpener();
        $polygons = [];

        do {
            $polygons[] = $this->readPolygonText($parser, $cs);
            $nextToken = $parser->getNextCloserOrComma();
        } while ($nextToken === ',');

        return new MultiPolygon($cs, ...$polygons);
    }
854692
public static long[] shape(DataBuffer buffer) {
        val ret = new long[rank(buffer)];
        for (int i = 0; i < ret.length; i++)
            ret[i] = buffer.getInt(1 + i);
        return ret;
    }
14383
private function readCircularStringText(WKTParser $parser, CoordinateSystem $cs) : CircularString
    {
        $points = $this->readMultiPoint($parser, $cs);

        return new CircularString($cs, ...$points);
    }
459312
public static MultiPolygon of(Stream<Polygon> polygons) {
        return of(polygons.collect(Collectors.toList()));
    }
691057
public void appendToBuffer(StringBuilder buf) {
    Iterator<Polygon> iter = polygons.iterator();
    while(iter.hasNext()) {
      Polygon poly = iter.next();
      poly.appendToBuffer(buf);
      if(iter.hasNext()) {
        buf.append(" -- ");
      }
    }
  }
907693
public static DataBuffer shapeOf(DataBuffer buffer) {
        int rank = (int) buffer.getLong(0);
        return Nd4j.createBuffer(buffer, 1, rank);
    }
1006392
@Override
    public Quaternionf wrapQuaternion(ByteBuffer buffer, int offset) {
    	float w = buffer.getFloat(offset);
    	float x = buffer.getFloat(offset + 4);
    	float y = buffer.getFloat(offset + 8);
    	float z = buffer.getFloat(offset + 12);
        return new Quaternionf(x, y, z, w);
    }
610939
private function readMultiPointText(WKTParser $parser, CoordinateSystem $cs) : MultiPoint
    {
        $points = $this->readMultiPoint($parser, $cs);

        return new MultiPoint($cs, ...$points);
    }
1051414
function polygon($points, $color, $width = null, $style = null, $fill = false) {

    $this->_set_fill_color($color);
    $this->_set_stroke_color($color);

    if ( !$fill && isset($width) )
      $this->_set_line_style($width, "square", "miter", $style);

    $y = $this->y(array_pop($points));
    $x = array_pop($points);
    $this->_pdf->moveto($x,$y);

    while (count($points) > 1) {
      $y = $this->y(array_pop($points));
      $x = array_pop($points);
      $this->_pdf->lineto($x,$y);
    }

    if ( $fill )
      $this->_pdf->fill();
    else
      $this->_pdf->closepath_stroke();
  }
243899
private static function createPolygon(array $coordinates): Polygon
    {
        $polygon = array_shift($coordinates);

        return new Polygon(array_map(Coordinate::class.'::create', $polygon), ...array_map(function (array $poly) {
            return array_map(Coordinate::class.'::create', $poly);
        }, $coordinates));
    }
1166217
private function readCurvePolygonText(WKTParser $parser, CoordinateSystem $cs) : CurvePolygon
    {
        $parser->matchOpener();
        $curves = [];

        do {
            if ($parser->isNextOpenerOrWord()) {
                $curves[] = $this->readLineStringText($parser, $cs);
            } else {
                $curves[] = $this->readGeometry($parser, $cs->SRID());
            }

            $nextToken = $parser->getNextCloserOrComma();
        } while ($nextToken === ',');

        return new CurvePolygon($cs, ...$curves);
    }
1231843
function() {
            if (this.polygons.length === 0) {
                var m = new CSG.Matrix4x4(); // unity
                return [m,m];
            } else {
                // get a list of unique planes in the CSG:
                var csg = this.canonicalized();
                var planemap = {};
                csg.polygons.map(function(polygon) {
                    planemap[polygon.plane.getTag()] = polygon.plane;
                });
                // try each plane in the CSG and find the plane that, when we align it flat onto z=0,
                // gives the least height in z-direction.
                // If two planes give the same height, pick the plane that originally had a normal closest
                // to [0,0,-1].
                var xvector = new CSG.Vector3D(1, 0, 0);
                var yvector = new CSG.Vector3D(0, 1, 0);
                var zvector = new CSG.Vector3D(0, 0, 1);
                var z0connectorx = new CSG.Connector([0, 0, 0], [0, 0, -1], xvector);
                var z0connectory = new CSG.Connector([0, 0, 0], [0, 0, -1], yvector);
                var isfirst = true;
                var minheight = 0;
                var maxdotz = 0;
                var besttransformation, bestinversetransformation;
                for (var planetag in planemap) {
                    var plane = planemap[planetag];
                    var pointonplane = plane.normal.times(plane.w);
                    var transformation, inversetransformation;
                    // We need a normal vecrtor for the transformation
                    // determine which is more perpendicular to the plane normal: x or y?
                    // we will align this as much as possible to the x or y axis vector
                    var xorthogonality = plane.normal.cross(xvector).length();
                    var yorthogonality = plane.normal.cross(yvector).length();
                    if (xorthogonality > yorthogonality) {
                        // x is better:
                        var planeconnector = new CSG.Connector(pointonplane, plane.normal, xvector);
                        transformation = planeconnector.getTransformationTo(z0connectorx, false, 0);
                        inversetransformation = z0connectorx.getTransformationTo(planeconnector, false, 0);
                    } else {
                        // y is better:
                        var planeconnector = new CSG.Connector(pointonplane, plane.normal, yvector);
                        transformation = planeconnector.getTransformationTo(z0connectory, false, 0);
                        inversetransformation = z0connectory.getTransformationTo(planeconnector, false, 0);
                    }
                    var transformedcsg = csg.transform(transformation);
                    var dotz = -plane.normal.dot(zvector);
                    var bounds = transformedcsg.getBounds();
                    var zheight = bounds[1].z - bounds[0].z;
                    var isbetter = isfirst;
                    if (!isbetter) {
                        if (zheight < minheight) {
                            isbetter = true;
                        } else if (zheight == minheight) {
                            if (dotz > maxdotz) isbetter = true;
                        }
                    }
                    if (isbetter) {
                        // translate the transformation around the z-axis and onto the z plane:
                        var translation = new CSG.Vector3D([-0.5 * (bounds[1].x + bounds[0].x), -0.5 * (bounds[1].y + bounds[0].y), -bounds[0].z]);
                        transformation = transformation.multiply(CSG.Matrix4x4.translation(translation));
                        inversetransformation = CSG.Matrix4x4.translation(translation.negated()).multiply(inversetransformation);
                        minheight = zheight;
                        maxdotz = dotz;
                        besttransformation = transformation;
                        bestinversetransformation = inversetransformation;
                    }
                    isfirst = false;
                }
                return [besttransformation, bestinversetransformation];
            }
        }
1023038
public static Dcsn cs_qr(Dcs A, Dcss S) {
        double Rx[], Vx[], Ax[], x[], Beta[];
        int i, k, p, n, vnz, p1, top, m2, len, col, rnz, s[], leftmost[], Ap[], Ai[], parent[], Rp[], Ri[], Vp[], Vi[], w[], pinv[], q[];
        Dcs R, V;
        Dcsn N;
        if (!Dcs_util.CS_CSC(A) || S == null)
            return (null);
        n = A.n;
        Ap = A.p;
        Ai = A.i;
        Ax = A.x;
        q = S.q;
        parent = S.parent;
        pinv = S.pinv;
        m2 = S.m2;
        vnz = S.lnz;
        rnz = S.unz;
        leftmost = S.leftmost;
        w = new int[m2 + n]; /* get int workspace */
        x = new double[m2]; /* get double workspace */
        N = new Dcsn(); /* allocate result */
        s = w;
        int s_offset = m2; /* s is size n */
        for (k = 0; k < m2; k++)
            x[k] = 0; /* clear workspace x */
        N.L = V = Dcs_util.cs_spalloc(m2, n, vnz, true, false); /* allocate result V */
        N.U = R = Dcs_util.cs_spalloc(m2, n, rnz, true, false); /* allocate result R */
        N.B = Beta = new double[n]; /* allocate result Beta */
        Rp = R.p;
        Ri = R.i;
        Rx = R.x;
        Vp = V.p;
        Vi = V.i;
        Vx = V.x;
        for (i = 0; i < m2; i++)
            w[i] = -1; /* clear w, to mark nodes */
        rnz = 0;
        vnz = 0;
        for (k = 0; k < n; k++) /* compute V and R */
        {
            Rp[k] = rnz; /* R(:,k) starts here */
            Vp[k] = p1 = vnz; /* V(:,k) starts here */
            w[k] = k; /* add V(k,k) to pattern of V */
            Vi[vnz++] = k;
            top = n;
            col = q != null ? q[k] : k;
            for (p = Ap[col]; p < Ap[col + 1]; p++) /* find R(:,k) pattern */
            {
                i = leftmost[Ai[p]]; /* i = min(find(A(i,q))) */
                for (len = 0; w[i] != k; i = parent[i]) /* traverse up to k */
                {
                    s[s_offset + (len++)] = i;
                    w[i] = k;
                }
                while (len > 0)
                    s[s_offset + (--top)] = s[s_offset + (--len)]; /* push path on stack */
                i = pinv[Ai[p]]; /* i = permuted row of A(:,col) */
                x[i] = Ax[p]; /* x (i) = A(:,col) */
                if (i > k && w[i] < k) /* pattern of V(:,k) = x (k+1:m) */
                {
                    Vi[vnz++] = i; /* add i to pattern of V(:,k) */
                    w[i] = k;
                }
            }
            for (p = top; p < n; p++) /* for each i in pattern of R(:,k) */
            {
                i = s[s_offset + p]; /* R(i,k) is nonzero */
                Dcs_happly.cs_happly(V, i, Beta[i], x); /* apply (V(i),Beta(i)) to x */
                Ri[rnz] = i; /* R(i,k) = x(i) */
                Rx[rnz++] = x[i];
                x[i] = 0;
                if (parent[i] == k)
                    vnz = Dcs_scatter.cs_scatter(V, i, 0, w, null, k, V, vnz);
            }
            for (p = p1; p < vnz; p++) /* gather V(:,k) = x */
            {
                Vx[p] = x[Vi[p]];
                x[Vi[p]] = 0;
            }
            Ri[rnz] = k; /* R(k,k) = norm (x) */
            double[] beta = new double[1];
            beta[0] = Beta[k];
            Rx[rnz++] = Dcs_house.cs_house(Vx, p1, beta, vnz - p1); /* [v,beta]=house(x) */
            Beta[k] = beta[0];
        }
        Rp[n] = rnz; /* finalize R */
        Vp[n] = vnz; /* finalize V */
        return N;
    }