<!-- Converted by db4-upgrade version 1.1 -->
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="reference_sfcgal">
    <title>SFCGAL Functions Reference</title>
    <para>
        SFCGAL is a C++ wrapper library around CGAL that provides advanced 2D and 3D spatial functions.
        For robustness, geometry coordinates have an exact rational number representation.
    </para>
    <para>
        Installation instructions for the library can be found on the SFCGAL home page (<link xlink:href="http://www.sfcgal.org">http://www.sfcgal.org</link>).
        To enable the functions use <code>create extension postgis_sfcgal</code>.
    </para>

    <section xml:id="sfcgal_management">
        <title>SFCGAL Management Functions</title>
        <info>
            <abstract>
                <para>This section lists functions for determining version of SFCGAL and library dependencies you are running.</para>
            </abstract>
        </info>

        <refentry xml:id="postgis_sfcgal_version">
            <refnamediv>
                <refname>postgis_sfcgal_version</refname>

                <refpurpose>Returns the version of SFCGAL in use</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>text <function>postgis_sfcgal_version</function></funcdef>
                        <void/>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the version of SFCGAL in use</para>

                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
                <para>&sfcgal_required;</para>
            </refsection>
            <refsection>
                <title>See Also</title>

                <para><xref linkend="postgis_sfcgal_full_version"/></para>
            </refsection>

        </refentry>

        <refentry xml:id="postgis_sfcgal_full_version">
            <refnamediv>
                <refname>postgis_sfcgal_full_version</refname>

                <refpurpose>Returns the full version of SFCGAL in use including CGAL and Boost versions</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>text <function>postgis_sfcgal_full_version</function></funcdef>
                        <void/>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the full version of SFCGAL in use including CGAL and Boost versions</para>

                <para role="availability" conformance="3.3.0">Availability: 3.3.0</para>
                <para>&sfcgal_required;</para>
            </refsection>
            <refsection>
                <title>See Also</title>

                <para><xref linkend="postgis_sfcgal_version"/></para>
            </refsection>

        </refentry>
    </section>

    <section xml:id="sfcgal_accessors">
        <title>SFCGAL Accessors and Setters</title>
        <info>
            <abstract>
                <para>These functions access or set properties of geometries. Geometries primarily supported by these functions are TINS and Polyhedral Surfaces.</para>
            </abstract>
        </info>
        <refentry xml:id="CG_ForceLHR">
            <refnamediv>
                <refname>CG_ForceLHR</refname>

                <refpurpose>Force LHR orientation</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>geometry <function>CG_ForceLHR</function></funcdef>
                        <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Returns an equivalent geometry whose polygonal components
                    follow the left-hand rule: exterior rings are
                    counter-clockwise and interior rings are clockwise. Rings
                    are reversed as needed; coordinates and dimensionality are
                    preserved. The input must be valid.
                </para>
                <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
                <para>&sfcgal_required;</para>
                <para>&Z_support;</para>
                <para>&P_support;</para>
                <para>&T_support;</para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <para>Reorient a polygon and its hole to the left-hand rule.</para>
                <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((0 0,0 4,4 4,4 0,0 0),
                  (1 1,3 1,3 3,1 3,1 1))'::geometry AS geom
)
SELECT geom AS input_polygon,
       CG_ForceLHR(geom) AS lhr_polygon,
       ST_IsPolygonCCW(geom) AS input_is_lhr,
       ST_IsPolygonCCW(CG_ForceLHR(geom)) AS output_is_lhr
FROM data;</programlisting>
                <screen role="visual-primary text-primary visual-separate-output visual-direction docbook-qa-ignore-wide-lines">POLYGON((0 0,0 4,4 4,4 0,0 0),(1 1,3 1,3 3,1 3,1 1)) | POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1,1 3,3 3,3 1,1 1)) | f | t</screen>
            </refsection>

        </refentry>

        <refentry xml:id="CG_IsPlanar">
            <refnamediv>
                <refname>CG_IsPlanar</refname>

                <refpurpose>Check if a surface is or not planar</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>boolean <function>CG_IsPlanar</function></funcdef>
                        <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Tests whether the input geometry lies in a single plane in 3D.</para>
                <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
                <para>&sfcgal_required;</para>
                <para>&Z_support;</para>
                <para>&P_support;</para>
                <para>&T_support;</para>
            </refsection>

        </refentry>

        <refentry xml:id="CG_IsSolid">
            <refnamediv>
                <refname>CG_IsSolid</refname>

                <refpurpose>Test if the geometry is a solid. No validity check is performed.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>boolean <function>CG_IsSolid</function></funcdef>
                        <paramdef><type>geometry</type> <parameter>geom1</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Returns <varname>true</varname> when the input carries the
                    solid flag, such as a geometry produced by
                    <xref linkend="CG_MakeSolid"/>. A closed
                    <varname>PolyhedralSurface</varname> remains a surface until
                    it is explicitly converted. This tests the representation,
                    not shell closure or validity; no validity check is
                    performed.
                </para>
                <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
                <para>&sfcgal_required;</para>
                <para>&Z_support;</para>
                <para>&P_support;</para>
                <para>&T_support;</para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <para>Compare the same closed shell before and after converting it to a solid.</para>
                <programlisting language="sql">WITH data AS (
  SELECT 'POLYHEDRALSURFACE Z (
    ((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)),
    ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),
    ((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0)),
    ((1 1 0,1 1 1,1 0 1,1 0 0,1 1 0)),
    ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)),
    ((0 0 1,1 0 1,1 1 1,0 1 1,0 0 1))
  )'::geometry AS geom
)
SELECT CG_IsSolid(geom) AS shell_is_solid,
       CG_IsSolid(CG_MakeSolid(geom)) AS solid_is_solid
FROM data;</programlisting>
                <screen role="text-primary">f | t</screen>
            </refsection>

        </refentry>

        <refentry xml:id="CG_MakeSolid">
            <refnamediv>
                <refname>CG_MakeSolid</refname>

                <refpurpose>Cast the geometry into a solid. No check is performed. To obtain a valid solid, the input geometry must be a closed Polyhedral Surface or a closed TIN.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>geometry <function>CG_MakeSolid</function></funcdef>
                        <paramdef><type>geometry</type> <parameter>geom1</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Marks a PolyhedralSurface or TIN as a solid. The input is
                    expected to describe a closed shell; the function sets the
                    solid representation and does not validate the shell.
                </para>
                <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
                <para>&sfcgal_required;</para>
                <para>&Z_support;</para>
                <para>&P_support;</para>
                <para>&T_support;</para>
            </refsection>
        </refentry>

        <refentry xml:id="CG_Orientation">
            <refnamediv>
                <refname>CG_Orientation</refname>

                <refpurpose>Determine surface orientation</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>integer <function>CG_Orientation</function></funcdef>
                        <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>The function only applies to polygons. It returns -1 if the polygon is counterclockwise oriented and 1 if the polygon is clockwise oriented.</para>

                <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
                <para>&sfcgal_required;</para>
                <para>&Z_support;</para>
            </refsection>

        </refentry>

        <refentry xml:id="CG_Area">
            <refnamediv>
                <refname>CG_Area</refname>
                <refpurpose>Calculates the area of a geometry</refpurpose>
            </refnamediv>
            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>double precision <function>CG_Area</function></funcdef>
                        <paramdef>
                            <type>geometry</type>
                            <parameter>geom</parameter>
                        </paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>
            <refsection>
                <title>Description</title>
                <para>Calculates the area of a geometry.</para>
                <para>Performed by the SFCGAL module</para>
                <note>
                    <para>NOTE: this function returns a double precision value representing the area.</para>
                </note>
                <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
                <para>&sfcgal_required;</para>
            </refsection>
            <refsection>
                <title>Geometry Examples</title>
                <programlisting language="sql">SELECT CG_Area('Polygon ((0 0,0 5,5 5,5 0,0 0),(1 1,2 1,2 2,1 2,1 1),(3 3,4 3,4 4,3 4,3 3))');</programlisting>
<screen role="text-primary">23</screen>
        </refsection>
        <refsection>
            <title>See Also</title>
            <para><xref linkend="CG_3DArea"/>, <xref linkend="ST_Area"/></para>
        </refsection>
    </refentry>

    <refentry xml:id="CG_3DArea">
        <refnamediv>
            <refname>CG_3DArea</refname>

            <refpurpose>Computes area of 3D surface geometries.  Will return 0 for solids.</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>float<function>CG_3DArea</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom1</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
            <para>&sfcgal_required;</para>
            <para>&sqlmm_compliant; SQL-MM IEC 13249-3: 8.1, 10.5</para>
            <para>&Z_support;</para>
            <para>&P_support;</para>
            <para>&T_support;</para>
        </refsection>

        <refsection>
            <title>Examples</title>
            <para>Note: By default a PolyhedralSurface built from WKT is a surface geometry, not solid.  It therefore has surface area.  Once converted to a solid, no area.</para>
            <programlisting language="sql">SELECT CG_3DArea(geom) As cube_surface_area,
CG_3DArea(CG_MakeSolid(geom)) As solid_surface_area
FROM (SELECT 'POLYHEDRALSURFACE( ((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)),
((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),
((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0)),
((1 1 0,1 1 1,1 0 1,1 0 0,1 1 0)),
((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)),
((0 0 1,1 0 1,1 1 1,0 1 1,0 0 1)) )'::geometry) As f(geom);</programlisting>
<screen role="text-primary">cube_surface_area │ solid_surface_area
──────────────────┼────────────────────
6                 │ 0</screen>

    </refsection>
    <refsection>
        <title>See Also</title>
        <para><xref linkend="CG_Area"/>, <xref linkend="CG_MakeSolid"/>, <xref linkend="CG_IsSolid"/>, <xref linkend="CG_Area"/></para>
    </refsection>
</refentry>


<refentry xml:id="CG_Volume">
    <refnamediv>
        <refname>CG_Volume</refname>

        <refpurpose>Computes the volume of a 3D geometry. Closed surfaces can have non-zero volume.</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
        <funcsynopsis>
            <funcprototype>
                <funcdef>float <function>CG_Volume</function></funcdef>
                <paramdef><type>geometry</type> <parameter>geom1</parameter></paramdef>
            </funcprototype>
        </funcsynopsis>
    </refsynopsisdiv>

    <refsection>
        <title>Description</title>

        <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
        <para>&sfcgal_required;</para>
        <para>&Z_support;</para>
        <para>&P_support;</para>
        <para>&T_support;</para>
        <para>&sqlmm_compliant; SQL-MM IEC 13249-3: 9.1 (same as CG_3DVolume)</para>
        <para>Closed surface geometries can have non-zero volume. Use
        <xref linkend="CG_MakeSolid"/> when the geometry value itself must carry
        the solid flag.</para>
    </refsection>

    <refsection>
        <title>Example</title>
        <para>A closed polyhedral surface has volume.  <xref linkend="CG_MakeSolid"/> makes the solid representation explicit.</para>
    <programlisting language="sql">SELECT CG_Volume(geom) As cube_surface_vol,
CG_Volume(CG_MakeSolid(geom)) As solid_surface_vol
FROM (SELECT 'POLYHEDRALSURFACE( ((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)),
((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),
((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0)),
((1 1 0,1 1 1,1 0 1,1 0 0,1 1 0)),
((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)),
((0 0 1,1 0 1,1 1 1,0 1 1,0 0 1)) )'::geometry) As f(geom);</programlisting>
<screen role="text-primary">cube_surface_vol │ solid_surface_vol
─────────────────┼──────────────────
1                │ 1</screen>
    </refsection>

    <refsection>
        <title>See Also</title>

        <para><xref linkend="CG_3DArea"/>, <xref linkend="CG_MakeSolid"/>, <xref linkend="CG_IsSolid"/></para>
    </refsection>

</refentry>
</section>

    <section xml:id="sfcgal_processing">
        <title>SFCGAL Processing and Relationship Functions</title>

        <refentry xml:id="CG_Intersection">
            <refnamediv>
                <refname>CG_Intersection</refname>
                <refpurpose>Computes the intersection of two geometries</refpurpose>
            </refnamediv>
            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>geometry <function>CG_Intersection</function></funcdef>
                        <paramdef>
                            <type>geometry</type>
                            <parameter>geomA</parameter>
                        </paramdef>
                        <paramdef>
                            <type>geometry</type>
                            <parameter>geomB</parameter>
                        </paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>
            <refsection>
                <title>Description</title>
                <para>Computes the intersection of two geometries.</para>
                <para>Performed by the SFCGAL module</para>
                <note>
                    <para>NOTE: this function returns a geometry representing the intersection.</para>
                </note>
                <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
                <para>&sfcgal_required;</para>
            </refsection>
            <refsection>
                <title>Geometry Examples</title>
                <programlisting language="sql">SELECT CG_Intersection('LINESTRING(0 0,5 5)', 'LINESTRING(5 0,0 5)');</programlisting>
<screen role="visual-primary text-primary">POINT(2.5 2.5)</screen>
        </refsection>
        <refsection>
            <title>See Also</title>
            <para><xref linkend="CG_3DIntersection"/>, <xref linkend="ST_Intersection"/></para>
        </refsection>
    </refentry>

    <refentry xml:id="CG_Intersects">
        <refnamediv>
            <refname>CG_Intersects</refname>

            <refpurpose>Tests if two geometries intersect (they have at least one point in common)</refpurpose>
        </refnamediv>
        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>boolean <function>CG_Intersects</function></funcdef>
                    <paramdef>
                        <type>geometry</type>
                        <parameter>geomA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>geometry</type>
                        <parameter>geomB</parameter>
                    </paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>
        <refsection>
            <title>Description</title>
            <para>Returns <varname>true</varname> if two geometries intersect.
            Geometries intersect if they have any point in common.
        </para>

        <para>Performed by the SFCGAL module</para>
        <note>
            <para>NOTE: this is the "allowable" version that returns a
            boolean, not an integer.</para>
    </note>
    <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
    <para>&sfcgal_required;</para>
    <!-- Optionally mention support for Triangles and TINS  -->
    <para>&T_support;</para>
</refsection>
<refsection>
    <title>Geometry Examples</title>
    <programlisting language="sql">SELECT CG_Intersects('POINT(0 0)'::geometry, 'LINESTRING ( 2 0,0 2 )'::geometry);</programlisting>
<screen role="text-primary">f</screen>
<programlisting language="sql">SELECT CG_Intersects('POINT(0 0)'::geometry, 'LINESTRING ( 0 0,0 2 )'::geometry);</programlisting>
<screen role="text-primary">t</screen>
    </refsection>
    <refsection>
        <title>See Also</title>
        <para><xref linkend="CG_3DIntersects"/>, <xref linkend="ST_3DIntersects"/>, <xref linkend="ST_Intersects"/>, <xref linkend="ST_Disjoint"/></para>
    </refsection>
</refentry>

<refentry xml:id="CG_3DIntersects">
    <refnamediv>
        <refname>CG_3DIntersects</refname>
        <refpurpose>Tests if two 3D geometries intersect</refpurpose>
    </refnamediv>
    <refsynopsisdiv>
        <funcsynopsis>
            <funcprototype>
                <funcdef>boolean <function>CG_3DIntersects</function></funcdef>
                <paramdef>
                    <type>geometry</type>
                    <parameter>geomA</parameter>
                </paramdef>
                <paramdef>
                    <type>geometry</type>
                    <parameter>geomB</parameter>
                </paramdef>
            </funcprototype>
        </funcsynopsis>
    </refsynopsisdiv>
    <refsection>
        <title>Description</title>
        <para>Tests if two 3D geometries intersect. 3D geometries intersect if they have any point in common in the three-dimensional space.</para>
        <para>Performed by the SFCGAL module</para>
        <note>
            <para>NOTE: this is the "allowable" version that returns a boolean, not an integer.</para>
        </note>
        <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
        <para>&sfcgal_required;</para>
        <!-- Optionally mention support for Triangles and TINS  -->
        <para>&T_support;</para>
    </refsection>
    <refsection>
        <title>Geometry Examples</title>
        <programlisting language="sql">SELECT CG_3DIntersects('POINT(1.2 0.1 0)', 'POLYHEDRALSURFACE(((0 0 0,0.5 0.5 0,1 0 0,1 1 0,0 1 0,0 0 0)),((1 0 0,2 0 0,2 1 0,1 1 0,1 0 0),(1.2 0.2 0,1.2 0.8 0,1.8 0.8 0,1.8 0.2 0,1.2 0.2 0)))');</programlisting>
<screen role="text-primary">t</screen>
</refsection>
<refsection>
    <title>See Also</title>
    <para><xref linkend="CG_Intersects"/>, <xref linkend="ST_3DIntersects"/>, <xref linkend="ST_Intersects"/>, <xref linkend="ST_Disjoint"/></para>
</refsection>
</refentry>

<refentry xml:id="CG_Difference">
    <refnamediv>
        <refname>CG_Difference</refname>
        <refpurpose>Computes the geometric difference between two geometries</refpurpose>
    </refnamediv>
    <refsynopsisdiv>
        <funcsynopsis>
            <funcprototype>
                <funcdef>geometry <function>CG_Difference</function></funcdef>
                <paramdef>
                    <type>geometry</type>
                    <parameter>geomA</parameter>
                </paramdef>
                <paramdef>
                    <type>geometry</type>
                    <parameter>geomB</parameter>
                </paramdef>
            </funcprototype>
        </funcsynopsis>
    </refsynopsisdiv>
    <refsection>
        <title>Description</title>
        <para>Computes the geometric difference between two geometries.
        The resulting geometry is a set of points that are present in geomA but not in geomB.</para>
    <para>Performed by the SFCGAL module</para>
    <note>
        <para>NOTE: this function returns a geometry.</para>
    </note>
    <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
    <para>&sfcgal_required;</para>
    <!-- Optionally mention support for Triangles and TINS  -->
    <para>&T_support;</para>
</refsection>
<refsection>
    <title>Geometry Examples</title>
    <programlisting language="sql">SELECT CG_Difference('POLYGON((0 0,0 1,1 1,1 0,0 0))'::geometry, 'LINESTRING(0 0,2 2)'::geometry);</programlisting>
<screen role="visual-primary text-primary">POLYGON((0 0,1 0,1 1,0 1,0 0))</screen>
    </refsection>
    <refsection>
        <title>See Also</title>
        <para><xref linkend="CG_3DDifference"/>, <xref linkend="ST_Difference"/></para>
    </refsection>
</refentry>

<refentry xml:id="CG_3DDifference">
    <refnamediv>
        <refname>CG_3DDifference</refname>

        <refpurpose>Perform 3D difference</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
        <funcsynopsis>
            <funcprototype>
                <funcdef>geometry <function>CG_3DDifference</function></funcdef>
                <paramdef><type>geometry</type> <parameter>geom1</parameter></paramdef>
                <paramdef><type>geometry</type> <parameter>geom2</parameter></paramdef>
            </funcprototype>
        </funcsynopsis>
    </refsynopsisdiv>

    <refsection>
        <title>Description</title>

        <para>Returns that part of geom1 that is not part of geom2.</para>
        <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
        <para>&sfcgal_required;</para>
        <para>&sqlmm_compliant; SQL-MM IEC 13249-3: 5.1</para>
        <para>&Z_support;</para>
        <para>&P_support;</para>
        <para>&T_support;</para>
    </refsection>

    <refsection>
        <title>Examples</title>
        <para>Subtract a smaller tetrahedral solid and render the two inputs and the actual remaining solid separately.</para>
        <programlisting language="sql" role="documented-output">WITH data AS (
  SELECT CG_MakeSolid('POLYHEDRALSURFACE Z (
    ((0 0 0,0 4 0,4 0 0,0 0 0)),
    ((0 0 0,4 0 0,0 0 4,0 0 0)),
    ((0 0 0,0 0 4,0 4 0,0 0 0)),
    ((4 0 0,0 4 0,0 0 4,4 0 0))
  )'::geometry) AS outer_solid
), solids AS (
  SELECT outer_solid,
         ST_Scale(outer_solid, 0.5, 0.5, 0.5) AS inner_solid
  FROM data
)
SELECT outer_solid AS input_outer,
       inner_solid AS input_inner,
       CG_3DDifference(outer_solid, inner_solid) AS difference
FROM solids;</programlisting>
        <screen role="visual-primary visual-separate-output docbook-qa-ignore-wide-lines">POLYHEDRALSURFACE Z (((0 0 0,0 4 0,4 0 0,0 0 0)),((0 0 0,4 0 0,0 0 4,0 0 0)),((0 0 0,0 0 4,0 4 0,0 0 0)),((4 0 0,0 4 0,0 0 4,4 0 0))) | POLYHEDRALSURFACE Z (((0 0 0,0 2 0,2 0 0,0 0 0)),((0 0 0,2 0 0,0 0 2,0 0 0)),((0 0 0,0 0 2,0 2 0,0 0 0)),((2 0 0,0 2 0,0 0 2,2 0 0))) | POLYHEDRALSURFACE Z (((0 2 0,4 0 0,2 0 0,0 2 0)),((0 0 2,2 0 0,0 0 4,0 0 2)),((0 0 2,0 4 0,0 2 0,0 0 2)),((4 0 0,0 4 0,0 0 4,4 0 0)),((4 0 0,0 2 0,0 4 0,4 0 0)),((2 0 0,4 0 0,0 0 4,2 0 0)),((0 4 0,0 0 2,0 0 4,0 4 0)),((0 0 2,0 2 0,2 0 0,0 0 2)))</screen>

    </refsection>

    <refsection>
        <title>See Also</title>

        <para>
            <xref linkend="CG_Extrude"/>,
            <xref linkend="ST_AsX3D"/>,  <xref linkend="CG_3DIntersection"/>
            <xref linkend="CG_3DUnion"/>
        </para>
    </refsection>
</refentry>

<refentry xml:id="CG_Distance">
    <refnamediv>
        <refname>CG_Distance</refname>
        <refpurpose>Computes the minimum distance between two geometries</refpurpose>
    </refnamediv>
    <refsynopsisdiv>
        <funcsynopsis>
            <funcprototype>
                <funcdef>double precision <function>CG_Distance</function></funcdef>
                <paramdef>
                    <type>geometry</type>
                    <parameter>geomA</parameter>
                </paramdef>
                <paramdef>
                    <type>geometry</type>
                    <parameter>geomB</parameter>
                </paramdef>
            </funcprototype>
        </funcsynopsis>
    </refsynopsisdiv>
    <refsection>
        <title>Description</title>
        <para>Computes the minimum distance between two geometries.</para>
        <para>Performed by the SFCGAL module</para>
        <note>
            <para>NOTE: this function returns a double precision value representing the distance.</para>
        </note>
        <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
        <para>&sfcgal_required;</para>
        <!-- Optionally mention support for Triangles and TINS  -->
        <para>&T_support;</para>
    </refsection>
    <refsection>
        <title>Geometry Examples</title>
        <programlisting language="sql">SELECT CG_Distance('LINESTRING(0.0 0.0,-1.0 -1.0)', 'LINESTRING(3.0 4.0,4.0 5.0)');</programlisting>
<screen role="text-primary">5</screen>
</refsection>
<refsection>
    <title>See Also</title>
    <para><xref linkend="CG_3DDistance"/>, <xref linkend="CG_Distance"/></para>
</refsection>
</refentry>

<refentry xml:id="CG_3DDistance">
    <refnamediv>
        <refname>CG_3DDistance</refname>
        <refpurpose>Computes the minimum 3D distance between two geometries</refpurpose>
    </refnamediv>
    <refsynopsisdiv>
        <funcsynopsis>
            <funcprototype>
                <funcdef>double precision <function>CG_3DDistance</function></funcdef>
                <paramdef>
                    <type>geometry</type>
                    <parameter>geomA</parameter>
                </paramdef>
                <paramdef>
                    <type>geometry</type>
                    <parameter>geomB</parameter>
                </paramdef>
            </funcprototype>
        </funcsynopsis>
    </refsynopsisdiv>
    <refsection>
        <title>Description</title>
        <para>Computes the minimum 3D distance between two geometries.</para>
        <para>Performed by the SFCGAL module</para>
        <note>
            <para>NOTE: this function returns a double precision value representing the 3D distance.</para>
        </note>
        <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
        <para>&sfcgal_required;</para>
        <!-- Optionally mention support for Triangles and TINS  -->
        <para>&T_support;</para>
    </refsection>
    <refsection>
        <title>Geometry Examples</title>
        <programlisting language="sql">SELECT CG_3DDistance('LINESTRING(-1.0 0.0 2.0,1.0 0.0 3.0)', 'TRIANGLE((-4.0 0.0 1.0,4.0 0.0 1.0,0.0 4.0 1.0,-4.0 0.0 1.0))');</programlisting>
<screen role="text-primary">1</screen>
</refsection>
<refsection>
    <title>See Also</title>
    <para><xref linkend="CG_Distance"/>, <xref linkend="ST_3DDistance"/></para>
</refsection>
</refentry>

<refentry xml:id="CG_3DConvexHull">
    <refnamediv>
        <refname>CG_3DConvexHull</refname>

        <refpurpose>Computes the 3D convex hull of a geometry.</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
        <funcsynopsis>
            <funcprototype>
                <funcdef>geometry <function>CG_3DConvexHull</function></funcdef>
                <paramdef><type>geometry</type> <parameter>geom1</parameter></paramdef>
            </funcprototype>
        </funcsynopsis>
    </refsynopsisdiv>

    <refsection>
        <title>Description</title>

        <para>
            Computes the smallest convex three-dimensional geometry that
            contains the input. Unlike <xref linkend="ST_ConvexHull"/>, this
            function uses Z coordinates when constructing the hull.
        </para>
        <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
        <para>&sfcgal_required;</para>
        <para>&Z_support;</para>
        <para>&P_support;</para>
        <para>&T_support;</para>
    </refsection>

    <refsection>
        <title>Examples</title>
        <para>Compute the 3D convex hull of a 3D LineString.</para>
        <programlisting language="sql">WITH data AS (
  SELECT 'LINESTRING Z(0 0 5,1 5 3,5 7 6,9 5 3,5 7 5,6 3 5)'::geometry AS source_line
)
SELECT CG_3DConvexHull(source_line) AS convex_hull
FROM data;</programlisting>
        <screen role="visual-primary text-primary docbook-qa-ignore-wide-lines">POLYHEDRALSURFACE Z (((1 5 3,9 5 3,0 0 5,1 5 3)),((1 5 3,0 0 5,5 7 6,1 5 3)),((5 7 6,5 7 5,1 5 3,5 7 6)),((0 0 5,6 3 5,5 7 6,0 0 5)),((6 3 5,9 5 3,5 7 6,6 3 5)),((0 0 5,9 5 3,6 3 5,0 0 5)),((9 5 3,5 7 5,5 7 6,9 5 3)),((1 5 3,5 7 5,9 5 3,1 5 3)))</screen>

        <para>Compare the extruded source geometry with its 3D convex hull.</para>
        <programlisting language="sql">WITH footprints(label, geom, height) AS (VALUES
  ('C', 'POLYGON((0 0,0 8,5 8,5 6,2 6,2 2,5 2,5 0,0 0))'::geometry, 3),
  ('H', 'POLYGON((7 0,9 0,9 3,12 3,12 0,14 0,14 8,12 8,12 5,9 5,9 8,7 8,7 0))'::geometry, 7)
), parts AS (
  SELECT label, CG_Extrude(geom, 0, 0, height) AS geom
  FROM footprints
), shapes AS (
  SELECT ST_Collect(geom ORDER BY label) AS source_geometry
  FROM parts
)
SELECT
  source_geometry AS input_source_geometry,
  CG_3DConvexHull(source_geometry) AS convex_hull
FROM shapes;</programlisting>
<screen role="visual-primary text-primary visual-separate-output psql-expanded">-[ RECORD 1 ]----------
input_source_geometry | GEOMETRYCOLLECTION(POLYHEDRALSURFACE(((0 0 0,0 8 0,5 8 0,5 6 0,2 6 0,2 2 0,5 2 0,5 0 0,0 0 0)),((0 0 3,5 0 3,5 2 3,2 2 3,2 6 3,5 6 3,5 8 3,0 8 3,0 0 3)),((0 0 0,0 0 3,0 8 3,0 8 0,0 0 0)),((0 8 0,0 8 3,5 8 3,5 8 0,0 8 0)),((5 8 0,5 8 3,5 6 3,5 6 0,5 8 0)),((5 6 0,5 6 3,2 6 3,2 6 0,5 6 0)),((2 6 0,2 6 3,2 2 3,2 2 0,2 6 0)),((2 2 0,2 2 3,5 2 3,5 2 0,2 2 0)),((5 2 0,5 2 3,5 0 3,5 0 0,5 2 0)),((5 0 0,5 0 3,0 0 3,0 0 0,5 0 0))), POLYHEDRALSURFACE(((7 0 0,7 8 0,9 8 0,9 5 0,12 5 0,12 8 0,14 8 0,14 0 0,12 0 0,12 3 0,9 3 0,9 0 0,7 0 0)),((7 0 7,9 0 7,9 3 7,12 3 7,12 0 7,14 0 7,14 8 7,12 8 7,12 5 7,9 5 7,9 8 7,7 8 7,7 0 7)),((7 0 0,7 0 7,7 8 7,7 8 0,7 0 0)),((7 8 0,7 8 7,9 8 7,9 8 0,7 8 0)),((9 8 0,9 8 7,9 5 7,9 5 0,9 8 0)),((9 5 0,9 5 7,12 5 7,12 5 0,9 5 0)),((12 5 0,12 5 7,12 8 7,12 8 0,12 5 0)),((12 8 0,12 8 7,14 8 7,14 8 0,12 8 0)),((14 8 0,14 8 7,14 0 7,14 0 0,14 8 0)),((14 0 0,14 0 7,12 0 7,12 0 0,14 0 0)),((12 0 0,12 0 7,12 3 7,12 3 0,12 0 0)),((12 3 0,12 3 7,9 3 7,9 3 0,12 3 0)),((9 3 0,9 3 7,9 0 7,9 0 0,9 3 0)),((9 0 0,9 0 7,7 0 7,7 0 0,9 0 0))))
convex_hull           | POLYHEDRALSURFACE(((14 8 7,14 0 0,14 8 0,14 8 7)),((14 0 7,7 8 7,7 0 7,14 0 7)),((0 8 3,7 8 7,0 8 0,0 8 3)),((0 0 3,7 8 7,0 8 3,0 0 3)),((0 0 3,0 8 3,0 0 0,0 0 3)),((7 0 7,7 8 7,0 0 3,7 0 7)),((14 0 7,14 0 0,14 8 7,14 0 7)),((7 0 7,14 0 0,14 0 7,7 0 7)),((14 8 7,7 8 7,14 0 7,14 8 7)),((0 0 0,0 8 3,0 8 0,0 0 0)),((0 0 0,14 0 0,0 0 3,0 0 0)),((0 0 3,14 0 0,7 0 7,0 0 3)),((0 8 0,14 0 0,0 0 0,0 8 0)),((14 8 0,14 0 0,0 8 0,14 8 0)),((14 8 0,7 8 7,14 8 7,14 8 0)),((0 8 0,7 8 7,14 8 0,0 8 0)))</screen>
</refsection>
<refsection>
    <title>See Also</title>
    <para><xref linkend="ST_Letters"/>, <xref linkend="ST_AsX3D"/></para>
</refsection>
    </refentry>

<refentry xml:id="CG_3DIntersection">
        <refnamediv>
            <refname>CG_3DIntersection</refname>

            <refpurpose>Perform 3D intersection</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_3DIntersection</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom1</parameter></paramdef>
                    <paramdef><type>geometry</type> <parameter>geom2</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>Return a geometry that is the shared portion between geom1 and geom2.</para>
            <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
            <para>&sfcgal_required;</para>
            <para>&sqlmm_compliant; SQL-MM IEC 13249-3: 5.1</para>
            <para>&Z_support;</para>
            <para>&P_support;</para>
            <para>&T_support;</para>
        </refsection>

        <refsection>
            <title>Examples</title>
            <para>3D linestrings and polygons can intersect in a 3D segment.</para>
            <programlisting language="sql">WITH data AS (
  SELECT 'LINESTRING Z (2 2 6,1.5 1.5 7,1 1 8,0.5 0.5 8,0 0 10)'::geometry AS input_linestring,
         'POLYGON Z ((0 0 8,0 1 8,1 1 8,1 0 8,0 0 8))'::geometry AS input_polygon
)
SELECT input_linestring AS input_linestring,
       input_polygon AS input_polygon,
       CG_3DIntersection(input_linestring, input_polygon) AS intersection
FROM data;</programlisting>
            <screen role="visual-primary text-primary visual-overlay docbook-qa-ignore-wide-lines">LINESTRING Z (2 2 6,1.5 1.5 7,1 1 8,0.5 0.5 8,0 0 10) | POLYGON Z ((0 0 8,0 1 8,1 1 8,1 0 8,0 0 8)) | LINESTRING Z (1 1 8,0.5 0.5 8)</screen>

            <para>Intersect a cube shell with a vertical polygon.</para>
            <programlisting language="sql">WITH data AS (
  SELECT 'POLYHEDRALSURFACE Z(
    ((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)),
    ((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),
    ((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0)),
    ((1 1 0,1 1 1,1 0 1,1 0 0,1 1 0)),
    ((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)),
    ((0 0 1,1 0 1,1 1 1,0 1 1,0 0 1))
  )'::geometry AS input_cube,
  'POLYGON Z ((0 0 0,0 0 0.5,0 0.5 0.5,0 0.5 0,0 0 0))'::geometry AS input_polygon
)
SELECT input_cube AS input_cube,
       input_polygon AS input_polygon,
       CG_3DIntersection(input_cube, input_polygon) AS intersection
FROM data;</programlisting>
            <screen role="visual-primary text-primary visual-overlay docbook-qa-ignore-wide-lines">POLYHEDRALSURFACE Z (((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0)),((1 1 0,1 1 1,1 0 1,1 0 0,1 1 0)),((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)),((0 0 1,1 0 1,1 1 1,0 1 1,0 0 1))) | POLYGON Z ((0 0 0,0 0 0.5,0 0.5 0.5,0 0.5 0,0 0 0)) | TIN Z (((0 0 0,0 0 0.5,0 0.5 0.5,0 0 0)),((0 0.5 0,0 0 0,0 0.5 0.5,0 0.5 0)))</screen>

            <para>A smaller solid contained by a larger solid remains volumetric after intersection.</para>
            <programlisting language="sql" role="documented-output">WITH data AS (
  SELECT CG_MakeSolid('POLYHEDRALSURFACE Z (
    ((0 0 0,0 4 0,4 0 0,0 0 0)),
    ((0 0 0,4 0 0,0 0 4,0 0 0)),
    ((0 0 0,0 0 4,0 4 0,0 0 0)),
    ((4 0 0,0 4 0,0 0 4,4 0 0))
  )'::geometry) AS outer_solid
), solids AS (
  SELECT outer_solid,
         ST_Scale(outer_solid, 0.5, 0.5, 0.5) AS inner_solid
  FROM data
)
SELECT outer_solid AS input_outer,
       inner_solid AS input_inner,
       CG_3DIntersection(outer_solid, inner_solid) AS intersection
FROM solids;</programlisting>
            <screen role="visual-primary text-primary visual-separate-output docbook-qa-ignore-wide-lines">POLYHEDRALSURFACE Z (((0 0 0,0 4 0,4 0 0,0 0 0)),((0 0 0,4 0 0,0 0 4,0 0 0)),((0 0 0,0 0 4,0 4 0,0 0 0)),((4 0 0,0 4 0,0 0 4,4 0 0))) | POLYHEDRALSURFACE Z (((0 0 0,0 2 0,2 0 0,0 0 0)),((0 0 0,2 0 0,0 0 2,0 0 0)),((0 0 0,0 0 2,0 2 0,0 0 0)),((2 0 0,0 2 0,0 0 2,2 0 0))) | POLYHEDRALSURFACE Z (((0 0 0,0 2 0,2 0 0,0 0 0)),((0 0 0,0 0 2,0 2 0,0 0 0)),((2 0 0,0 0 2,0 0 0,2 0 0)),((2 0 0,0 2 0,0 0 2,2 0 0)))</screen>

</refsection>

        </refentry>

        <refentry xml:id="CG_Union">
            <refnamediv>
                <refname>CG_Union</refname>
                <refpurpose>Computes the union of two geometries</refpurpose>
            </refnamediv>
            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>geometry <function>CG_Union</function></funcdef>
                        <paramdef>
                            <type>geometry</type>
                            <parameter>geomA</parameter>
                        </paramdef>
                        <paramdef>
                            <type>geometry</type>
                            <parameter>geomB</parameter>
                        </paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>
            <refsection>
                <title>Description</title>
                <para>Computes the union of two geometries.</para>
                <para>Performed by the SFCGAL module</para>
                <note>
                    <para>NOTE: this function returns a geometry representing the union.</para>
                </note>
                <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
                <para>&sfcgal_required;</para>
            </refsection>
            <refsection>
                <title>Geometry Examples</title>
                <programlisting language="sql">SELECT CG_Union('POINT(.5 0)', 'LINESTRING(-1 0,1 0)');</programlisting>
<screen role="visual-primary text-primary">LINESTRING(-1 0,0.5 0,1 0)</screen>
        </refsection>
        <refsection>
            <title>See Also</title>
        <para><xref linkend="CG_3DUnion"/>, <xref linkend="ST_Union"/></para>
        </refsection>
    </refentry>

<refentry xml:id="CG_3DUnion">
        <refnamediv>
            <refname>CG_3DUnion</refname>

            <refpurpose>Perform 3D union using postgis_sfcgal.</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_3DUnion</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom1</parameter></paramdef>
                    <paramdef><type>geometry</type> <parameter>geom2</parameter></paramdef>
                </funcprototype>
                <funcprototype>
                    <funcdef>geometry <function>CG_3DUnion</function></funcdef>
                    <paramdef><type>geometry set</type> <parameter>g1field</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
            <para>&sfcgal_required;</para>
            <para>&sqlmm_compliant; SQL-MM IEC 13249-3: 5.1</para>
            <para>&Z_support;</para>
            <para>&P_support;</para>
            <para>&T_support;</para>

            <para>
                <emphasis role="bold">Aggregate variant:</emphasis>
                returns a geometry that is the 3D union of a rowset of geometries.
                The CG_3DUnion() function is an "aggregate"
                function in the terminology of PostgreSQL. That means that it
                operates on rows of data, in the same way the SUM() and AVG()
                functions do and like most aggregates, it also ignores NULL geometries.
            </para>
        </refsection>

        <refsection>
            <title>Examples</title>
        <para>Union two overlapping tetrahedral solids.</para>
        <programlisting language="sql">WITH solids AS (
  SELECT CG_MakeSolid('POLYHEDRALSURFACE Z (
           ((0 0 0,4 0 0,0 4 0,0 0 0)),
           ((0 0 0,0 0 4,4 0 0,0 0 0)),
           ((0 0 0,0 4 0,0 0 4,0 0 0)),
           ((4 0 0,0 0 4,0 4 0,4 0 0)))'::geometry) AS geom1,
         CG_MakeSolid('POLYHEDRALSURFACE Z (
           ((2 0 0,6 0 0,2 4 0,2 0 0)),
           ((2 0 0,2 0 4,6 0 0,2 0 0)),
           ((2 0 0,2 4 0,2 0 4,2 0 0)),
           ((6 0 0,2 0 4,2 4 0,6 0 0)))'::geometry) AS geom2
)
SELECT CG_3DUnion(geom1, geom2) AS union_result
FROM solids;</programlisting>
        <screen role="visual-primary text-primary docbook-qa-ignore-wide-lines">POLYHEDRALSURFACE Z (((2 0 0,0 0 0,2 2 0,2 0 0)),((2 0 2,0 0 0,2 0 0,2 0 2)),((0 0 4,0 4 0,0 0 0,0 0 4)),((2 0 2,0 4 0,0 0 4,2 0 2)),((0 4 0,2 2 0,0 0 0,0 4 0)),((2 2 0,0 4 0,2 0 2,2 2 0)),((0 0 0,2 0 2,0 0 4,0 0 0)),((4 0 0,2 0 0,2 2 0,4 0 0)),((4 0 0,2 0 2,2 0 0,4 0 0)),((4 0 0,2 2 0,6 0 0,4 0 0)),((2 0 2,4 0 0,2 0 4,2 0 2)),((2 0 2,2 4 0,2 2 0,2 0 2)),((2 4 0,2 0 4,6 0 0,2 4 0)),((2 2 0,2 4 0,6 0 0,2 2 0)),((2 4 0,2 0 2,2 0 4,2 4 0)),((4 0 0,6 0 0,2 0 4,4 0 0)))</screen>

</refsection>

<refsection>
    <title>See Also</title>

    <para>
        <xref linkend="CG_Extrude"/>,
        <xref linkend="ST_AsX3D"/>,  <xref linkend="CG_3DIntersection"/>
        <xref linkend="CG_3DDifference"/>
    </para>
</refsection>
        </refentry>

<refentry xml:id="CG_AlphaShape">
        <refnamediv>
            <refname>CG_AlphaShape</refname>

            <refpurpose>Computes an Alpha-shape enclosing a geometry</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_AlphaShape</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                    <paramdef choice="opt"><type>float </type> <parameter>alpha</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>allow_holes = false</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>Computes the
            <link xlink:href="https://en.wikipedia.org/wiki/Alpha_shape">Alpha-Shape</link>
            of the points in a geometry.
            An alpha-shape is a (usually) concave polygonal geometry which contains all the vertices of the input,
            and whose vertices are a subset of the input vertices.
            An alpha-shape provides a closer fit to the shape of the input
            than the shape produced by the <link linkend="ST_ConvexHull">convex hull</link>.
        </para>

        <para>
            The "closeness of fit" is controlled by the <varname>alpha</varname> parameter,
            which can have values from 0 to infinity.
            Smaller alpha values produce more concave results.
            Alpha values greater than some data-dependent value produce the convex hull of the input.
        </para>

        <note><para>
                Following the CGAL implementation, the alpha value is the <emphasis>square</emphasis> of the radius of the disc used
                in the Alpha-Shape algorithm to "erode" the Delaunay Triangulation of the input points.
                See <link xlink:href="https://doc.cgal.org/latest/Alpha_shapes_2/index.html#Chapter_2D_Alpha_Shapes">CGAL Alpha-Shapes</link>
                for more information.
                This is different from the original definition of alpha-shapes,
                which defines alpha as the radius of the eroding disc.
        </para></note>

        <para>The computed shape does not contain holes unless the optional <varname>allow_holes</varname> argument is specified as true.
    </para>

    <para>
        This function effectively computes a concave hull of a geometry in a similar way to <xref linkend="ST_ConcaveHull"/>,
        but uses CGAL and a different algorithm.
    </para>

    <para role="availability" conformance="3.5.0">Availability: 3.5.0 - requires SFCGAL &gt;= 1.4.1.</para>
    <para>&sfcgal_required;</para>
</refsection>

<refsection>
    <title>Examples</title>
    <para>The original point cloud and the alpha-shape share one comparison frame.</para>
    <programlisting language="sql">WITH data AS (
  SELECT 'MULTIPOINT((63 84),(76 88),(68 73),(53 18),(91 50),(81 70),
(88 29),(24 82),(32 51),(37 23),(27 54),(84 19),(75 87),(44 42),(77 67),(90 30),(36 61),(32 65),
(81 47),(88 58),(68 73),(49 95),(81 60),(87 50),
(78 16),(79 21),(30 22),(78 43),(26 85),(48 34),(35 35),(36 40),(31 79),(83 29),(27 84),(52 98),(72 95),(85 71),
(75 84),(75 77),(81 29),(77 73),(41 42),(83 72),(23 36),(89 53),(27 57),(57 97),(27 77),(39 88),(60 81),
(80 72),(54 32),(55 26),(62 22),(70 20),(76 27),(84 35),(87 42),(82 54),(83 64),(69 86),(60 90),(50 86),(43 80),(36 73),
(36 68),(40 75),(24 67),(23 60),(26 44),(28 33),(40 32),(43 19),(65 16),(73 16),(38 46),(31 59),(34 86),(45 90),(64 97))'::geometry AS input_points
)
SELECT input_points AS input_points,

         CG_AlphaShape(input_points, 80.2) AS alpha_shape
FROM data;</programlisting>
    <screen role="visual-primary visual-overlay docbook-qa-ignore-wide-lines">MULTIPOINT((63 84),(76 88),(68 73),(53 18),(91 50),(81 70),(88 29),(24 82),(32 51),(37 23),(27 54),(84 19),(75 87),(44 42),(77 67),(90 30),(36 61),(32 65),(81 47),(88 58),(68 73),(49 95),(81 60),(87 50),(78 16),(79 21),(30 22),(78 43),(26 85),(48 34),(35 35),(36 40),(31 79),(83 29),(27 84),(52 98),(72 95),(85 71),(75 84),(75 77),(81 29),(77 73),(41 42),(83 72),(23 36),(89 53),(27 57),(57 97),(27 77),(39 88),(60 81),(80 72),(54 32),(55 26),(62 22),(70 20),(76 27),(84 35),(87 42),(82 54),(83 64),(69 86),(60 90),(50 86),(43 80),(36 73),(36 68),(40 75),(24 67),(23 60),(26 44),(28 33),(40 32),(43 19),(65 16),(73 16),(38 46),(31 59),(34 86),(45 90),(64 97)) | MULTIPOLYGON(((89 53,88 58,85 71,83 72,75 84,76 88,72 95,64 97,57 97,52 98,49 95,45 90,39 88,34 86,26 85,24 82,27 77,24 67,23 60,27 54,26 44,23 36,28 33,30 22,37 23,43 19,53 18,65 16,73 16,78 16,84 19,88 29,90 30,87 42,91 50,89 53)))</screen>

    <para>The same point cloud can produce a shape with a hole when holes are allowed.</para>
    <programlisting language="sql">WITH data AS (
  SELECT 'MULTIPOINT((63 84),(76 88),(68 73),(53 18),(91 50),(81 70),(88 29),(24 82),(32 51),(37 23),(27 54),(84 19),(75 87),(44 42),(77 67),(90 30),(36 61),(32 65),(81 47),(88 58),(68 73),(49 95),(81 60),(87 50),
(78 16),(79 21),(30 22),(78 43),(26 85),(48 34),(35 35),(36 40),(31 79),(83 29),(27 84),(52 98),(72 95),(85 71),
(75 84),(75 77),(81 29),(77 73),(41 42),(83 72),(23 36),(89 53),(27 57),(57 97),(27 77),(39 88),(60 81),
(80 72),(54 32),(55 26),(62 22),(70 20),(76 27),(84 35),(87 42),(82 54),(83 64),(69 86),(60 90),(50 86),(43 80),(36 73),
(36 68),(40 75),(24 67),(23 60),(26 44),(28 33),(40 32),(43 19),(65 16),(73 16),(38 46),(31 59),(34 86),(45 90),(64 97))'::geometry AS input_points
)
SELECT input_points AS input_points,

         CG_AlphaShape(input_points, 100.1, true) AS alpha_shape
FROM data;</programlisting>
    <screen role="visual-primary visual-overlay docbook-qa-ignore-wide-lines">MULTIPOINT((63 84),(76 88),(68 73),(53 18),(91 50),(81 70),(88 29),(24 82),(32 51),(37 23),(27 54),(84 19),(75 87),(44 42),(77 67),(90 30),(36 61),(32 65),(81 47),(88 58),(68 73),(49 95),(81 60),(87 50),(78 16),(79 21),(30 22),(78 43),(26 85),(48 34),(35 35),(36 40),(31 79),(83 29),(27 84),(52 98),(72 95),(85 71),(75 84),(75 77),(81 29),(77 73),(41 42),(83 72),(23 36),(89 53),(27 57),(57 97),(27 77),(39 88),(60 81),(80 72),(54 32),(55 26),(62 22),(70 20),(76 27),(84 35),(87 42),(82 54),(83 64),(69 86),(60 90),(50 86),(43 80),(36 73),(36 68),(40 75),(24 67),(23 60),(26 44),(28 33),(40 32),(43 19),(65 16),(73 16),(38 46),(31 59),(34 86),(45 90),(64 97)) | MULTIPOLYGON(((89 53,88 58,85 71,83 72,75 84,76 88,72 95,64 97,57 97,52 98,49 95,45 90,39 88,34 86,26 85,24 82,27 77,24 67,23 60,27 54,26 44,23 36,28 33,30 22,43 19,53 18,65 16,73 16,78 16,84 19,90 30,87 42,91 50,89 53),(36 68,40 75,43 80,60 81,68 73,77 67,81 60,82 54,81 47,78 43,76 27,62 22,54 32,44 42,38 46,36 61,36 68)))</screen>

            <para>The second documented point cloud also produces a holed alpha-shape.</para>
            <programlisting language="sql">WITH data AS (
  SELECT 'MULTIPOINT ((132 64),(114 64),(99 64),(81 64),(63 64),(57 49),(52 36),(46 20),(37 20),(26 20),(32 36),(39 55),(43 69),(50 84),(57 100),(63 118),(68 133),(74 149),(81 164),(88 180),(101 180),(112 180),(119 164),(126 149),(132 131),(139 113),(143 100),(150 84),(157 69),(163 51),(168 36),(174 20),(163 20),(150 20),(143 36),(139 49),(132 64),(99 151),(92 138),(88 124),(81 109),(74 93),(70 82),(83 82),(99 82),(112 82),(126 82),(121 96),(114 109),(110 122),(103 138),(99 151),(34 27),(43 31),(48 44),(46 58),(52 73),(63 73),(61 84),(72 71),(90 69),(101 76),(123 71),(141 62),(166 27),(150 33),(159 36),(146 44),(154 53),(152 62),(146 73),(134 76),(143 82),(141 91),(130 98),(126 104),(132 113),(128 127),(117 122),(112 133),(119 144),(108 147),(119 153),(110 171),(103 164),(92 171),(86 160),(88 142),(79 140),(72 124),(83 131),(79 118),(68 113),(63 102),(68 93),(35 45))'::geometry AS input_points
)
SELECT input_points AS input_points,

         CG_AlphaShape(input_points, 102.2, true) AS alpha_shape
FROM data;</programlisting>
            <screen role="visual-primary visual-overlay docbook-qa-ignore-wide-lines">MULTIPOINT((132 64),(114 64),(99 64),(81 64),(63 64),(57 49),(52 36),(46 20),(37 20),(26 20),(32 36),(39 55),(43 69),(50 84),(57 100),(63 118),(68 133),(74 149),(81 164),(88 180),(101 180),(112 180),(119 164),(126 149),(132 131),(139 113),(143 100),(150 84),(157 69),(163 51),(168 36),(174 20),(163 20),(150 20),(143 36),(139 49),(132 64),(99 151),(92 138),(88 124),(81 109),(74 93),(70 82),(83 82),(99 82),(112 82),(126 82),(121 96),(114 109),(110 122),(103 138),(99 151),(34 27),(43 31),(48 44),(46 58),(52 73),(63 73),(61 84),(72 71),(90 69),(101 76),(123 71),(141 62),(166 27),(150 33),(159 36),(146 44),(154 53),(152 62),(146 73),(134 76),(143 82),(141 91),(130 98),(126 104),(132 113),(128 127),(117 122),(112 133),(119 144),(108 147),(119 153),(110 171),(103 164),(92 171),(86 160),(88 142),(79 140),(72 124),(83 131),(79 118),(68 113),(63 102),(68 93),(35 45)) | MULTIPOLYGON(((168 36,163 51,157 69,150 84,143 100,139 113,132 131,126 149,119 164,112 180,101 180,88 180,81 164,74 149,68 133,63 118,57 100,50 84,43 69,39 55,35 45,32 36,26 20,37 20,46 20,52 36,57 49,63 64,81 64,90 69,99 64,114 64,132 64,139 49,143 36,150 20,163 20,174 20,168 36),(81 109,88 124,92 138,103 138,110 122,114 109,121 96,112 82,99 82,83 82,74 93,81 109)))</screen>
</refsection>
<refsection>
    <title>See Also</title>
    <para><xref linkend="ST_ConcaveHull"/>, <xref linkend="CG_OptimalAlphaShape"/></para>
</refsection>

        </refentry>

        <refentry xml:id="CG_ApproxConvexPartition">
            <refnamediv>
                <refname>CG_ApproxConvexPartition</refname>

                <refpurpose>Computes approximal convex partition of the polygon geometry</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>geometry <function>CG_ApproxConvexPartition</function></funcdef>
                        <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Computes approximal convex partition of the polygon geometry (using a triangulation).
            </para>

            <note><para>
                    A partition of a polygon P is a set of polygons such that the interiors of the polygons do not intersect and the union of the polygons is equal to the interior of the original polygon P.
                    CG_ApproxConvexPartition and CG_GreeneApproxConvexPartition functions produce approximately optimal convex partitions. Both these functions produce convex decompositions by first decomposing the polygon into simpler polygons; CG_ApproxConvexPartition uses a triangulation and CG_GreeneApproxConvexPartition a monotone partition. These two functions both guarantee that they will produce no more than four times the optimal number of convex pieces but they differ in their runtime complexities. Though the triangulation-based approximation algorithm often results in fewer convex pieces, this is not always the case.
            </para></note>


            <para role="availability" conformance="3.5.0">Availability: 3.5.0 - requires SFCGAL &gt;= 1.5.0.</para>
            <para role="sfcgal_requirement" conformance="1.5.0">Requires SFCGAL &gt;= 1.5.0</para>
            <para>&sfcgal_required;</para>
        </refsection>

        <refsection>
            <title>Examples</title>
            <para>Approximate convex partition of the same polygon used by the other partition examples.</para>
            <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((156 150,83 181,89 131,148 120,107 61,32 159,0 45,41 86,45 1,177 2,67 24,109 31,170 60,180 110,156 150))'::geometry AS input_polygon
)
SELECT input_polygon AS input_polygon,
       CG_ApproxConvexPartition(input_polygon) AS partition
FROM data;</programlisting>
            <screen role="visual-primary text-primary visual-overlay docbook-qa-ignore-wide-lines">POLYGON((156 150,83 181,89 131,148 120,107 61,32 159,0 45,41 86,45 1,177 2,67 24,109 31,170 60,180 110,156 150)) | GEOMETRYCOLLECTION(POLYGON((156 150,83 181,89 131,148 120,156 150)), POLYGON((32 159,0 45,41 86,32 159)), POLYGON((107 61,32 159,41 86,107 61)), POLYGON((45 1,177 2,67 24,45 1)), POLYGON((41 86,45 1,67 24,41 86)), POLYGON((107 61,41 86,67 24,109 31,107 61)), POLYGON((148 120,107 61,109 31,170 60,148 120)), POLYGON((156 150,148 120,170 60,180 110,156 150)))</screen>
        </refsection>
        <refsection>
            <title>See Also</title>
            <para><xref linkend="CG_YMonotonePartition" />, <xref linkend="CG_GreeneApproxConvexPartition" />, <xref linkend="CG_OptimalConvexPartition" /></para>
        </refsection>

    </refentry>

<refentry xml:id="CG_ApproximateMedialAxis">
        <refnamediv>
            <refname>CG_ApproximateMedialAxis</refname>

            <refpurpose>Compute the approximate medial axis of an areal geometry.</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_ApproximateMedialAxis</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                </funcprototype>
                <funcprototype>
                    <funcdef>geometry <function>CG_ApproximateMedialAxis</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                    <paramdef><type>boolean</type> <parameter>projected</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>
                Return an approximate medial axis for the areal input based on
                its straight skeleton. Uses an SFCGAL specific API when built against
                a capable version (1.2.0+). Otherwise the function is just a wrapper
                around CG_StraightSkeleton (slower case).
            </para>
            <para>
                When <varname>projected</varname> is <varname>true</varname>, free
                endpoints of the medial axis are extended to reach the polygon boundary
                (projected medial axis). Requires SFCGAL 2.3.0+. When built against
                an older SFCGAL version, a notice is emitted and the non-projected
                result is returned instead.
            </para>

            <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
            <para role="availability" conformance="3.7.0">Availability: 3.7.0 - <varname>projected</varname> parameter. Requires SFCGAL &gt;= 2.3.0 for projected result; falls back to non-projected with a notice on older versions.</para>
            <note><para>This function ignores the Z dimension.
It always gives a 2D result even when used on a 3D geometry.</para></note>
            <para>&sfcgal_required;</para>
            <para>&P_support;</para>
            <para>&T_support;</para>
        </refsection>

        <refsection><title>Examples</title>
            <para>A polygon and its approximate medial axis.</para>
            <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((190 190,10 190,10 10,190 10,190 20,160 30,60 30,60 130,190 140,190 190))'::geometry AS polygon
)
SELECT polygon AS input_polygon,
       CG_ApproximateMedialAxis(polygon) AS medial_axis
FROM data;</programlisting>
            <screen role="visual-primary text-primary">POLYGON((190 190,10 190,10 10,190 10,190 20,160 30,60 30,60 130,190 140,190 190)) | MULTILINESTRING((184.189 15.811,158.377 20),(50 20,158.377 20),(50 20,35 35),(35 153.151,35 35),(35 153.151,40.697 159.303),(164.04 164.04,40.697 159.303))</screen>

            <para>This example computes the projected medial axis with free endpoints extended to the polygon boundary.</para>
            <programlisting language="sql">SELECT CG_ApproximateMedialAxis('POLYGON((0 0,2 0,2 1,0 1,0 0))', true);</programlisting>
<screen role="visual-primary text-primary">MULTILINESTRING((0 0.5,0.5 0.5,1.5 0.5,2 0.5))</screen>
        </refsection>

        <refsection>
            <title>See Also</title>

            <para><xref linkend="CG_StraightSkeleton"/>, <xref linkend="CG_StraightSkeletonPartition"/></para>
        </refsection>

    </refentry>

    <refentry xml:id="CG_GenerateFlatRoof">
        <refnamediv>
            <refname>CG_GenerateFlatRoof</refname>
            <refpurpose>Generate a flat (box) roof from a footprint polygon.</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_GenerateFlatRoof</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                    <paramdef choice="opt"><type>float8</type> <parameter>height</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>
            <para>
                Generate a flat (box-shaped) roof as a 3D
                <varname>PolyhedralSurface Z</varname> from a 2D footprint polygon.
                The roof height above the ground plane is given by
                <varname>height</varname> (default 3.0).
            </para>
            <para role="availability" conformance="3.7.0">Availability: 3.7.0 - requires SFCGAL &gt;= 2.3.0.</para>
            <para>&sfcgal_required;</para>
            <para>&P_support;</para>
        </refsection>

        <refsection>
            <title>Examples</title>
            <para>Generate a flat roof two units above a rectangular footprint.</para>
            <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((0 0,5 0,5 4,0 4,0 0))'::geometry AS footprint
)
SELECT CG_GenerateFlatRoof(footprint, 2.0) AS roof
FROM data;</programlisting>
<screen role="visual-primary text-primary">POLYHEDRALSURFACE Z (((0 0 0,0 4 0,5 4 0,5 0 0,0 0 0)),((0 0 2,5 0 2,5 4 2,0 4 2,0 0 2)),((0 0 0,0 0 2,0 4 2,0 4 0,0 0 0)),((0 4 0,0 4 2,5 4 2,5 4 0,0 4 0)),((5 4 0,5 4 2,5 0 2,5 0 0,5 4 0)),((5 0 0,5 0 2,0 0 2,0 0 0,5 0 0)))</screen>
        </refsection>

        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="CG_GenerateHippedRoof"/>,
                <xref linkend="CG_GenerateGableRoof"/>,
                <xref linkend="CG_GenerateSkillionRoof"/>,
                <xref linkend="CG_GenerateRoof"/>
            </para>
        </refsection>

    </refentry>

    <refentry xml:id="CG_GenerateHippedRoof">
        <refnamediv>
            <refname>CG_GenerateHippedRoof</refname>
            <refpurpose>Generate a hipped roof from a footprint polygon.</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_GenerateHippedRoof</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                    <paramdef choice="opt"><type>float8</type> <parameter>height</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>
            <para>
                Generate a hipped roof as a 3D <varname>PolyhedralSurface Z</varname>
                from a 2D footprint polygon. All sides slope upward to meet at a ridge
                or apex. The roof height is given by <varname>height</varname>
                (default 3.0).
            </para>
            <para role="availability" conformance="3.7.0">Availability: 3.7.0 - requires SFCGAL &gt;= 2.3.0.</para>
            <para>&sfcgal_required;</para>
            <para>&P_support;</para>
        </refsection>

        <refsection>
            <title>Examples</title>
            <para>The footprint and hipped roof are shown side-by-side so the generated 3D faces do not hide behind the input footprint.</para>
            <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((0 0,5 0,5 4,0 4,0 0))'::geometry AS input_footprint
)
SELECT input_footprint AS input_footprint,
       CG_GenerateHippedRoof(input_footprint, 2.0) AS hipped_roof
FROM data;</programlisting>
            <screen role="visual-primary text-primary visual-separate-output docbook-qa-ignore-wide-lines">POLYGON((0 0,5 0,5 4,0 4,0 0)) | POLYHEDRALSURFACE Z (((0 4 0,5 4 0,5 0 0,0 0 0,0 4 0)),((0 4 0,0 0 0,2 2 2,0 4 0)),((0 0 0,5 0 0,3 2 2,2 2 2,0 0 0)),((5 0 0,5 4 0,3 2 2,5 0 0)),((5 4 0,0 4 0,2 2 2,3 2 2,5 4 0)))</screen>
        </refsection>

        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="CG_GenerateFlatRoof"/>,
                <xref linkend="CG_GenerateGableRoof"/>,
                <xref linkend="CG_GenerateSkillionRoof"/>,
                <xref linkend="CG_GenerateRoof"/>
            </para>
        </refsection>

    </refentry>

    <refentry xml:id="CG_GenerateGableRoof">
        <refnamediv>
            <refname>CG_GenerateGableRoof</refname>
            <refpurpose>Generate a gable roof from a footprint polygon.</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_GenerateGableRoof</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                    <paramdef choice="opt"><type>float8</type> <parameter>height</parameter></paramdef>
                    <paramdef choice="opt"><type>float8</type> <parameter>slope_angle</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>
            <para>
                Generate a gable roof as a 3D <varname>PolyhedralSurface Z</varname>
                from a 2D footprint polygon. Two opposite sides are vertical gable
                ends; the other two sides slope to a horizontal ridge.
                <varname>height</varname> sets the ridge height above the ground
                (default 3.0) and <varname>slope_angle</varname> controls the pitch
                in degrees (default 30.0). The SRID of the input geometry is
                preserved.
            </para>
            <para role="availability" conformance="3.7.0">Availability: 3.7.0 - requires SFCGAL &gt;= 2.3.0.</para>
            <para>&sfcgal_required;</para>
            <para>&P_support;</para>
        </refsection>

        <refsection>
            <title>Examples</title>
            <para>Generate a gable roof using a height of 2 and a 30 degree slope.</para>
            <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((0 0,5 0,5 4,0 4,0 0))'::geometry AS footprint
)
SELECT CG_GenerateGableRoof(footprint, 2.0, 30.0) AS roof
FROM data;</programlisting>
<screen role="visual-primary text-primary">POLYHEDRALSURFACE Z (((5 4 0,5 0 0,0 0 0,0 4 0,5 4 0)),((0 4 0,0 0 0,0 2 1.155,0 4 0)),((0 0 0,5 0 0,5 2 1.155,0 2 1.155,0 0 0)),((5 0 0,5 4 0,5 2 1.155,5 0 0)),((5 4 0,0 4 0,0 2 1.155,5 2 1.155,5 4 0)))</screen>
        </refsection>

        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="CG_GenerateFlatRoof"/>,
                <xref linkend="CG_GenerateHippedRoof"/>,
                <xref linkend="CG_GenerateSkillionRoof"/>,
                <xref linkend="CG_GenerateRoof"/>
            </para>
        </refsection>

    </refentry>

    <refentry xml:id="CG_GenerateSkillionRoof">
        <refnamediv>
            <refname>CG_GenerateSkillionRoof</refname>
            <refpurpose>Generate a skillion (single-slope) roof from a footprint polygon.</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_GenerateSkillionRoof</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                    <paramdef choice="opt"><type>float8</type> <parameter>height</parameter></paramdef>
                    <paramdef choice="opt"><type>float8</type> <parameter>slope_angle</parameter></paramdef>
                    <paramdef choice="opt"><type>integer</type> <parameter>primary_edge_index</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>
            <para>
                Generate a skillion (single-slope, shed-style) roof as a 3D
                <varname>PolyhedralSurface Z</varname> from a 2D footprint polygon.
                The entire roof surface slopes in one direction.
                <varname>height</varname> sets the maximum ridge height (default 3.0),
                <varname>slope_angle</varname> sets the pitch in degrees (default
                30.0), and <varname>primary_edge_index</varname> selects which
                polygon edge defines the high side (0-based, default 0).
            </para>
            <para>
                When the combination of <varname>height</varname> and
                <varname>slope_angle</varname> would cause a side wall to vanish
                (the slope reaches the far edge before the full height is achieved),
                that face is omitted from the result. This means the number of
                output patches can vary depending on the parameters — a lower
                height relative to the footprint depth produces more faces than
                a taller, steeper configuration.
            </para>
            <para role="availability" conformance="3.7.0">Availability: 3.7.0 - requires SFCGAL &gt;= 2.3.0.</para>
            <para>&sfcgal_required;</para>
            <para>&P_support;</para>
        </refsection>

        <refsection>
            <title>Examples</title>
            <para>
                Height 2.0 produces 6 faces (all walls present); height 4.0
                produces 5 faces (one side wall is filtered out because the
                slope reaches the far edge before the full height).
            </para>
            <programlisting language="sql" role="visual-skip">SELECT
  ST_NumPatches(CG_GenerateSkillionRoof(
    'POLYGON((0 0,5 0,5 4,0 4,0 0))', 2.0)) AS "height 2",
  ST_NumPatches(CG_GenerateSkillionRoof(
    'POLYGON((0 0,5 0,5 4,0 4,0 0))', 4.0)) AS "height 4";</programlisting>
<screen role="text-primary">6 | 5</screen>

            <para>The height 2.0 result is shown with its footprint.</para>
            <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((0 0,5 0,5 4,0 4,0 0))'::geometry AS footprint
)
SELECT CG_GenerateSkillionRoof(footprint, 2.0) AS roof
FROM data;</programlisting>
<screen role="visual-primary text-primary">POLYHEDRALSURFACE Z (((0 4 0,5 4 0,5 0 0,0 0 0,0 4 0)),((5 0 2,5 4 2,3.464 4 2,3.464 0 2,5 0 2)),((0 4 0,0 0 0,3.464 0 2,3.464 4 2,0 4 0)),((0 0 0,5 0 0,5 0 2,3.464 0 2,0 0 0)),((5 0 0,5 4 0,5 4 2,5 0 2,5 0 0)),((5 4 0,0 4 0,3.464 4 2,5 4 2,5 4 0)))</screen>
        </refsection>

        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="CG_GenerateFlatRoof"/>,
                <xref linkend="CG_GenerateHippedRoof"/>,
                <xref linkend="CG_GenerateGableRoof"/>,
                <xref linkend="CG_GenerateRoof"/>
            </para>
        </refsection>

    </refentry>

    <refentry xml:id="CG_GenerateRoof">
        <refnamediv>
            <refname>CG_GenerateRoof</refname>
            <refpurpose>Generate a roof of the requested type from a footprint polygon.</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_GenerateRoof</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                    <paramdef choice="opt"><type>text</type> <parameter>roof_type</parameter></paramdef>
                    <paramdef choice="opt"><type>float8</type> <parameter>height</parameter></paramdef>
                    <paramdef choice="opt"><type>float8</type> <parameter>slope_angle</parameter></paramdef>
                    <paramdef choice="opt"><type>integer</type> <parameter>primary_edge_index</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>
            <para>
                Generate a roof as a 3D <varname>PolyhedralSurface Z</varname> from
                a 2D footprint polygon. The <varname>roof_type</varname> parameter
                selects the roof style (default <literal>'HIPPED'</literal>):
            </para>
            <itemizedlist>
                <listitem><para><varname>FLAT</varname> — flat box roof.</para></listitem>
                <listitem><para><varname>HIPPED</varname> — hipped roof (all sides slope to apex).</para></listitem>
                <listitem><para><varname>GABLE</varname> — gable roof (two sloping sides, two vertical ends).</para></listitem>
                <listitem><para><varname>SKILLION</varname> — single-slope (shed) roof.</para></listitem>
            </itemizedlist>
            <para>
                <varname>height</varname> sets the roof height (default 3.0),
                <varname>slope_angle</varname> sets the pitch in degrees (default
                30.0), and <varname>primary_edge_index</varname> selects the
                reference edge for skillion roofs (default 0).
            </para>
            <para role="availability" conformance="3.7.0">Availability: 3.7.0 - requires SFCGAL &gt;= 2.3.0.</para>
            <para>&sfcgal_required;</para>
            <para>&P_support;</para>
        </refsection>

        <refsection>
            <title>Examples</title>
            <para>The generic dispatcher returns the same 3D roofs as the specialized helpers for the same footprint.</para>
            <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((0 0,4 0,4 4,0 4,0 0))'::geometry AS input_footprint
)
SELECT input_footprint AS input_footprint,
       CG_GenerateRoof(input_footprint, 'HIPPED', 2.0, 30.0, 0) AS hipped_roof,
       CG_GenerateRoof(input_footprint, 'FLAT', 2.0, 30.0, 0) AS flat_roof
FROM data;</programlisting>
            <screen role="visual-primary text-primary visual-separate-output docbook-qa-ignore-wide-lines">POLYGON((0 0,4 0,4 4,0 4,0 0)) | POLYHEDRALSURFACE Z (((0 4 0,4 4 0,4 0 0,0 0 0,0 4 0)),((0 4 0,0 0 0,2 2 2,0 4 0)),((0 0 0,4 0 0,2 2 2,0 0 0)),((4 0 0,4 4 0,2 2 2,4 0 0)),((4 4 0,0 4 0,2 2 2,4 4 0))) | POLYHEDRALSURFACE Z (((0 0 0,0 4 0,4 4 0,4 0 0,0 0 0)),((0 0 2,4 0 2,4 4 2,0 4 2,0 0 2)),((0 0 0,0 0 2,0 4 2,0 4 0,0 0 0)),((0 4 0,0 4 2,4 4 2,4 4 0,0 4 0)),((4 4 0,4 4 2,4 0 2,4 0 0,4 4 0)),((4 0 0,4 0 2,0 0 2,0 0 0,4 0 0)))</screen>
        </refsection>

        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="CG_GenerateFlatRoof"/>,
                <xref linkend="CG_GenerateHippedRoof"/>,
                <xref linkend="CG_GenerateGableRoof"/>,
                <xref linkend="CG_GenerateSkillionRoof"/>
            </para>
        </refsection>

    </refentry>

    <refentry xml:id="CG_PolygonRepair">
        <refnamediv>
            <refname>CG_PolygonRepair</refname>
            <refpurpose>Repair an invalid polygon or multipolygon.</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_PolygonRepair</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                    <paramdef choice="opt"><type>text</type> <parameter>rule</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>
            <para>
                Repair an invalid polygon or multipolygon using CGAL's 2D Polygon
                Repair algorithm. Returns a <varname>MultiPolygon</varname>.
            </para>
            <para>
                The <varname>rule</varname> parameter controls the repair strategy:
            </para>
            <itemizedlist>
                <listitem><para><varname>EVEN_ODD</varname> (default) — areas covered an odd
                    number of times are kept. Available with CGAL 6.0+.</para></listitem>
                <listitem><para><varname>NON_ZERO</varname> — areas with non-zero winding
                    number are kept. Requires CGAL 6.1+.</para></listitem>
                <listitem><para><varname>UNION</varname> — union of all input polygons.
                    Requires CGAL 6.1+.</para></listitem>
                <listitem><para><varname>INTERSECTION</varname> — intersection of all input
                    polygons. Requires CGAL 6.1+.</para></listitem>
            </itemizedlist>
            <para role="availability" conformance="3.7.0">Availability: 3.7.0 - requires SFCGAL &gt;= 2.3.0 and CGAL &gt;= 6.0.</para>
            <para>&sfcgal_required;</para>
            <para>&P_support;</para>
        </refsection>

        <refsection>
            <title>Examples</title>
            <para>Repair a self-intersecting bowtie polygon with the default <literal>EVEN_ODD</literal> rule.</para>
            <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((0 0,2 2,2 0,0 2,0 0))'::geometry AS input_polygon
)
SELECT input_polygon AS input_polygon,
       CG_PolygonRepair(input_polygon) AS repaired_polygon
FROM data;</programlisting>
            <screen role="visual-primary text-primary visual-overlay">POLYGON((0 0,2 2,2 0,0 2,0 0)) | MULTIPOLYGON(((0 0,1 1,0 2,0 0)),((1 1,2 0,2 2,1 1)))</screen>

            <para>With the <literal>UNION</literal> rule, all winding area is kept. This rule requires CGAL 6.1 or later.</para>
            <programlisting language="sql" role="requires-cgal-6.1">WITH data AS (
  SELECT 'POLYGON((0 0,2 2,2 0,0 2,0 0))'::geometry AS input_polygon
)
SELECT input_polygon AS input_polygon,
       CG_PolygonRepair(input_polygon, 'UNION') AS repaired_polygon
FROM data;</programlisting>
            <screen role="visual-primary text-primary visual-overlay">POLYGON((0 0,2 2,2 0,0 2,0 0)) | MULTIPOLYGON(((0 0,1 1,0 2,0 0)))</screen>
        </refsection>

        <refsection>
            <title>See Also</title>
            <para><xref linkend="ST_IsValid"/>, <xref linkend="ST_MakeValid"/></para>
        </refsection>

    </refentry>

<refentry xml:id="CG_ConstrainedDelaunayTriangles">
        <refnamediv>
            <refname>CG_ConstrainedDelaunayTriangles</refname>

            <refpurpose>
                Return a constrained Delaunay triangulation around the given input geometry.
            </refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_ConstrainedDelaunayTriangles</function></funcdef>
                    <paramdef><type>geometry </type> <parameter>g1</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>
                Return a <link xlink:href="https://en.wikipedia.org/wiki/Constrained_Delaunay_triangulation">Constrained Delaunay
                triangulation</link> around the vertices of the input geometry.
                Output is a TIN.
            </para>
            <para>&sfcgal_required;</para>
            <para role="availability" conformance="3.0.0">Availability: 3.0.0</para>
            <para>&Z_support;</para>
        </refsection>
        <refsection>
            <title>Examples</title>
            <para>Constrained Delaunay triangulation of the polygon and buffered point.</para>
            <programlisting language="sql">SELECT
  CG_ConstrainedDelaunayTriangles(
    ST_Union(
      'POLYGON((175 150,20 40,50 60,125 100,175 150))'::geometry,
      ST_Buffer('POINT(110 170)'::geometry, 20)
    )
  );</programlisting>
<screen role="visual-primary docbook-qa-ignore-wide-lines">TIN(((50 60,175 150,20 40,50 60)),((125 100,50 60,20 40,125 100)),((50 60,125 100,175 150,50 60)),((130 170,129.6 166.1,175 150,130 170)),((128.5 162.3,175 150,129.6 166.1,128.5 162.3)),((130 170,124.1 155.9,129.6 166.1,130 170)),((126.6 158.9,175 150,128.5 162.3,126.6 158.9)),((129.6 166.1,126.6 158.9,128.5 162.3,129.6 166.1)),((124.1 155.9,175 150,126.6 158.9,124.1 155.9)),((129.6 166.1,124.1 155.9,126.6 158.9,129.6 166.1)),((121.1 153.4,175 150,124.1 155.9,121.1 153.4)),((110 150,121.1 153.4,124.1 155.9,110 150)),((117.7 151.5,175 150,121.1 153.4,117.7 151.5)),((113.9 150.4,117.7 151.5,121.1 153.4,113.9 150.4)),((113.9 150.4,175 150,117.7 151.5,113.9 150.4)),((20 40,113.9 150.4,110 150,20 40)),((20 40,175 150,113.9 150.4,20 40)),((20 40,110 150,106.1 150.4,20 40)),((113.9 150.4,121.1 153.4,110 150,113.9 150.4)),((20 40,106.1 150.4,102.3 151.5,20 40)),((110 150,124.1 155.9,128.5 177.7,110 150)),((20 40,102.3 151.5,98.9 153.4,20 40)),((106.1 150.4,110 150,98.9 153.4,106.1 150.4)),((20 40,98.9 153.4,95.9 155.9,20 40)),((102.3 151.5,106.1 150.4,98.9 153.4,102.3 151.5)),((20 40,95.9 155.9,93.4 158.9,20 40)),((98.9 153.4,110 150,95.9 155.9,98.9 153.4)),((20 40,93.4 158.9,91.5 162.3,20 40)),((95.9 155.9,110 150,102.3 188.5,95.9 155.9)),((20 40,91.5 162.3,90.4 166.1,20 40)),((93.4 158.9,95.9 155.9,91.5 162.3,93.4 158.9)),((20 40,90.4 166.1,90 170,20 40)),((91.5 162.3,95.9 155.9,90 170,91.5 162.3)),((20 40,90 170,90.4 173.9,20 40)),((90.4 166.1,91.5 162.3,90 170,90.4 166.1)),((20 40,90.4 173.9,91.5 177.7,20 40)),((90 170,95.9 155.9,102.3 188.5,90 170)),((90.4 173.9,90 170,91.5 177.7,90.4 173.9)),((91.5 177.7,90 170,102.3 188.5,91.5 177.7)),((93.4 181.1,91.5 177.7,95.9 184.1,93.4 181.1)),((95.9 184.1,91.5 177.7,102.3 188.5,95.9 184.1)),((98.9 186.6,95.9 184.1,102.3 188.5,98.9 186.6)),((102.3 188.5,110 150,128.5 177.7,102.3 188.5)),((106.1 189.6,102.3 188.5,110 190,106.1 189.6)),((110 190,102.3 188.5,117.7 188.5,110 190)),((113.9 189.6,110 190,117.7 188.5,113.9 189.6)),((117.7 188.5,102.3 188.5,128.5 177.7,117.7 188.5)),((121.1 186.6,124.1 184.1,175 150,121.1 186.6)),((121.1 186.6,117.7 188.5,124.1 184.1,121.1 186.6)),((124.1 184.1,126.6 181.1,175 150,124.1 184.1)),((124.1 184.1,117.7 188.5,128.5 177.7,124.1 184.1)),((126.6 181.1,128.5 177.7,175 150,126.6 181.1)),((126.6 181.1,124.1 184.1,128.5 177.7,126.6 181.1)),((128.5 177.7,129.6 173.9,175 150,128.5 177.7)),((128.5 177.7,124.1 155.9,130 170,128.5 177.7)),((129.6 173.9,130 170,175 150,129.6 173.9)),((129.6 173.9,128.5 177.7,130 170,129.6 173.9)))</screen>

            <para><xref linkend="ST_DelaunayTriangles"/> applied to the same input.
                Triangle edges cross polygon boundaries.</para>
            <programlisting language="sql">SELECT
  ST_DelaunayTriangles(
    ST_Union(
      'POLYGON((175 150,20 40,50 60,125 100,175 150))'::geometry,
      ST_Buffer('POINT(110 170)'::geometry, 20)
    )
  );</programlisting>
<screen role="visual-primary docbook-qa-ignore-wide-lines">GEOMETRYCOLLECTION(POLYGON((95.9 184.1,93.4 181.1,95.9 155.9,95.9 184.1)), POLYGON((95.9 184.1,95.9 155.9,102.3 188.5,95.9 184.1)), POLYGON((95.9 184.1,102.3 188.5,98.9 186.6,95.9 184.1)), POLYGON((102.3 188.5,95.9 155.9,98.9 153.4,102.3 188.5)), POLYGON((102.3 188.5,98.9 153.4,102.3 151.5,102.3 188.5)), POLYGON((102.3 188.5,102.3 151.5,106.1 189.6,102.3 188.5)), POLYGON((106.1 189.6,102.3 151.5,106.1 150.4,106.1 189.6)), POLYGON((106.1 189.6,106.1 150.4,110 190,106.1 189.6)), POLYGON((110 190,106.1 150.4,110 150,110 190)), POLYGON((110 190,110 150,117.7 188.5,110 190)), POLYGON((110 190,117.7 188.5,113.9 189.6,110 190)), POLYGON((117.7 188.5,110 150,121.1 153.4,117.7 188.5)), POLYGON((117.7 188.5,121.1 153.4,121.1 186.6,117.7 188.5)), POLYGON((121.1 186.6,121.1 153.4,124.1 155.9,121.1 186.6)), POLYGON((121.1 186.6,124.1 155.9,124.1 184.1,121.1 186.6)), POLYGON((121.1 186.6,124.1 184.1,175 150,121.1 186.6)), POLYGON((175 150,124.1 184.1,126.6 181.1,175 150)), POLYGON((175 150,126.6 181.1,128.5 177.7,175 150)), POLYGON((175 150,128.5 177.7,129.6 173.9,175 150)), POLYGON((175 150,129.6 173.9,130 170,175 150)), POLYGON((175 150,130 170,129.6 166.1,175 150)), POLYGON((175 150,129.6 166.1,128.5 162.3,175 150)), POLYGON((175 150,128.5 162.3,126.6 158.9,175 150)), POLYGON((175 150,126.6 158.9,124.1 155.9,175 150)), POLYGON((175 150,124.1 155.9,125 100,175 150)), POLYGON((125 100,124.1 155.9,121.1 153.4,125 100)), POLYGON((125 100,121.1 153.4,117.7 151.5,125 100)), POLYGON((125 100,117.7 151.5,113.9 150.4,125 100)), POLYGON((125 100,113.9 150.4,110 150,125 100)), POLYGON((125 100,110 150,106.1 150.4,125 100)), POLYGON((125 100,106.1 150.4,102.3 151.5,125 100)), POLYGON((125 100,102.3 151.5,98.9 153.4,125 100)), POLYGON((125 100,98.9 153.4,50 60,125 100)), POLYGON((125 100,50 60,20 40,125 100)), POLYGON((20 40,50 60,90.4 166.1,20 40)), POLYGON((20 40,90.4 166.1,90 170,20 40)), POLYGON((20 40,90 170,90.4 173.9,20 40)), POLYGON((20 40,90.4 173.9,91.5 177.7,20 40)), POLYGON((91.5 177.7,90.4 173.9,90 170,91.5 177.7)), POLYGON((91.5 177.7,90 170,91.5 162.3,91.5 177.7)), POLYGON((91.5 177.7,91.5 162.3,93.4 158.9,91.5 177.7)), POLYGON((91.5 177.7,93.4 158.9,93.4 181.1,91.5 177.7)), POLYGON((93.4 181.1,93.4 158.9,95.9 155.9,93.4 181.1)), POLYGON((95.9 155.9,93.4 158.9,50 60,95.9 155.9)), POLYGON((95.9 155.9,50 60,98.9 153.4,95.9 155.9)), POLYGON((50 60,93.4 158.9,91.5 162.3,50 60)), POLYGON((50 60,91.5 162.3,90.4 166.1,50 60)), POLYGON((90.4 166.1,91.5 162.3,90 170,90.4 166.1)), POLYGON((110 150,113.9 150.4,121.1 153.4,110 150)), POLYGON((121.1 153.4,113.9 150.4,117.7 151.5,121.1 153.4)), POLYGON((124.1 155.9,126.6 158.9,129.6 166.1,124.1 155.9)), POLYGON((124.1 155.9,129.6 166.1,128.5 177.7,124.1 155.9)), POLYGON((124.1 155.9,128.5 177.7,124.1 184.1,124.1 155.9)), POLYGON((124.1 184.1,128.5 177.7,126.6 181.1,124.1 184.1)), POLYGON((128.5 177.7,129.6 166.1,130 170,128.5 177.7)), POLYGON((128.5 177.7,130 170,129.6 173.9,128.5 177.7)), POLYGON((129.6 166.1,126.6 158.9,128.5 162.3,129.6 166.1)))</screen>
        </refsection>
        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="ST_DelaunayTriangles"/>,
                <xref linkend="ST_TriangulatePolygon"/>,
                <xref linkend="CG_Tesselate"/>,
                <xref linkend="ST_ConcaveHull"/>,
                <xref linkend="ST_Dump"/>
            </para>
        </refsection>
    </refentry>

<refentry xml:id="CG_Extrude">
        <refnamediv>
            <refname>CG_Extrude</refname>

            <refpurpose>Extrude a surface to a related volume</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_Extrude</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                    <paramdef><type>float</type> <parameter>x</parameter></paramdef>
                    <paramdef><type>float</type> <parameter>y</parameter></paramdef>
                    <paramdef><type>float</type> <parameter>z</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>
                Extrudes the input along the vector
                (<parameter>x</parameter>, <parameter>y</parameter>,
                <parameter>z</parameter>) and connects it to its translated
                copy. Extrusion can raise the dimensionality of the result,
                for example from a surface to a volume.
            </para>
            <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
            <para>&sfcgal_required;</para>
            <para>&Z_support;</para>
            <para>&P_support;</para>
            <para>&T_support;</para>
        </refsection>

        <refsection><title>Examples</title>
            <para>The figures use <xref linkend="ST_Affine"/> to project Z diagonally into XY after extrusion. The returned geometry from <function>CG_Extrude</function> remains a 3D PolyhedralSurface.</para>

            <para>Extruding an octagonal Polygon 30 units along Z.</para>
            <programlisting language="sql">WITH data AS (
  SELECT ST_Buffer('POINT(100 90)'::geometry, 50, 'quad_segs=2') AS geom
), projected AS (
  SELECT ST_Force2D(ST_Affine(geom,
           1, 0, 0.5, 0, 1, 0.5, 0, 0, 0, 0, 0, 0)) AS input_geom,
         ST_Force2D(ST_Affine(CG_Extrude(geom, 0, 0, 30),
           1, 0, 0.5, 0, 1, 0.5, 0, 0, 0, 0, 0, 0)) AS output_geom
  FROM data
)
SELECT input_geom AS input_geometry,
       output_geom AS extruded_projection
FROM projected;</programlisting>
            <screen role="visual-primary">POLYGON((150 90,135.355 54.645,100 40,64.645 54.645,50 90,64.645 125.355,100 140,135.355 125.355,150 90)) | POLYHEDRALSURFACE(((150 90,135.355 54.645,100 40,64.645 54.645,50 90,64.645 125.355,100 140,135.355 125.355,150 90)),((165 105,150.355 140.355,115 155,79.645 140.355,65 105,79.645 69.645,115 55,150.355 69.645,165 105)),((150 90,165 105,150.355 69.645,135.355 54.645,150 90)),((135.355 54.645,150.355 69.645,115 55,100 40,135.355 54.645)),((100 40,115 55,79.645 69.645,64.645 54.645,100 40)),((64.645 54.645,79.645 69.645,65 105,50 90,64.645 54.645)),((50 90,65 105,79.645 140.355,64.645 125.355,50 90)),((64.645 125.355,79.645 140.355,115 155,100 140,64.645 125.355)),((100 140,115 155,150.355 140.355,135.355 125.355,100 140)),((135.355 125.355,150.355 140.355,165 105,150 90,135.355 125.355)))</screen>

            <para>Extruding a LineString 10 units along Z.</para>
            <programlisting language="sql">WITH data AS (
  SELECT 'LINESTRING(50 50,100 90,95 150)'::geometry AS geom
), projected AS (
  SELECT ST_Force2D(ST_Affine(geom,
           1, 0, 0.5, 0, 1, 0.5, 0, 0, 0, 0, 0, 0)) AS input_geom,
         ST_Force2D(ST_Affine(CG_Extrude(geom, 0, 0, 10),
           1, 0, 0.5, 0, 1, 0.5, 0, 0, 0, 0, 0, 0)) AS output_geom
  FROM data
)
SELECT input_geom AS input_geometry,
       output_geom AS extruded_projection
FROM projected;</programlisting>
            <screen role="visual-primary text-primary">LINESTRING(50 50,100 90,95 150) | POLYHEDRALSURFACE(((50 50,100 90,105 95,55 55,50 50)),((100 90,95 150,100 155,105 95,100 90)))</screen>
            </refsection>
            <refsection>
                <title>See Also</title>
                <para><xref linkend="ST_AsX3D"/>, <xref linkend="CG_ExtrudeStraightSkeleton" /></para>
            </refsection>
        </refentry>

        <refentry xml:id="CG_ExtrudeStraightSkeleton">
            <refnamediv>
                <refname>CG_ExtrudeStraightSkeleton</refname>

                <refpurpose>Straight Skeleton Extrusion</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>geometry <function>CG_ExtrudeStraightSkeleton</function></funcdef>
                        <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                        <paramdef><type>float </type> <parameter>roof_height</parameter></paramdef>
                        <paramdef choice="opt"><type>float </type> <parameter>body_height = 0</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Computes an extrusion with a maximal height of the polygon geometry.
            </para>

            <note><para>
                    Perhaps the first (historically) use-case of straight skeletons: given a polygonal roof, the straight skeleton directly gives the layout of each tent. If each skeleton edge is lifted from the plane a height equal to its offset distance, the resulting roof is "correct" in that water will always fall down to the contour edges (the roof's border), regardless of where it falls on the roof.
                    The function computes this extrusion aka "roof" on a polygon. If the argument body_height > 0, so the polygon is extruded like with CG_Extrude(polygon, 0, 0, body_height). The result is an union of these polyhedralsurfaces.
            </para></note>


            <para role="availability" conformance="3.5.0">Availability: 3.5.0 - requires SFCGAL &gt;= 1.5.0.</para>
            <para role="sfcgal_requirement" conformance="1.5.0">Requires SFCGAL &gt;= 1.5.0</para>
            <para>&sfcgal_required;</para>
        </refsection>

	        <refsection>
	            <title>Examples</title>
	            <para>Extrude a polygon with a hole into a body and straight-skeleton roof.</para>
	            <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON ((0 0,5 0,5 5,4 5,4 4,0 4,0 0),(1 1,1 2,2 2,2 1,1 1))'::geometry AS input_polygon
)
SELECT input_polygon AS input_polygon,
       CG_ExtrudeStraightSkeleton(input_polygon, 3.0, 2.0) AS straight_skeleton_extrusion
FROM data;</programlisting>
	            <screen role="visual-primary visual-separate-output">POLYGON((0 0,5 0,5 5,4 5,4 4,0 4,0 0),(1 1,1 2,2 2,2 1,1 1)) | POLYHEDRALSURFACE Z (((0 0 0,0 4 0,4 4 0,4 5 0,5 5 0,5 0 0,0 0 0),(1 1 0,2 1 0,2 2 0,1 2 0,1 1 0)),((0 0 0,0 0 2,0 4 2,0 4 0,0 0 0)),((0 4 0,0 4 2,4 4 2,4 4 0,0 4 0)),((4 4 0,4 4 2,4 5 2,4 5 0,4 4 0)),((4 5 0,4 5 2,5 5 2,5 5 0,4 5 0)),((5 5 0,5 5 2,5 0 2,5 0 0,5 5 0)),((5 0 0,5 0 2,0 0 2,0 0 0,5 0 0)),((1 1 0,1 1 2,2 1 2,2 1 0,1 1 0)),((2 1 0,2 1 2,2 2 2,2 2 0,2 1 0)),((2 2 0,2 2 2,1 2 2,1 2 0,2 2 0)),((1 2 0,1 2 2,1 1 2,1 1 0,1 2 0)),((0 4 2,0 0 2,0.5 0.5 2.5,0.5 2.5 2.5,1 3 3,0 4 2)),((0 0 2,5 0 2,3.5 1.5 3.5,2.5 0.5 2.5,0.5 0.5 2.5,0 0 2)),((5 0 2,5 5 2,4.5 4.5 2.5,4.5 3.5 2.5,3.5 2.5 3.5,3.5 1.5 3.5,5 0 2)),((5 5 2,4 5 2,4.5 4.5 2.5,5 5 2)),((4 5 2,4 4 2,4.5 3.5 2.5,4.5 4.5 2.5,4 5 2)),((4 4 2,0 4 2,1 3 3,3 3 3,3.5 2.5 3.5,4.5 3.5 2.5,4 4 2)),((2 1 2,1 1 2,0.5 0.5 2.5,2.5 0.5 2.5,2 1 2)),((1 1 2,1 2 2,0.5 2.5 2.5,0.5 0.5 2.5,1 1 2)),((1 2 2,2 2 2,3 3 3,1 3 3,0.5 2.5 2.5,1 2 2)),((2 2 2,2 1 2,2.5 0.5 2.5,3.5 1.5 3.5,3.5 2.5 3.5,3 3 3,2 2 2)))</screen>
	        </refsection>
        <refsection>
            <title>See Also</title>
            <para><xref linkend="CG_Extrude" />, <xref linkend="CG_ExtrudeStraightSkeleton" />, <xref linkend="CG_StraightSkeleton" />,  <xref linkend="CG_StraightSkeletonPartition" /> </para>
        </refsection>

    </refentry>

    <refentry xml:id="CG_GreeneApproxConvexPartition">
        <refnamediv>
            <refname>CG_GreeneApproxConvexPartition</refname>

            <refpurpose>Computes approximal convex partition of the polygon geometry</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_GreeneApproxConvexPartition</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>Computes approximal monotone convex partition of the polygon geometry.
        </para>

        <note><para>
                A partition of a polygon P is a set of polygons such that the interiors of the polygons do not intersect and the union of the polygons is equal to the interior of the original polygon P.
                CG_ApproxConvexPartition and CG_GreeneApproxConvexPartition functions produce approximately optimal convex partitions. Both these functions produce convex decompositions by first decomposing the polygon into simpler polygons; CG_ApproxConvexPartition uses a triangulation and CG_GreeneApproxConvexPartition a monotone partition. These two functions both guarantee that they will produce no more than four times the optimal number of convex pieces but they differ in their runtime complexities. Though the triangulation-based approximation algorithm often results in fewer convex pieces, this is not always the case.
        </para></note>


        <para role="availability" conformance="3.5.0">Availability: 3.5.0 - requires SFCGAL &gt;= 1.5.0.</para>
        <para role="sfcgal_requirement" conformance="1.5.0">Requires SFCGAL &gt;= 1.5.0</para>
        <para>&sfcgal_required;</para>
    </refsection>

	    <refsection>
	        <title>Examples</title>
	        <para>Greene's monotone-based approximation uses the same polygon and stays directly comparable in one panel.</para>
	        <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((156 150,83 181,89 131,148 120,107 61,32 159,0 45,41 86,45 1,177 2,67 24,109 31,170 60,180 110,156 150))'::geometry AS input_polygon
)
SELECT input_polygon AS input_polygon,
       CG_GreeneApproxConvexPartition(input_polygon) AS partition
FROM data;</programlisting>
	        <screen role="visual-primary text-primary visual-overlay docbook-qa-ignore-wide-lines">POLYGON((156 150,83 181,89 131,148 120,107 61,32 159,0 45,41 86,45 1,177 2,67 24,109 31,170 60,180 110,156 150)) | GEOMETRYCOLLECTION(POLYGON((32 159,0 45,41 86,32 159)), POLYGON((45 1,177 2,67 24,45 1)), POLYGON((67 24,109 31,170 60,107 61,67 24)), POLYGON((41 86,45 1,67 24,41 86)), POLYGON((107 61,32 159,41 86,67 24,107 61)), POLYGON((148 120,107 61,170 60,148 120)), POLYGON((148 120,170 60,180 110,156 150,148 120)), POLYGON((156 150,83 181,89 131,148 120,156 150)))</screen>
	    </refsection>
    <refsection>
        <title>See Also</title>
        <para><xref linkend="CG_YMonotonePartition" />, <xref linkend="CG_ApproxConvexPartition" />, <xref linkend="CG_OptimalConvexPartition" /></para>
    </refsection>

</refentry>

<refentry xml:id="CG_MinkowskiSum">
    <refnamediv>
        <refname>CG_MinkowskiSum</refname>

        <refpurpose>Performs Minkowski sum</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
        <funcsynopsis>
            <funcprototype>
                <funcdef>geometry <function>CG_MinkowskiSum</function></funcdef>
                <paramdef><type>geometry</type> <parameter>geom1</parameter></paramdef>
                <paramdef><type>geometry</type> <parameter>geom2</parameter></paramdef>
            </funcprototype>
        </funcsynopsis>
    </refsynopsisdiv>

    <refsection>
        <title>Description</title>

        <para>This function performs a 2D minkowski sum of a point, line or polygon with a polygon.</para>
        <para>A minkowski sum of two geometries A and B is the set of all points that are the sum of any point in A and B. Minkowski sums are often used in motion planning and computer-aided design. More details on <link xlink:href="https://en.wikipedia.org/wiki/Minkowski_addition">Wikipedia Minkowski addition</link>.</para>
        <para>The first parameter can be any 2D geometry (point, linestring, polygon). If a 3D geometry is passed, it will be converted to 2D by forcing Z to 0, leading to possible cases of invalidity. The second parameter must be a 2D polygon.</para>

        <para>Implementation utilizes <link xlink:href="http://doc.cgal.org/latest/Minkowski_sum_2/">CGAL 2D Minkowskisum</link>.</para>


        <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
        <para>&sfcgal_required;</para>
    </refsection>

    <refsection><title>Examples</title>
        <para>Minkowski sum of a LineString and a circular polygon. The line crosses the polygon, and the result sweeps the polygon along the line.</para>
        <programlisting language="sql">WITH data AS (
  SELECT ST_MakeLine(ST_Point(10, 10), ST_Point(100, 100)) AS line,
         ST_Buffer('POINT(50 50)'::geometry, 30) AS circle
)
SELECT line AS input_line,
       circle AS input_circle,
       CG_MinkowskiSum(line, circle) AS minkowski_sum
FROM data;</programlisting>
        <screen role="visual-primary docbook-qa-ignore-wide-lines">LINESTRING(10 10,100 100) | POLYGON((80 50,79.424 44.147,77.716 38.519,74.944 33.333,71.213 28.787,66.667 25.056,61.481 22.284,55.853 20.576,50 20,44.147 20.576,38.519 22.284,33.333 25.056,28.787 28.787,25.056 33.333,22.284 38.519,20.576 44.147,20 50,20.576 55.853,22.284 61.481,25.056 66.667,28.787 71.213,33.333 74.944,38.519 77.716,44.147 79.424,50 80,55.853 79.424,61.481 77.716,66.667 74.944,71.213 71.213,74.944 66.667,77.716 61.481,79.424 55.853,80 50)) | MULTIPOLYGON(((179.424 155.853,177.716 161.481,174.944 166.667,171.213 171.213,166.667 174.944,161.481 177.716,155.853 179.424,150 180,144.147 179.424,138.519 177.716,133.333 174.944,128.787 171.213,38.787 81.213,35.056 76.667,32.284 71.481,30.576 65.853,30 60,30.576 54.147,32.284 48.519,35.056 43.333,38.787 38.787,43.333 35.056,48.519 32.284,54.147 30.576,60 30,65.853 30.576,71.481 32.284,76.667 35.056,81.213 38.787,171.213 128.787,174.944 133.333,177.716 138.519,179.424 144.147,180 150,179.424 155.853)))</screen>

        <para>Minkowski sum of a MultiPoint and a polygon. The result contains one translated copy of the polygon for each point.</para>
        <programlisting language="sql">WITH data AS (
  SELECT 'MULTIPOINT(25 50,70 25)'::geometry AS points,
         'POLYGON((130 150,20 40,50 60,125 100,130 150))'::geometry AS polygon
)
SELECT points AS input_points,
       polygon AS input_polygon,
       CG_MinkowskiSum(points, polygon) AS minkowski_sum
FROM data;</programlisting>
        <screen role="visual-primary text-primary docbook-qa-ignore-wide-lines">MULTIPOINT((25 50),(70 25)) | POLYGON((130 150,20 40,50 60,125 100,130 150)) | MULTIPOLYGON(((45 90,75 110,150 150,155 200,45 90)),((90 65,120 85,195 125,200 175,90 65)))</screen>
    </refsection>

        </refentry>

<refentry xml:id="CG_OptimalAlphaShape">
        <refnamediv>
            <refname>CG_OptimalAlphaShape</refname>

            <refpurpose>Computes an Alpha-shape enclosing a geometry using an "optimal" alpha value.</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_OptimalAlphaShape</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>allow_holes = false</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>nb_components = 1</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>Computes the "optimal" alpha-shape of the points in a geometry.
            The alpha-shape is computed using a value of α chosen so that:
        </para>
        <orderedlist>
            <listitem>
                <para>the number of polygon elements is equal to or smaller than <varname>nb_components</varname>
                    (which defaults to 1)</para>
            </listitem>
            <listitem>
                <para>all input points are contained in the shape</para>
            </listitem>
        </orderedlist>
        <para>
            The result will not contain holes unless the optional <varname>allow_holes</varname> argument is specified as true.
        </para>

        <para role="availability" conformance="3.5.0">Availability: 3.5.0 - requires SFCGAL &gt;= 1.4.1.</para>
        <para>&sfcgal_required;</para>
    </refsection>

    <refsection>
        <title>Examples</title>
        <para>The original point cloud and the optimal alpha-shape share one comparison frame.</para>
        <programlisting language="sql">WITH data AS (
  SELECT 'MULTIPOINT((63 84),(76 88),(68 73),(53 18),(91 50),(81 70),
(88 29),(24 82),(32 51),(37 23),(27 54),(84 19),(75 87),(44 42),(77 67),(90 30),(36 61),(32 65),
(81 47),(88 58),(68 73),(49 95),(81 60),(87 50),
(78 16),(79 21),(30 22),(78 43),(26 85),(48 34),(35 35),(36 40),(31 79),(83 29),(27 84),(52 98),(72 95),(85 71),
(75 84),(75 77),(81 29),(77 73),(41 42),(83 72),(23 36),(89 53),(27 57),(57 97),(27 77),(39 88),(60 81),
(80 72),(54 32),(55 26),(62 22),(70 20),(76 27),(84 35),(87 42),(82 54),(83 64),(69 86),(60 90),(50 86),(43 80),(36 73),
(36 68),(40 75),(24 67),(23 60),(26 44),(28 33),(40 32),(43 19),(65 16),(73 16),(38 46),(31 59),(34 86),(45 90),(64 97))'::geometry AS input_points
)
SELECT input_points AS input_points,

         CG_OptimalAlphaShape(input_points) AS optimal_alpha_shape
FROM data;</programlisting>
        <screen role="visual-primary visual-overlay docbook-qa-ignore-wide-lines">MULTIPOINT((63 84),(76 88),(68 73),(53 18),(91 50),(81 70),(88 29),(24 82),(32 51),(37 23),(27 54),(84 19),(75 87),(44 42),(77 67),(90 30),(36 61),(32 65),(81 47),(88 58),(68 73),(49 95),(81 60),(87 50),(78 16),(79 21),(30 22),(78 43),(26 85),(48 34),(35 35),(36 40),(31 79),(83 29),(27 84),(52 98),(72 95),(85 71),(75 84),(75 77),(81 29),(77 73),(41 42),(83 72),(23 36),(89 53),(27 57),(57 97),(27 77),(39 88),(60 81),(80 72),(54 32),(55 26),(62 22),(70 20),(76 27),(84 35),(87 42),(82 54),(83 64),(69 86),(60 90),(50 86),(43 80),(36 73),(36 68),(40 75),(24 67),(23 60),(26 44),(28 33),(40 32),(43 19),(65 16),(73 16),(38 46),(31 59),(34 86),(45 90),(64 97)) | MULTIPOLYGON(((89 53,88 58,83 64,85 71,83 72,75 77,75 84,76 88,72 95,64 97,57 97,52 98,49 95,45 90,39 88,34 86,26 85,24 82,27 77,24 67,23 60,27 54,26 44,23 36,28 33,30 22,37 23,43 19,53 18,65 16,73 16,78 16,84 19,88 29,90 30,87 42,91 50,89 53)))</screen>

            <para>Allowing holes keeps the same outer shell but carves a central hole.</para>
            <programlisting language="sql">WITH data AS (
  SELECT 'MULTIPOINT((63 84),(76 88),(68 73),(53 18),(91 50),(81 70),(88 29),(24 82),(32 51),(37 23),(27 54),(84 19),(75 87),(44 42),(77 67),(90 30),(36 61),(32 65),(81 47),(88 58),(68 73),(49 95),(81 60),(87 50),
(78 16),(79 21),(30 22),(78 43),(26 85),(48 34),(35 35),(36 40),(31 79),(83 29),(27 84),(52 98),(72 95),(85 71),
(75 84),(75 77),(81 29),(77 73),(41 42),(83 72),(23 36),(89 53),(27 57),(57 97),(27 77),(39 88),(60 81),
(80 72),(54 32),(55 26),(62 22),(70 20),(76 27),(84 35),(87 42),(82 54),(83 64),(69 86),(60 90),(50 86),(43 80),(36 73),
(36 68),(40 75),(24 67),(23 60),(26 44),(28 33),(40 32),(43 19),(65 16),(73 16),(38 46),(31 59),(34 86),(45 90),(64 97))'::geometry AS input_points
)
SELECT input_points AS input_points,

         CG_OptimalAlphaShape(input_points, allow_holes =&gt; true) AS optimal_alpha_shape
FROM data;</programlisting>
        <screen role="visual-primary visual-overlay docbook-qa-ignore-wide-lines">MULTIPOINT((63 84),(76 88),(68 73),(53 18),(91 50),(81 70),(88 29),(24 82),(32 51),(37 23),(27 54),(84 19),(75 87),(44 42),(77 67),(90 30),(36 61),(32 65),(81 47),(88 58),(68 73),(49 95),(81 60),(87 50),(78 16),(79 21),(30 22),(78 43),(26 85),(48 34),(35 35),(36 40),(31 79),(83 29),(27 84),(52 98),(72 95),(85 71),(75 84),(75 77),(81 29),(77 73),(41 42),(83 72),(23 36),(89 53),(27 57),(57 97),(27 77),(39 88),(60 81),(80 72),(54 32),(55 26),(62 22),(70 20),(76 27),(84 35),(87 42),(82 54),(83 64),(69 86),(60 90),(50 86),(43 80),(36 73),(36 68),(40 75),(24 67),(23 60),(26 44),(28 33),(40 32),(43 19),(65 16),(73 16),(38 46),(31 59),(34 86),(45 90),(64 97)) | MULTIPOLYGON(((89 53,88 58,83 64,85 71,83 72,75 77,75 84,76 88,72 95,64 97,57 97,52 98,49 95,45 90,39 88,34 86,26 85,24 82,27 77,24 67,23 60,27 54,26 44,23 36,28 33,30 22,37 23,43 19,53 18,65 16,73 16,78 16,84 19,88 29,90 30,87 42,91 50,89 53),(36 68,40 75,43 80,50 86,60 81,68 73,77 67,81 60,82 54,81 47,78 43,81 29,76 27,70 20,62 22,55 26,54 32,48 34,44 42,38 46,36 61,36 68)))</screen>

    </refsection>
            <refsection>
                <title>See Also</title>
                <para><xref linkend="ST_ConcaveHull"/>, <xref linkend="CG_AlphaShape"/></para>
            </refsection>

        </refentry>

        <refentry xml:id="CG_OptimalConvexPartition">
            <refnamediv>
                <refname>CG_OptimalConvexPartition</refname>

                <refpurpose>Computes an optimal convex partition of the polygon geometry</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>geometry <function>CG_OptimalConvexPartition</function></funcdef>
                        <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Computes an optimal convex partition of the polygon geometry.
            </para>

            <note><para>
                    A partition of a polygon P is a set of polygons such that the interiors of the polygons do not intersect and the union of the polygons is equal to the interior of the original polygon P.
                    CG_OptimalConvexPartition produces a partition that is optimal in the number of pieces.
            </para></note>


            <para role="availability" conformance="3.5.0">Availability: 3.5.0 - requires SFCGAL &gt;= 1.5.0.</para>
            <para role="sfcgal_requirement" conformance="1.5.0">Requires SFCGAL &gt;= 1.5.0</para>
            <para>&sfcgal_required;</para>
        </refsection>

        <refsection>
            <title>Examples</title>
            <para>The optimal convex partition uses the same polygon and produces the smallest documented piece count.</para>
            <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((156 150,83 181,89 131,148 120,107 61,32 159,0 45,41 86,45 1,177 2,67 24,109 31,170 60,180 110,156 150))'::geometry AS input_polygon
)
SELECT input_polygon AS input_polygon,
       CG_OptimalConvexPartition(input_polygon) AS partition
FROM data;</programlisting>
            <screen role="visual-primary text-primary visual-overlay docbook-qa-ignore-wide-lines">POLYGON((156 150,83 181,89 131,148 120,107 61,32 159,0 45,41 86,45 1,177 2,67 24,109 31,170 60,180 110,156 150)) | GEOMETRYCOLLECTION(POLYGON((156 150,83 181,89 131,148 120,156 150)), POLYGON((32 159,0 45,41 86,32 159)), POLYGON((45 1,177 2,67 24,45 1)), POLYGON((41 86,45 1,67 24,41 86)), POLYGON((107 61,32 159,41 86,67 24,109 31,107 61)), POLYGON((148 120,107 61,109 31,170 60,180 110,148 120)), POLYGON((156 150,148 120,180 110,156 150)))</screen>
        </refsection>
        <refsection>
            <title>See Also</title>
            <para><xref linkend="CG_YMonotonePartition" />, <xref linkend="CG_ApproxConvexPartition" />, <xref linkend="CG_GreeneApproxConvexPartition" /></para>
        </refsection>
    </refentry>

    <refentry xml:id="CG_StraightSkeleton">
        <refnamediv>
            <refname>CG_StraightSkeleton</refname>

            <refpurpose>Compute a straight skeleton from a geometry</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_StraightSkeleton</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>use_distance_as_m = false</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>
                Computes the straight skeleton of a polygon by tracing the
                inward propagation of its edges. When
                <parameter>use_distance_as_m</parameter> is
                <varname>true</varname>, the M coordinate of each output point
                stores its distance from the input boundary.
            </para>
            <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
            <para role="sfcgal_requirement" conformance="1.3.8">Requires SFCGAL &gt;= 1.3.8 for option use_distance_as_m</para>
            <para>&sfcgal_required;</para>
            <para>&Z_support;</para>
            <para>&P_support;</para>
            <para>&T_support;</para>
        </refsection>

	        <refsection><title>Examples</title>

            <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((190 190,10 190,10 10,190 10,190 20,160 30,60 30,60 130,190 140,190 190))'::geometry AS polygon
)
SELECT CG_StraightSkeleton(polygon) AS straight_skeleton
FROM data;</programlisting>
<screen role="visual-primary docbook-qa-ignore-wide-lines">MULTILINESTRING((190 190,164.03987973986756 164.03987973986756),(10 190,40.697077206292434 159.30292279370755),(10 10,35 35),(190 10,184.18861169915812 15.811388300841896),(190 20,184.18861169915812 15.811388300841896),(160 30,158.3772233983162 20),(60 30,50 20),(60 130,35 153.15077848154866),(190 140,164.03987973986756 164.03987973986756),(184.18861169915812 15.811388300841896,158.3772233983162 20),(50 20,158.3772233983162 20),(50 20,35 35),(35 153.15077848154866,35 35),(35 153.15077848154866,40.697077206292434 159.30292279370755),(164.03987973986756 164.03987973986756,40.697077206292434 159.30292279370755))</screen>

            <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((0 0,1 0,1 1,0 1,0 0))'::geometry AS polygon
)
SELECT CG_StraightSkeleton(polygon, true) AS straight_skeleton_with_m
FROM data;</programlisting>
<screen role="visual-primary text-primary">MULTILINESTRING M ((0 0 0,0.5 0.5 0.5),(1 0 0,0.5 0.5 0.5),(1 1 0,0.5 0.5 0.5),(0 1 0,0.5 0.5 0.5))</screen>

            <para>Note that valid inputs with rings that touch at a single point will raise an error.</para>
                <programlisting language="sql">SELECT CG_StraightSkeleton('POLYGON((0 0,3 0,3 3,0 3,0 0),(0 0,1 2,2 1,0 0))'));</programlisting>
<screen role="text-primary">NOTICE:  During straight_skeleton(A) :
NOTICE:    with A: POLYGON((0/1 0/1,3/1 0/1,3/1 3/1,0/1 3/1,0/1 0/1),(0/1 0/1,1/1 2/1,2/1 1/1,0/1 0/1))
ERROR:  straight skeleton of Polygon with point touching rings is not implemented.</screen>

        </refsection>

        <refsection>
            <title>See Also</title>
            <para><xref linkend="CG_StraightSkeletonPartition" />, <xref linkend="CG_ExtrudeStraightSkeleton" /></para>
        </refsection>
    </refentry>

<refentry xml:id="CG_Tesselate">
        <refnamediv>
            <refname>CG_Tesselate</refname>

            <refpurpose>Perform surface Tessellation of a polygon or polyhedralsurface and returns as a TIN or collection of TINS</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_Tesselate</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>Takes as input a surface such a  MULTI(POLYGON) or POLYHEDRALSURFACE and returns a TIN representation via the process of tessellation using triangles.</para>
            <note><para><xref linkend="ST_TriangulatePolygon" /> does similar to this function except that it returns a geometry collection of polygons instead of a TIN and also only works with 2D geometries.</para></note>
            <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
            <para>&sfcgal_required;</para>
            <para>&Z_support;</para>
            <para>&P_support;</para>
            <para>&T_support;</para>
        </refsection>

        <refsection>
            <title>Examples</title>
            <para>Tessellation divides each face of a cube into triangles.</para>
            <programlisting language="sql">WITH data AS (
  SELECT 'POLYHEDRALSURFACE Z( ((0 0 0,0 0 1,0 1 1,0 1 0,0 0 0)),
((0 0 0,0 1 0,1 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,1 0 1,0 0 1,0 0 0)),
((1 1 0,1 1 1,1 0 1,1 0 0,1 1 0)),
((0 1 0,0 1 1,1 1 1,1 1 0,0 1 0)),((0 0 1,1 0 1,1 1 1,0 1 1,0 0 1)) )'::geometry AS cube
)
SELECT CG_Tesselate(cube) AS tessellation
FROM data;</programlisting>
<screen role="visual-primary text-primary">TIN Z (((0 0 0,0 0 1,0 1 1,0 0 0)),((0 1 0,0 0 0,0 1 1,0 1 0)),((0 0 0,0 1 0,1 1 0,0 0 0)),((1 0 0,0 0 0,1 1 0,1 0 0)),((0 0 1,1 0 0,1 0 1,0 0 1)),((0 0 1,0 0 0,1 0 0,0 0 1)),((1 1 0,1 1 1,1 0 1,1 1 0)),((1 0 0,1 1 0,1 0 1,1 0 0)),((0 1 0,0 1 1,1 1 1,0 1 0)),((1 1 0,0 1 0,1 1 1,1 1 0)),((0 1 1,1 0 1,1 1 1,0 1 1)),((0 1 1,0 0 1,1 0 1,0 1 1)))</screen>

                <para>Tessellation of a Polygon.</para>
                <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((10 190,10 70,80 70,80 130,50 160,120 160,120 190,10 190))'::geometry AS polygon
)
SELECT polygon AS input_polygon,
       CG_Tesselate(polygon) AS tessellation
FROM data;</programlisting>
                <screen role="visual-primary text-primary">POLYGON((10 190,10 70,80 70,80 130,50 160,120 160,120 190,10 190)) | TIN(((80 130,10 70,80 70,80 130)),((50 160,10 190,10 70,50 160)),((80 130,50 160,10 70,80 130)),((120 160,120 190,50 160,120 160)),((120 190,10 190,50 160,120 190)))</screen>
            </refsection>

            <refsection>
                <title>See Also</title>

                <para><xref linkend="CG_ConstrainedDelaunayTriangles"/>, <xref linkend="ST_DelaunayTriangles"/>, <xref linkend="ST_TriangulatePolygon"/></para>
            </refsection>


        </refentry>

        <refentry xml:id="CG_Triangulate">
            <refnamediv>
                <refname>CG_Triangulate</refname>
                <refpurpose>Triangulates a polygonal geometry</refpurpose>
            </refnamediv>
            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>geometry <function>CG_Triangulate</function></funcdef>
                        <paramdef>
                            <type>geometry</type>
                            <parameter>geom</parameter>
                        </paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>
            <refsection>
                <title>Description</title>
                <para>Triangulates a polygonal geometry.</para>
                <para>Performed by the SFCGAL module</para>
                <note>
                    <para>NOTE: this function returns a geometry representing the triangulated result.</para>
                </note>
                <para role="availability" conformance="3.5.0">Availability: 3.5.0</para>
                <para>&sfcgal_required;</para>
            </refsection>
            <refsection>
                <title>Geometry Examples</title>
                <programlisting language="sql">SELECT CG_Triangulate(
  'POLYGON((0 0,1 0,1 1,0 1,0 0),
            (0.2 0.2,0.2 0.8,0.8 0.8,0.8 0.2,0.2 0.2))'
);</programlisting>
<screen role="visual-primary text-primary">TIN(((0.8 0.2,0.2 0.2,1 0,0.8 0.2)),((0.2 0.2,0 0,1 0,0.2 0.2)),((1 1,0.8 0.8,0.8 0.2,1 1)),((0 1,0 0,0.2 0.2,0 1)),((0 1,0.2 0.8,1 1,0 1)),((0 1,0.2 0.2,0.2 0.8,0 1)),((0.2 0.8,0.8 0.8,1 1,0.2 0.8)),((0.2 0.8,0.2 0.2,0.8 0.2,0.2 0.8)),((1 1,0.8 0.2,1 0,1 1)),((0.8 0.8,0.2 0.8,0.8 0.2,0.8 0.8)))</screen>
        </refsection>
        <refsection>
            <title>See Also</title>
            <para><xref linkend="CG_ConstrainedDelaunayTriangles"/>, <xref linkend="ST_DelaunayTriangles"/>, <xref linkend="ST_TriangulatePolygon"/></para>
        </refsection>
    </refentry>

    <refentry xml:id="CG_Visibility">
        <refnamediv>
            <refname>CG_Visibility</refname>

            <refpurpose>Compute a visibility polygon from a point or a segment in a polygon geometry</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_Visibility</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>polygon</parameter></paramdef>
                    <paramdef><type>geometry</type> <parameter>point</parameter></paramdef>
                </funcprototype>
                <funcprototype>
                    <funcdef>geometry <function>CG_Visibility</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>polygon</parameter></paramdef>
                    <paramdef><type>geometry</type> <parameter>pointA</parameter></paramdef>
                    <paramdef><type>geometry</type> <parameter>pointB</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>
                Returns the portion of a polygon visible from an observer
                point, or from the observer segment defined by
                <parameter>pointA</parameter> and <parameter>pointB</parameter>.
            </para>
            <para role="availability" conformance="3.5.0">Availability: 3.5.0 - requires SFCGAL &gt;= 1.5.0.</para>
            <para role="sfcgal_requirement" conformance="1.5.0">Requires SFCGAL &gt;= 1.5.0</para>
            <para>&sfcgal_required;</para>
            <para>&Z_support;</para>
            <para>&P_support;</para>
            <para>&T_support;</para>
        </refsection>

        <refsection>
            <title>Examples</title>
            <para>Visibility from a point inside a polygon with holes.</para>
            <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((23.5 23.5,23.5 173.5,173.5 173.5,173.5 23.5,23.5 23.5),(108 98,108 36,156 37,155 99,108 98),(107 157.5,107 106.5,135 107.5,133 127.5,143.5 127.5,143.5 108.5,153.5 109.5,151.5 166,107 157.5),(41 95.5,41 35,100.5 36,98.5 68,78.5 68,77.5 96.5,41 95.5),(39 150,40 104,97.5 106.5,95.5 152,39 150))'::geometry AS polygon,
         'POINT(91 87)'::geometry AS observer
)
SELECT ST_Collect(polygon, observer) AS input_scene,
       CG_Visibility(polygon, observer) AS visibility
FROM data;</programlisting>
            <screen role="visual-primary visual-separate-output docbook-qa-ignore-wide-lines">GEOMETRYCOLLECTION(POLYGON((23.5 23.5,23.5 173.5,173.5 173.5,173.5 23.5,23.5 23.5),(108 98,108 36,156 37,155 99,108 98),(107 157.5,107 106.5,135 107.5,133 127.5,143.5 127.5,143.5 108.5,153.5 109.5,151.5 166,107 157.5),(41 95.5,41 35,100.5 36,98.5 68,78.5 68,77.5 96.5,41 95.5),(39 150,40 104,97.5 106.5,95.5 152,39 150)), POINT(91 87)) | POLYGON((78.5 68,98.5 68,108 43.93333333333334,108 98,121.96219931271477 107.03436426116838,107 106.5,107 135,97.5 106.5,65.28017241379311 105.09913793103448,77.5 96.5,78.5 68))</screen>

            <para>Visibility from a segment inside the same polygon.</para>
            <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((23.5 23.5,23.5 173.5,173.5 173.5,173.5 23.5,23.5 23.5),(108 98,108 36,156 37,155 99,108 98),(107 157.5,107 106.5,135 107.5,133 127.5,143.5 127.5,143.5 108.5,153.5 109.5,151.5 166,107 157.5),(41 95.5,41 35,100.5 36,98.5 68,78.5 68,77.5 96.5,41 95.5),(39 150,40 104,97.5 106.5,95.5 152,39 150))'::geometry AS polygon,
         'LINESTRING(78.5 68,98.5 68)'::geometry AS observer
)
SELECT ST_Collect(polygon, observer) AS input_scene,
       CG_Visibility(polygon,
                     ST_StartPoint(observer),
                     ST_EndPoint(observer)) AS visibility
FROM data;</programlisting>
            <screen role="visual-primary visual-separate-output docbook-qa-ignore-wide-lines">GEOMETRYCOLLECTION(POLYGON((23.5 23.5,23.5 173.5,173.5 173.5,173.5 23.5,23.5 23.5),(108 98,108 36,156 37,155 99,108 98),(107 157.5,107 106.5,135 107.5,133 127.5,143.5 127.5,143.5 108.5,153.5 109.5,151.5 166,107 157.5),(41 95.5,41 35,100.5 36,98.5 68,78.5 68,77.5 96.5,41 95.5),(39 150,40 104,97.5 106.5,95.5 152,39 150)), LINESTRING(78.5 68,98.5 68)) | POLYGON((78.5 68,98.5 68,100.5 36,101.28125 23.5,111.7109375 23.5,108 36,108 98,110.73389524382901 106.63335340156533,107 106.5,107 157.5,108.51955307262571 173.5,95.75974025974025 173.5,97.5 106.5,70.9811529933481 105.3470066518847,77.5 96.5,78.5 68))</screen>
        </refsection>

    </refentry>

    <refentry xml:id="CG_YMonotonePartition">
        <refnamediv>
            <refname>CG_YMonotonePartition</refname>

            <refpurpose>Computes y-monotone partition of the polygon geometry</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>geometry <function>CG_YMonotonePartition</function></funcdef>
                    <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>Computes y-monotone partition of the polygon geometry.
        </para>

        <note><para>
                A partition of a polygon P is a set of polygons such that the interiors of the polygons do not intersect and the union of the polygons is equal to the interior of the original polygon P.
                A y-monotone polygon is a polygon whose vertices v1,…,vn can be divided into two chains v1,…,vk and vk,…,vn,v1, such that any horizontal line intersects either chain at most once. This algorithm does not guarantee a bound on the number of polygons produced with respect to the optimal number.
        </para></note>


        <para role="availability" conformance="3.5.0">Availability: 3.5.0 - requires SFCGAL &gt;= 1.5.0.</para>
        <para role="sfcgal_requirement" conformance="1.5.0">Requires SFCGAL &gt;= 1.5.0</para>
        <para>&sfcgal_required;</para>
    </refsection>

    <refsection>
        <title>Examples</title>
        <para>The same polygon can also be partitioned into y-monotone pieces for downstream processing.</para>
        <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((156 150,83 181,89 131,148 120,107 61,32 159,0 45,41 86,45 1,177 2,67 24,109 31,170 60,180 110,156 150))'::geometry AS input_polygon
)
SELECT input_polygon AS input_polygon,
       CG_YMonotonePartition(input_polygon) AS partition
FROM data;</programlisting>
        <screen role="visual-primary text-primary visual-overlay docbook-qa-ignore-wide-lines">POLYGON((156 150,83 181,89 131,148 120,107 61,32 159,0 45,41 86,45 1,177 2,67 24,109 31,170 60,180 110,156 150)) | GEOMETRYCOLLECTION(POLYGON((32 159,0 45,41 86,32 159)), POLYGON((107 61,32 159,41 86,45 1,177 2,67 24,109 31,170 60,107 61)), POLYGON((156 150,83 181,89 131,148 120,107 61,170 60,180 110,156 150)))</screen>
    </refsection>
    <refsection>
        <title>See Also</title>
        <para><xref linkend="CG_ApproxConvexPartition" />, <xref linkend="CG_GreeneApproxConvexPartition" />, <xref linkend="CG_OptimalConvexPartition" /></para>
    </refsection>

</refentry>

<refentry xml:id="CG_StraightSkeletonPartition">
    <refnamediv>
        <refname>CG_StraightSkeletonPartition</refname>
        <refpurpose>Computes the straight skeleton partition of a polygon.</refpurpose>
    </refnamediv>
    <refsynopsisdiv>
        <funcsynopsis>
            <funcprototype>
                <funcdef>geometry <function>CG_StraightSkeletonPartition</function></funcdef>
                <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
                <paramdef><type>boolean</type> <parameter>auto_orientation</parameter></paramdef>
            </funcprototype>
        </funcsynopsis>
    </refsynopsisdiv>
    <refsection>
        <title>Description</title>
        <para>Computes the straight skeleton partition of the input polygon geometry <parameter>geom</parameter>.
        The straight skeleton is a partitioning of the polygon into faces formed by tracing the collapse of its edges.
        If <parameter>auto_orientation</parameter> is set to true, the function will automatically adjust the orientation of the input polygon to ensure correct results.</para>
        <para role="availability" conformance="3.6.0">Availability: 3.6.0 - requires SFCGAL &gt;= 2.0.0.</para>
        <para>&sfcgal_required;</para>
    </refsection>
    <refsection>
        <title>Examples</title>
        <programlisting language="sql">SELECT CG_StraightSkeletonPartition('POLYGON((0 0,4 0,2 2,0 0))', true);</programlisting>
<screen role="visual-primary text-primary">POLYHEDRALSURFACE(((0 0,2 0.82842712474619,2 2,0 0)),((4 0,2 0.82842712474619,0 0,4 0)),((2 2,2 0.82842712474619,4 0,2 2)))</screen>

        <para>Straight skeleton partition of a polygon.</para>
        <programlisting language="sql">WITH data AS (
  SELECT 'POLYGON((190 190,10 190,10 10,190 10,190 20,160 30,60 30,60 130,190 140,190 190))'::geometry AS polygon
)
SELECT polygon AS input_polygon,
       CG_StraightSkeletonPartition(polygon, true) AS skeleton_partition
FROM data;</programlisting>
        <screen role="visual-primary">POLYGON((190 190,10 190,10 10,190 10,190 20,160 30,60 30,60 130,190 140,190 190)) | POLYHEDRALSURFACE(((190 190,164.04 164.04,190 140,190 190)),((10 190,40.697 159.303,164.04 164.04,190 190,10 190)),((10 10,35 35,35 153.151,40.697 159.303,10 190,10 10)),((190 10,184.189 15.811,158.377 20,50 20,35 35,10 10,190 10)),((190 20,184.189 15.811,190 10,190 20)),((160 30,158.377 20,184.189 15.811,190 20,160 30)),((60 30,50 20,158.377 20,160 30,60 30)),((60 130,35 153.151,35 35,50 20,60 30,60 130)),((190 140,164.04 164.04,40.697 159.303,35 153.151,60 130,190 140)))</screen>
    </refsection>

    <refsection>
        <title>See Also</title>
        <para><xref linkend="CG_StraightSkeleton"/>, <xref linkend="ST_Polygonize"/></para>
    </refsection>
</refentry>

<refentry xml:id="CG_3DBuffer">
   <refnamediv>
       <refname>CG_3DBuffer</refname>
       <refpurpose>Computes a 3D buffer around a geometry.</refpurpose>
   </refnamediv>
   <refsynopsisdiv>
       <funcsynopsis>
           <funcprototype>
               <funcdef>geometry <function>CG_3DBuffer</function></funcdef>
               <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>radius</parameter></paramdef>
               <paramdef><type>integer</type> <parameter>segments</parameter></paramdef>
               <paramdef><type>integer</type> <parameter>buffer_type</parameter></paramdef>
           </funcprototype>
       </funcsynopsis>
   </refsynopsisdiv>
   <refsection>
       <title>Description</title>
       <para>Generates a 3D buffer around the input geometry <parameter>geom</parameter> with a specified <parameter>radius</parameter>.
       The buffer is constructed in 3D space, creating a volumetric representation of the geometry's surroundings.
       The <parameter>segments</parameter> parameter defines the number of segments used to approximate the curved sections of the buffer, with a minimum value of 4 segments required.
       The <parameter>buffer_type</parameter> specifies the type of buffer to create:
       0: Rounded buffer (default)
       1: Flat buffer
       2: Square buffer</para>
       <para>Input geometry must be a Point or LineString.</para>
       <para role="availability" conformance="3.6.0">Availability: 3.6.0 - requires SFCGAL &gt;= 2.0.0</para>
       <para>&sfcgal_required;</para>
   </refsection>
   <refsection>
       <title>Examples</title>
       <programlisting language="sql">SELECT CG_3DBuffer('POINT(0 0 0)', 1, 8, 0);</programlisting>
<screen role="visual-primary text-primary">POLYHEDRALSURFACE Z (((0 0 1, 0.5 -0.5 0.71, 0 -0.71 0.71, 0 0 1)), ... )</screen>

       <para>A rounded point buffer using 32 segments.</para>
       <programlisting language="sql" role="documented-output">SELECT
  'POINT(100 90)'::geometry AS input_geometry,
  CG_3DBuffer('POINT(100 90)'::geometry, 50, 32, 0) AS buffer;</programlisting>
<screen role="visual-primary geometry-output-precision-0">POINT(100 90) | POLYHEDRALSURFACE Z (((74 133 0,66 126 7,78 133 12,74 133 0)),((60 115 15,71 124 21,66 126 7,60 115 15)),((85 130 25,78 133 12,71 124 21,85 130 25)),((66 126 7,71 124 21,78 133 12,66 126 7)),((57 90 26,64 97 34,57 102 22,57 90 26)),((75 105 40,66 111 29,64 97 34,75 105 40)),((60 115 15,57 102 22,66 111 29,60 115 15)),((64 97 34,66 111 29,57 102 22,64 97 34)),((100 116 43,93 124 36,88 112 43,100 116 43)),((85 130 25,79 119 34,93 124 36,85 130 25)),((75 105 40,88 112 43,79 119 34,75 105 40)),((93 124 36,79 119 34,88 112 43,93 124 36)),((60 115 15,66 111 29,71 124 21,60 115 15)),((75 105 40,79 119 34,66 111 29,75 105 40)),((85 130 25,71 124 21,79 119 34,85 130 25)),((66 111 29,79 119 34,71 124 21,66 111 29)),((74 133 0,78 133 12,85 138 0,74 133 0)),((85 130 25,92 138 13,78 133 12,85 130 25)),((100 140 0,85 138 0,92 138 13,100 140 0)),((78 133 12,92 138 13,85 138 0,78 133 12)),((100 116 43,107 124 36,93 124 36,100 116 43)),((115 130 25,100 133 26,107 124 36,115 130 25)),((85 130 25,93 124 36,100 133 26,85 130 25)),((107 124 36,100 133 26,93 124 36,107 124 36)),((126 133 0,115 138 0,122 133 12,126 133 0)),((100 140 0,108 138 13,115 138 0,100 140 0)),((115 130 25,122 133 12,108 138 13,115 130 25)),((115 138 0,108 138 13,122 133 12,115 138 0)),((85 130 25,100 133 26,92 138 13,85 130 25)),((115 130 25,108 138 13,100 133 26,115 130 25)),((100 140 0,92 138 13,108 138 13,100 140 0)),((100 133 26,108 138 13,92 138 13,100 133 26)),((74 133 0,85 138 0,78 133 -12,74 133 0)),((100 140 0,92 138 -13,85 138 0,100 140 0)),((85 130 -25,78 133 -12,92 138 -13,85 130 -25)),((85 138 0,92 138 -13,78 133 -12,85 138 0)),((126 133 0,122 133 -12,115 138 0,126 133 0)),((115 130 -25,108 138 -13,122 133 -12,115 130 -25)),((100 140 0,115 138 0,108 138 -13,100 140 0)),((122 133 -12,108 138 -13,115 138 0,122 133 -12)),((100 116 -43,93 124 -36,107 124 -36,100 116 -43)),((85 130 -25,100 133 -26,93 124 -36,85 130 -25)),((115 130 -25,107 124 -36,100 133 -26,115 130 -25)),((93 124 -36,100 133 -26,107 124 -36,93 124 -36)),((100 140 0,108 138 -13,92 138 -13,100 140 0)),((115 130 -25,100 133 -26,108 138 -13,115 130 -25)),((85 130 -25,92 138 -13,100 133 -26,85 130 -25)),((108 138 -13,100 133 -26,92 138 -13,108 138 -13)),((74 133 0,78 133 -12,66 126 -7,74 133 0)),((85 130 -25,71 124 -21,78 133 -12,85 130 -25)),((60 115 -15,66 126 -7,71 124 -21,60 115 -15)),((78 133 -12,71 124 -21,66 126 -7,78 133 -12)),((100 116 -43,88 112 -43,93 124 -36,100 116 -43)),((75 105 -40,79 119 -34,88 112 -43,75 105 -40)),((85 130 -25,93 124 -36,79 119 -34,85 130 -25)),((88 112 -43,79 119 -34,93 124 -36,88 112 -43)),((57 90 -26,57 102 -22,64 97 -34,57 90 -26)),((60 115 -15,66 111 -29,57 102 -22,60 115 -15)),((75 105 -40,64 97 -34,66 111 -29,75 105 -40)),((57 102 -22,66 111 -29,64 97 -34,57 102 -22)),((85 130 -25,79 119 -34,71 124 -21,85 130 -25)),((75 105 -40,66 111 -29,79 119 -34,75 105 -40)),((60 115 -15,71 124 -21,66 111 -29,60 115 -15)),((79 119 -34,66 111 -29,71 124 -21,79 119 -34)),((74 133 0,66 126 -7,66 126 7,74 133 0)),((60 115 -15,57 116 0,66 126 -7,60 115 -15)),((60 115 15,66 126 7,57 116 0,60 115 15)),((66 126 -7,57 116 0,66 126 7,66 126 -7)),((57 90 -26,52 90 -15,57 102 -22,57 90 -26)),((50 90 0,52 103 -8,52 90 -15,50 90 0)),((60 115 -15,57 102 -22,52 103 -8,60 115 -15)),((52 90 -15,52 103 -8,57 102 -22,52 90 -15)),((57 90 26,57 102 22,52 90 15,57 90 26)),((60 115 15,52 103 8,57 102 22,60 115 15)),((50 90 0,52 90 15,52 103 8,50 90 0)),((57 102 22,52 103 8,52 90 15,57 102 22)),((60 115 -15,52 103 -8,57 116 0,60 115 -15)),((50 90 0,52 103 8,52 103 -8,50 90 0)),((60 115 15,57 116 0,52 103 8,60 115 15)),((52 103 -8,52 103 8,57 116 0,52 103 -8)),((126 133 0,122 133 12,134 126 7,126 133 0)),((115 130 25,129 124 21,122 133 12,115 130 25)),((140 115 15,134 126 7,129 124 21,140 115 15)),((122 133 12,129 124 21,134 126 7,122 133 12)),((100 116 43,112 112 43,107 124 36,100 116 43)),((125 105 40,121 119 34,112 112 43,125 105 40)),((115 130 25,107 124 36,121 119 34,115 130 25)),((112 112 43,121 119 34,107 124 36,112 112 43)),((143 90 26,143 102 22,136 97 34,143 90 26)),((140 115 15,134 111 29,143 102 22,140 115 15)),((125 105 40,136 97 34,134 111 29,125 105 40)),((143 102 22,134 111 29,136 97 34,143 102 22)),((115 130 25,121 119 34,129 124 21,115 130 25)),((125 105 40,134 111 29,121 119 34,125 105 40)),((140 115 15,129 124 21,134 111 29,140 115 15)),((121 119 34,134 111 29,129 124 21,121 119 34)),((100 116 43,88 112 43,100 105 48,100 116 43)),((75 105 40,87 98 48,88 112 43,75 105 40)),((100 90 50,100 105 48,87 98 48,100 90 50)),((88 112 43,87 98 48,100 105 48,88 112 43)),((57 90 26,64 83 34,64 97 34,57 90 26)),((75 75 40,74 90 43,64 83 34,75 75 40)),((75 105 40,64 97 34,74 90 43,75 105 40)),((64 83 34,74 90 43,64 97 34,64 83 34)),((100 64 43,100 75 48,88 68 43,100 64 43)),((100 90 50,87 82 48,100 75 48,100 90 50)),((75 75 40,88 68 43,87 82 48,75 75 40)),((100 75 48,87 82 48,88 68 43,100 75 48)),((75 105 40,74 90 43,87 98 48,75 105 40)),((75 75 40,87 82 48,74 90 43,75 75 40)),((100 90 50,87 98 48,87 82 48,100 90 50)),((74 90 43,87 82 48,87 98 48,74 90 43)),((57 90 26,52 90 15,57 78 22,57 90 26)),((50 90 0,52 77 8,52 90 15,50 90 0)),((60 65 15,57 78 22,52 77 8,60 65 15)),((52 90 15,52 77 8,57 78 22,52 90 15)),((57 90 -26,57 78 -22,52 90 -15,57 90 -26)),((60 65 -15,52 77 -8,57 78 -22,60 65 -15)),((50 90 0,52 90 -15,52 77 -8,50 90 0)),((57 78 -22,52 77 -8,52 90 -15,57 78 -22)),((74 47 0,66 54 7,66 54 -7,74 47 0)),((60 65 15,57 64 0,66 54 7,60 65 15)),((60 65 -15,66 54 -7,57 64 0,60 65 -15)),((66 54 7,57 64 0,66 54 -7,66 54 7)),((50 90 0,52 77 -8,52 77 8,50 90 0)),((60 65 -15,57 64 0,52 77 -8,60 65 -15)),((60 65 15,52 77 8,57 64 0,60 65 15)),((52 77 -8,57 64 0,52 77 8,52 77 -8)),((57 90 -26,64 97 -34,64 83 -34,57 90 -26)),((75 105 -40,74 90 -43,64 97 -34,75 105 -40)),((75 75 -40,64 83 -34,74 90 -43,75 75 -40)),((64 97 -34,74 90 -43,64 83 -34,64 97 -34)),((100 116 -43,100 105 -48,88 112 -43,100 116 -43)),((100 90 -50,87 98 -48,100 105 -48,100 90 -50)),((75 105 -40,88 112 -43,87 98 -48,75 105 -40)),((100 105 -48,87 98 -48,88 112 -43,100 105 -48)),((100 64 -43,88 68 -43,100 75 -48,100 64 -43)),((75 75 -40,87 82 -48,88 68 -43,75 75 -40)),((100 90 -50,100 75 -48,87 82 -48,100 90 -50)),((88 68 -43,87 82 -48,100 75 -48,88 68 -43)),((75 105 -40,87 98 -48,74 90 -43,75 105 -40)),((100 90 -50,87 82 -48,87 98 -48,100 90 -50)),((75 75 -40,74 90 -43,87 82 -48,75 75 -40)),((87 98 -48,87 82 -48,74 90 -43,87 98 -48)),((100 116 -43,107 124 -36,112 112 -43,100 116 -43)),((115 130 -25,121 119 -34,107 124 -36,115 130 -25)),((125 105 -40,112 112 -43,121 119 -34,125 105 -40)),((107 124 -36,121 119 -34,112 112 -43,107 124 -36)),((126 133 0,134 126 -7,122 133 -12,126 133 0)),((140 115 -15,129 124 -21,134 126 -7,140 115 -15)),((115 130 -25,122 133 -12,129 124 -21,115 130 -25)),((134 126 -7,129 124 -21,122 133 -12,134 126 -7)),((143 90 -26,136 97 -34,143 102 -22,143 90 -26)),((125 105 -40,134 111 -29,136 97 -34,125 105 -40)),((140 115 -15,143 102 -22,134 111 -29,140 115 -15)),((136 97 -34,134 111 -29,143 102 -22,136 97 -34)),((115 130 -25,129 124 -21,121 119 -34,115 130 -25)),((140 115 -15,134 111 -29,129 124 -21,140 115 -15)),((125 105 -40,121 119 -34,134 111 -29,125 105 -40)),((129 124 -21,134 111 -29,121 119 -34,129 124 -21)),((126 47 0,134 54 7,122 47 12,126 47 0)),((140 65 15,129 56 21,134 54 7,140 65 15)),((115 50 25,122 47 12,129 56 21,115 50 25)),((134 54 7,129 56 21,122 47 12,134 54 7)),((143 90 26,136 83 34,143 78 22,143 90 26)),((125 75 40,134 69 29,136 83 34,125 75 40)),((140 65 15,143 78 22,134 69 29,140 65 15)),((136 83 34,134 69 29,143 78 22,136 83 34)),((100 64 43,107 56 36,112 68 43,100 64 43)),((115 50 25,121 61 34,107 56 36,115 50 25)),((125 75 40,112 68 43,121 61 34,125 75 40)),((107 56 36,121 61 34,112 68 43,107 56 36)),((140 65 15,134 69 29,129 56 21,140 65 15)),((125 75 40,121 61 34,134 69 29,125 75 40)),((115 50 25,129 56 21,121 61 34,115 50 25)),((134 69 29,121 61 34,129 56 21,134 69 29)),((126 47 0,122 47 12,115 42 0,126 47 0)),((115 50 25,108 42 13,122 47 12,115 50 25)),((100 40 0,115 42 0,108 42 13,100 40 0)),((122 47 12,108 42 13,115 42 0,122 47 12)),((100 64 43,93 56 36,107 56 36,100 64 43)),((85 50 25,100 47 26,93 56 36,85 50 25)),((115 50 25,107 56 36,100 47 26,115 50 25)),((93 56 36,100 47 26,107 56 36,93 56 36)),((74 47 0,85 42 0,78 47 12,74 47 0)),((100 40 0,92 42 13,85 42 0,100 40 0)),((85 50 25,78 47 12,92 42 13,85 50 25)),((85 42 0,92 42 13,78 47 12,85 42 0)),((115 50 25,100 47 26,108 42 13,115 50 25)),((85 50 25,92 42 13,100 47 26,85 50 25)),((100 40 0,108 42 13,92 42 13,100 40 0)),((100 47 26,92 42 13,108 42 13,100 47 26)),((126 47 0,115 42 0,122 47 -12,126 47 0)),((100 40 0,108 42 -13,115 42 0,100 40 0)),((115 50 -25,122 47 -12,108 42 -13,115 50 -25)),((115 42 0,108 42 -13,122 47 -12,115 42 0)),((74 47 0,78 47 -12,85 42 0,74 47 0)),((85 50 -25,92 42 -13,78 47 -12,85 50 -25)),((100 40 0,85 42 0,92 42 -13,100 40 0)),((78 47 -12,92 42 -13,85 42 0,78 47 -12)),((100 64 -43,107 56 -36,93 56 -36,100 64 -43)),((115 50 -25,100 47 -26,107 56 -36,115 50 -25)),((85 50 -25,93 56 -36,100 47 -26,85 50 -25)),((107 56 -36,100 47 -26,93 56 -36,107 56 -36)),((100 40 0,92 42 -13,108 42 -13,100 40 0)),((85 50 -25,100 47 -26,92 42 -13,85 50 -25)),((115 50 -25,108 42 -13,100 47 -26,115 50 -25)),((92 42 -13,100 47 -26,108 42 -13,92 42 -13)),((126 47 0,122 47 -12,134 54 -7,126 47 0)),((115 50 -25,129 56 -21,122 47 -12,115 50 -25)),((140 65 -15,134 54 -7,129 56 -21,140 65 -15)),((122 47 -12,129 56 -21,134 54 -7,122 47 -12)),((100 64 -43,112 68 -43,107 56 -36,100 64 -43)),((125 75 -40,121 61 -34,112 68 -43,125 75 -40)),((115 50 -25,107 56 -36,121 61 -34,115 50 -25)),((112 68 -43,121 61 -34,107 56 -36,112 68 -43)),((143 90 -26,143 78 -22,136 83 -34,143 90 -26)),((140 65 -15,134 69 -29,143 78 -22,140 65 -15)),((125 75 -40,136 83 -34,134 69 -29,125 75 -40)),((143 78 -22,134 69 -29,136 83 -34,143 78 -22)),((115 50 -25,121 61 -34,129 56 -21,115 50 -25)),((125 75 -40,134 69 -29,121 61 -34,125 75 -40)),((140 65 -15,129 56 -21,134 69 -29,140 65 -15)),((121 61 -34,134 69 -29,129 56 -21,121 61 -34)),((126 47 0,134 54 -7,134 54 7,126 47 0)),((140 65 -15,143 64 0,134 54 -7,140 65 -15)),((140 65 15,134 54 7,143 64 0,140 65 15)),((134 54 -7,143 64 0,134 54 7,134 54 -7)),((143 90 -26,148 90 -15,143 78 -22,143 90 -26)),((150 90 0,148 77 -8,148 90 -15,150 90 0)),((140 65 -15,143 78 -22,148 77 -8,140 65 -15)),((148 90 -15,148 77 -8,143 78 -22,148 90 -15)),((143 90 26,143 78 22,148 90 15,143 90 26)),((140 65 15,148 77 8,143 78 22,140 65 15)),((150 90 0,148 90 15,148 77 8,150 90 0)),((143 78 22,148 77 8,148 90 15,143 78 22)),((140 65 -15,148 77 -8,143 64 0,140 65 -15)),((150 90 0,148 77 8,148 77 -8,150 90 0)),((140 65 15,143 64 0,148 77 8,140 65 15)),((148 77 -8,148 77 8,143 64 0,148 77 -8)),((100 64 43,112 68 43,100 75 48,100 64 43)),((125 75 40,113 82 48,112 68 43,125 75 40)),((100 90 50,100 75 48,113 82 48,100 90 50)),((112 68 43,113 82 48,100 75 48,112 68 43)),((143 90 26,136 97 34,136 83 34,143 90 26)),((125 105 40,126 90 43,136 97 34,125 105 40)),((125 75 40,136 83 34,126 90 43,125 75 40)),((136 97 34,126 90 43,136 83 34,136 97 34)),((100 116 43,100 105 48,112 112 43,100 116 43)),((100 90 50,113 98 48,100 105 48,100 90 50)),((125 105 40,112 112 43,113 98 48,125 105 40)),((100 105 48,113 98 48,112 112 43,100 105 48)),((125 75 40,126 90 43,113 82 48,125 75 40)),((125 105 40,113 98 48,126 90 43,125 105 40)),((100 90 50,113 82 48,113 98 48,100 90 50)),((126 90 43,113 98 48,113 82 48,126 90 43)),((74 47 0,78 47 12,66 54 7,74 47 0)),((85 50 25,71 56 21,78 47 12,85 50 25)),((60 65 15,66 54 7,71 56 21,60 65 15)),((78 47 12,71 56 21,66 54 7,78 47 12)),((100 64 43,88 68 43,93 56 36,100 64 43)),((75 75 40,79 61 34,88 68 43,75 75 40)),((85 50 25,93 56 36,79 61 34,85 50 25)),((88 68 43,79 61 34,93 56 36,88 68 43)),((57 90 26,57 78 22,64 83 34,57 90 26)),((60 65 15,66 69 29,57 78 22,60 65 15)),((75 75 40,64 83 34,66 69 29,75 75 40)),((57 78 22,66 69 29,64 83 34,57 78 22)),((85 50 25,79 61 34,71 56 21,85 50 25)),((75 75 40,66 69 29,79 61 34,75 75 40)),((60 65 15,71 56 21,66 69 29,60 65 15)),((79 61 34,66 69 29,71 56 21,79 61 34)),((100 64 -43,93 56 -36,88 68 -43,100 64 -43)),((85 50 -25,79 61 -34,93 56 -36,85 50 -25)),((75 75 -40,88 68 -43,79 61 -34,75 75 -40)),((93 56 -36,79 61 -34,88 68 -43,93 56 -36)),((74 47 0,66 54 -7,78 47 -12,74 47 0)),((60 65 -15,71 56 -21,66 54 -7,60 65 -15)),((85 50 -25,78 47 -12,71 56 -21,85 50 -25)),((66 54 -7,71 56 -21,78 47 -12,66 54 -7)),((57 90 -26,64 83 -34,57 78 -22,57 90 -26)),((75 75 -40,66 69 -29,64 83 -34,75 75 -40)),((60 65 -15,57 78 -22,66 69 -29,60 65 -15)),((64 83 -34,66 69 -29,57 78 -22,64 83 -34)),((85 50 -25,71 56 -21,79 61 -34,85 50 -25)),((60 65 -15,66 69 -29,71 56 -21,60 65 -15)),((75 75 -40,79 61 -34,66 69 -29,75 75 -40)),((71 56 -21,66 69 -29,79 61 -34,71 56 -21)),((143 90 -26,136 83 -34,136 97 -34,143 90 -26)),((125 75 -40,126 90 -43,136 83 -34,125 75 -40)),((125 105 -40,136 97 -34,126 90 -43,125 105 -40)),((136 83 -34,126 90 -43,136 97 -34,136 83 -34)),((100 64 -43,100 75 -48,112 68 -43,100 64 -43)),((100 90 -50,113 82 -48,100 75 -48,100 90 -50)),((125 75 -40,112 68 -43,113 82 -48,125 75 -40)),((100 75 -48,113 82 -48,112 68 -43,100 75 -48)),((100 116 -43,112 112 -43,100 105 -48,100 116 -43)),((125 105 -40,113 98 -48,112 112 -43,125 105 -40)),((100 90 -50,100 105 -48,113 98 -48,100 90 -50)),((112 112 -43,113 98 -48,100 105 -48,112 112 -43)),((125 75 -40,113 82 -48,126 90 -43,125 75 -40)),((100 90 -50,113 98 -48,113 82 -48,100 90 -50)),((125 105 -40,126 90 -43,113 98 -48,125 105 -40)),((113 82 -48,113 98 -48,126 90 -43,113 82 -48)),((143 90 26,148 90 15,143 102 22,143 90 26)),((150 90 0,148 103 8,148 90 15,150 90 0)),((140 115 15,143 102 22,148 103 8,140 115 15)),((148 90 15,148 103 8,143 102 22,148 90 15)),((143 90 -26,143 102 -22,148 90 -15,143 90 -26)),((140 115 -15,148 103 -8,143 102 -22,140 115 -15)),((150 90 0,148 90 -15,148 103 -8,150 90 0)),((143 102 -22,148 103 -8,148 90 -15,143 102 -22)),((126 133 0,134 126 7,134 126 -7,126 133 0)),((140 115 15,143 116 0,134 126 7,140 115 15)),((140 115 -15,134 126 -7,143 116 0,140 115 -15)),((134 126 7,143 116 0,134 126 -7,134 126 7)),((150 90 0,148 103 -8,148 103 8,150 90 0)),((140 115 -15,143 116 0,148 103 -8,140 115 -15)),((140 115 15,148 103 8,143 116 0,140 115 15)),((148 103 -8,143 116 0,148 103 8,148 103 -8)))</screen>

       <para>A coarser rounded point buffer using 5 segments.</para>
       <programlisting language="sql" role="documented-output">SELECT
  'POINT(100 90)'::geometry AS input_geometry,
  CG_3DBuffer('POINT(100 90)'::geometry, 50, 5, 0) AS buffer;</programlisting>
<screen role="visual-primary geometry-output-precision-0">POINT(100 90) | POLYHEDRALSURFACE Z (((74 133 0,60 115 15,85 130 25,74 133 0)),((57 90 26,75 105 40,60 115 15,57 90 26)),((100 116 43,85 130 25,75 105 40,100 116 43)),((60 115 15,75 105 40,85 130 25,60 115 15)),((74 133 0,85 130 25,100 140 0,74 133 0)),((100 116 43,115 130 25,85 130 25,100 116 43)),((126 133 0,100 140 0,115 130 25,126 133 0)),((85 130 25,115 130 25,100 140 0,85 130 25)),((74 133 0,100 140 0,85 130 -25,74 133 0)),((126 133 0,115 130 -25,100 140 0,126 133 0)),((100 116 -43,85 130 -25,115 130 -25,100 116 -43)),((100 140 0,115 130 -25,85 130 -25,100 140 0)),((74 133 0,85 130 -25,60 115 -15,74 133 0)),((100 116 -43,75 105 -40,85 130 -25,100 116 -43)),((57 90 -26,60 115 -15,75 105 -40,57 90 -26)),((85 130 -25,75 105 -40,60 115 -15,85 130 -25)),((74 133 0,60 115 -15,60 115 15,74 133 0)),((57 90 -26,50 90 0,60 115 -15,57 90 -26)),((57 90 26,60 115 15,50 90 0,57 90 26)),((60 115 -15,50 90 0,60 115 15,60 115 -15)),((126 133 0,115 130 25,140 115 15,126 133 0)),((100 116 43,125 105 40,115 130 25,100 116 43)),((143 90 26,140 115 15,125 105 40,143 90 26)),((115 130 25,125 105 40,140 115 15,115 130 25)),((100 116 43,75 105 40,100 90 50,100 116 43)),((57 90 26,75 75 40,75 105 40,57 90 26)),((100 64 43,100 90 50,75 75 40,100 64 43)),((75 105 40,75 75 40,100 90 50,75 105 40)),((57 90 26,50 90 0,60 65 15,57 90 26)),((57 90 -26,60 65 -15,50 90 0,57 90 -26)),((74 47 0,60 65 15,60 65 -15,74 47 0)),((50 90 0,60 65 -15,60 65 15,50 90 0)),((57 90 -26,75 105 -40,75 75 -40,57 90 -26)),((100 116 -43,100 90 -50,75 105 -40,100 116 -43)),((100 64 -43,75 75 -40,100 90 -50,100 64 -43)),((75 105 -40,100 90 -50,75 75 -40,75 105 -40)),((100 116 -43,115 130 -25,125 105 -40,100 116 -43)),((126 133 0,140 115 -15,115 130 -25,126 133 0)),((143 90 -26,125 105 -40,140 115 -15,143 90 -26)),((115 130 -25,140 115 -15,125 105 -40,115 130 -25)),((126 47 0,140 65 15,115 50 25,126 47 0)),((143 90 26,125 75 40,140 65 15,143 90 26)),((100 64 43,115 50 25,125 75 40,100 64 43)),((140 65 15,125 75 40,115 50 25,140 65 15)),((126 47 0,115 50 25,100 40 0,126 47 0)),((100 64 43,85 50 25,115 50 25,100 64 43)),((74 47 0,100 40 0,85 50 25,74 47 0)),((115 50 25,85 50 25,100 40 0,115 50 25)),((126 47 0,100 40 0,115 50 -25,126 47 0)),((74 47 0,85 50 -25,100 40 0,74 47 0)),((100 64 -43,115 50 -25,85 50 -25,100 64 -43)),((100 40 0,85 50 -25,115 50 -25,100 40 0)),((126 47 0,115 50 -25,140 65 -15,126 47 0)),((100 64 -43,125 75 -40,115 50 -25,100 64 -43)),((143 90 -26,140 65 -15,125 75 -40,143 90 -26)),((115 50 -25,125 75 -40,140 65 -15,115 50 -25)),((126 47 0,140 65 -15,140 65 15,126 47 0)),((143 90 -26,150 90 0,140 65 -15,143 90 -26)),((143 90 26,140 65 15,150 90 0,143 90 26)),((140 65 -15,150 90 0,140 65 15,140 65 -15)),((100 64 43,125 75 40,100 90 50,100 64 43)),((143 90 26,125 105 40,125 75 40,143 90 26)),((100 116 43,100 90 50,125 105 40,100 116 43)),((125 75 40,125 105 40,100 90 50,125 75 40)),((74 47 0,85 50 25,60 65 15,74 47 0)),((100 64 43,75 75 40,85 50 25,100 64 43)),((57 90 26,60 65 15,75 75 40,57 90 26)),((85 50 25,75 75 40,60 65 15,85 50 25)),((100 64 -43,85 50 -25,75 75 -40,100 64 -43)),((74 47 0,60 65 -15,85 50 -25,74 47 0)),((57 90 -26,75 75 -40,60 65 -15,57 90 -26)),((85 50 -25,60 65 -15,75 75 -40,85 50 -25)),((143 90 -26,125 75 -40,125 105 -40,143 90 -26)),((100 64 -43,100 90 -50,125 75 -40,100 64 -43)),((100 116 -43,125 105 -40,100 90 -50,100 116 -43)),((125 75 -40,100 90 -50,125 105 -40,125 75 -40)),((143 90 26,150 90 0,140 115 15,143 90 26)),((143 90 -26,140 115 -15,150 90 0,143 90 -26)),((126 133 0,140 115 15,140 115 -15,126 133 0)),((150 90 0,140 115 -15,140 115 15,150 90 0)))</screen>

       <para>A rounded buffer around a line using 32 segments.</para>
       <programlisting language="sql" role="documented-output">SELECT
  'LINESTRING(50 50,150 150,150 50)'::geometry AS input_geometry,
  CG_3DBuffer('LINESTRING(50 50,150 150,150 50)'::geometry, 10, 32, 0) AS buffer;</programlisting>
<screen role="visual-primary geometry-output-precision-0">LINESTRING(50 50,150 150,150 50) | POLYHEDRALSURFACE Z (((40 50 3,40 50 0,40 47 2,40 50 3)),((40 47 2,40 50 0,40 47 -2,40 47 2)),((40 47 -2,40 50 0,40 50 -3,40 47 -2)),((40 50 -3,40 50 0,40 53 -2,40 50 -3)),((40 53 -2,40 50 0,40 53 2,40 53 -2)),((40 53 2,40 50 0,40 50 3,40 53 2)),((40 53 2,40 50 3,41 52 4,40 53 2)),((41 52 4,40 50 3,41 50 5,41 52 4)),((41 50 5,40 50 3,41 48 4,41 50 5)),((41 48 4,40 50 3,40 47 2,41 48 4)),((40 47 2,40 47 -2,41 45 0,40 47 2)),((41 48 4,40 47 2,42 45 3,41 48 4)),((42 45 3,40 47 2,41 45 0,42 45 3)),((41 45 0,40 47 -2,42 45 -3,41 45 0)),((42 45 -3,40 47 -2,41 48 -4,42 45 -3)),((40 47 -2,40 50 -3,41 48 -4,40 47 -2)),((41 48 -4,40 50 -3,41 50 -5,41 48 -4)),((41 50 -5,40 50 -3,41 52 -4,41 50 -5)),((41 52 -4,40 50 -3,40 53 -2,41 52 -4)),((41 55 0,40 53 -2,40 53 2,41 55 0)),((41 52 -4,40 53 -2,42 55 -3,41 52 -4)),((42 55 -3,40 53 -2,41 55 0,42 55 -3)),((41 55 0,40 53 2,42 55 3,41 55 0)),((42 55 3,40 53 2,41 52 4,42 55 3)),((42 55 3,41 52 4,43 54 6,42 55 3)),((43 54 6,41 52 4,43 51 7,43 54 6)),((43 51 7,41 52 4,41 50 5,43 51 7)),((43 51 7,41 50 5,43 49 7,43 51 7)),((41 50 5,41 48 4,43 49 7,41 50 5)),((43 49 7,41 48 4,43 46 6,43 49 7)),((43 46 6,41 48 4,42 45 3,43 46 6)),((42 45 3,41 45 0,43 43 1,42 45 3)),((43 43 1,41 45 0,43 43 -1,43 43 1)),((43 43 -1,41 45 0,42 45 -3,43 43 -1)),((43 46 6,42 45 3,44 43 4,43 46 6)),((44 43 4,42 45 3,43 43 1,44 43 4)),((44 43 -4,42 45 -3,43 46 -6,44 43 -4)),((42 45 -3,41 48 -4,43 46 -6,42 45 -3)),((43 43 -1,42 45 -3,44 43 -4,43 43 -1)),((43 46 -6,41 48 -4,43 49 -7,43 46 -6)),((43 49 -7,41 48 -4,41 50 -5,43 49 -7)),((43 49 -7,41 50 -5,43 51 -7,43 49 -7)),((41 50 -5,41 52 -4,43 51 -7,41 50 -5)),((43 51 -7,41 52 -4,43 54 -6,43 51 -7)),((43 54 -6,41 52 -4,42 55 -3,43 54 -6)),((42 55 -3,41 55 0,43 57 -1,42 55 -3)),((43 57 -1,41 55 0,43 57 1,43 57 -1)),((43 57 1,41 55 0,42 55 3,43 57 1)),((43 54 -6,42 55 -3,44 57 -4,43 54 -6)),((44 57 -4,42 55 -3,43 57 -1,44 57 -4)),((43 57 1,42 55 3,44 57 4,43 57 1)),((44 57 4,42 55 3,43 54 6,44 57 4)),((43 54 6,46 56 7,44 57 4,43 54 6)),((44 57 4,46 56 7,146 156 7,44 57 4)),((44 57 4,146 156 7,144 157 4,44 57 4)),((46 56 7,43 54 6,45 53 8,46 56 7)),((43 54 6,43 51 7,45 53 8,43 54 6)),((45 53 8,43 51 7,45 50 9,45 53 8)),((43 51 7,43 49 7,45 50 9,43 51 7)),((45 50 9,43 49 7,45 47 8,45 50 9)),((45 47 8,43 49 7,43 46 6,45 47 8)),((45 47 8,43 46 6,46 44 7,45 47 8)),((46 44 7,43 46 6,44 43 4,46 44 7)),((43 43 1,43 43 -1,45 41 0,43 43 1)),((44 43 4,43 43 1,46 41 2,44 43 4)),((46 41 2,43 43 1,45 41 0,46 41 2)),((45 41 0,43 43 -1,46 41 -2,45 41 0)),((46 41 -2,43 43 -1,44 43 -4,46 41 -2)),((46 44 7,44 43 4,47 42 5,46 44 7)),((47 42 5,44 43 4,46 41 2,47 42 5)),((47 42 -5,44 43 -4,46 44 -7,47 42 -5)),((44 43 -4,43 46 -6,46 44 -7,44 43 -4)),((46 41 -2,44 43 -4,47 42 -5,46 41 -2)),((46 44 -7,43 46 -6,45 47 -8,46 44 -7)),((43 46 -6,43 49 -7,45 47 -8,43 46 -6)),((45 47 -8,43 49 -7,45 50 -9,45 47 -8)),((45 50 -9,43 49 -7,43 51 -7,45 50 -9)),((45 50 -9,43 51 -7,45 53 -8,45 50 -9)),((45 53 -8,43 51 -7,43 54 -6,45 53 -8)),((45 53 -8,43 54 -6,46 56 -7,45 53 -8)),((43 54 -6,44 57 -4,46 56 -7,43 54 -6)),((46 56 -7,44 57 -4,144 157 -4,46 56 -7)),((46 56 -7,144 157 -4,146 156 -7,46 56 -7)),((43 57 -1,43 57 1,143 157 -1,43 57 -1)),((143 157 -1,43 57 1,143 157 1,143 157 -1)),((43 57 -1,143 157 -1,44 57 -4,43 57 -1)),((44 57 -4,143 157 -1,144 157 -4,44 57 -4)),((43 57 1,44 57 4,143 157 1,43 57 1)),((143 157 1,44 57 4,144 157 4,143 157 1)),((146 159 2,143 157 1,144 157 4,146 159 2)),((146 159 2,144 157 4,147 158 5,146 159 2)),((147 158 5,144 157 4,146 156 7,147 158 5)),((46 56 7,45 53 8,145 153 8,46 56 7)),((146 156 7,46 56 7,145 153 8,146 156 7)),((147 158 5,146 156 7,149 157 7,147 158 5)),((149 157 7,146 156 7,148 154 9,149 157 7)),((146 156 7,145 153 8,148 154 9,146 156 7)),((145 153 8,45 53 8,48 54 9,145 153 8)),((148 154 9,145 153 8,48 54 9,148 154 9)),((48 54 9,45 53 8,47 52 10,48 54 9)),((45 53 8,45 50 9,47 52 10,45 53 8)),((47 52 10,45 50 9,47 48 10,47 52 10)),((47 48 10,45 50 9,45 47 8,47 48 10)),((47 48 10,45 47 8,48 46 9,47 48 10)),((48 46 9,45 47 8,46 44 7,48 46 9)),((48 46 9,46 44 7,49 43 7,48 46 9)),((49 43 7,46 44 7,47 42 5,49 43 7)),((46 41 2,45 41 0,47 40 0,46 41 2)),((47 40 0,45 41 0,46 41 -2,47 40 0)),((47 42 5,46 41 2,48 40 3,47 42 5)),((48 40 3,46 41 2,47 40 0,48 40 3)),((48 40 -3,46 41 -2,47 42 -5,48 40 -3)),((47 40 0,46 41 -2,48 40 -3,47 40 0)),((49 43 7,47 42 5,50 41 5,49 43 7)),((50 41 5,47 42 5,48 40 3,50 41 5)),((50 41 -5,47 42 -5,49 43 -7,50 41 -5)),((47 42 -5,46 44 -7,49 43 -7,47 42 -5)),((48 40 -3,47 42 -5,50 41 -5,48 40 -3)),((49 43 -7,46 44 -7,48 46 -9,49 43 -7)),((46 44 -7,45 47 -8,48 46 -9,46 44 -7)),((48 46 -9,45 47 -8,47 48 -10,48 46 -9)),((45 47 -8,45 50 -9,47 48 -10,45 47 -8)),((47 48 -10,45 50 -9,47 52 -10,47 48 -10)),((47 52 -10,45 50 -9,45 53 -8,47 52 -10)),((47 52 -10,45 53 -8,48 54 -9,47 52 -10)),((45 53 -8,145 153 -8,48 54 -9,45 53 -8)),((48 54 -9,145 153 -8,148 154 -9,48 54 -9)),((45 53 -8,46 56 -7,145 153 -8,45 53 -8)),((145 153 -8,46 56 -7,146 156 -7,145 153 -8)),((148 154 -9,145 153 -8,146 156 -7,148 154 -9)),((148 154 -9,146 156 -7,149 157 -7,148 154 -9)),((149 157 -7,146 156 -7,147 158 -5,149 157 -7)),((146 156 -7,144 157 -4,147 158 -5,146 156 -7)),((147 158 -5,144 157 -4,146 159 -2,147 158 -5)),((144 157 -4,143 157 -1,146 159 -2,144 157 -4)),((146 159 -2,143 157 -1,145 159 0,146 159 -2)),((145 159 0,143 157 -1,143 157 1,145 159 0)),((145 159 0,143 157 1,146 159 2,145 159 0)),((147 160 0,145 159 0,146 159 2,147 160 0)),((147 160 0,146 159 2,148 160 3,147 160 0)),((148 160 3,146 159 2,147 158 5,148 160 3)),((148 160 3,147 158 5,150 159 5,148 160 3)),((150 159 5,147 158 5,149 157 7,150 159 5)),((150 159 5,149 157 7,151 157 7,150 159 5)),((151 157 7,149 157 7,150 155 9,151 157 7)),((149 157 7,148 154 9,150 155 9,149 157 7)),((48 54 9,47 52 10,147 152 10,48 54 9)),((148 154 9,48 54 9,147 152 10,148 154 9)),((150 155 9,148 154 9,150 153 10,150 155 9)),((148 154 9,147 152 10,150 153 10,148 154 9)),((147 152 10,47 52 10,50 50 10,147 152 10)),((150 150 10,147 152 10,50 50 10,150 150 10)),((47 52 10,47 48 10,50 50 10,47 52 10)),((50 50 10,47 48 10,50 47 10,50 50 10)),((50 47 10,47 48 10,48 46 9,50 47 10)),((50 47 10,48 46 9,50 45 9,50 47 10)),((50 45 9,48 46 9,49 43 7,50 45 9)),((50 45 9,49 43 7,51 43 7,50 45 9)),((51 43 7,49 43 7,50 41 5,51 43 7)),((48 40 3,47 40 0,50 40 0,48 40 3)),((50 40 0,47 40 0,48 40 -3,50 40 0)),((50 41 5,48 40 3,52 40 3,50 41 5)),((52 40 3,48 40 3,50 40 0,52 40 3)),((50 40 0,48 40 -3,52 40 -3,50 40 0)),((52 40 -3,48 40 -3,50 41 -5,52 40 -3)),((51 43 7,50 41 5,53 42 5,51 43 7)),((53 42 5,50 41 5,52 40 3,53 42 5)),((52 40 -3,50 41 -5,53 42 -5,52 40 -3)),((53 42 -5,50 41 -5,51 43 -7,53 42 -5)),((50 41 -5,49 43 -7,51 43 -7,50 41 -5)),((51 43 -7,49 43 -7,50 45 -9,51 43 -7)),((49 43 -7,48 46 -9,50 45 -9,49 43 -7)),((50 45 -9,48 46 -9,50 47 -10,50 45 -9)),((48 46 -9,47 48 -10,50 47 -10,48 46 -9)),((50 47 -10,47 48 -10,50 50 -10,50 47 -10)),((50 50 -10,47 48 -10,47 52 -10,50 50 -10)),((47 52 -10,147 152 -10,50 50 -10,47 52 -10)),((50 50 -10,147 152 -10,150 150 -10,50 50 -10)),((47 52 -10,48 54 -9,147 152 -10,47 52 -10)),((147 152 -10,48 54 -9,148 154 -9,147 152 -10)),((150 153 -10,147 152 -10,148 154 -9,150 153 -10)),((150 153 -10,148 154 -9,150 155 -9,150 153 -10)),((150 155 -9,148 154 -9,149 157 -7,150 155 -9)),((150 155 -9,149 157 -7,151 157 -7,150 155 -9)),((151 157 -7,149 157 -7,150 159 -5,151 157 -7)),((149 157 -7,147 158 -5,150 159 -5,149 157 -7)),((150 159 -5,147 158 -5,148 160 -3,150 159 -5)),((147 158 -5,146 159 -2,148 160 -3,147 158 -5)),((148 160 -3,146 159 -2,147 160 0,148 160 -3)),((146 159 -2,145 159 0,147 160 0,146 159 -2)),((148 160 -3,147 160 0,150 160 0,148 160 -3)),((150 160 0,147 160 0,148 160 3,150 160 0)),((150 160 0,148 160 3,152 160 3,150 160 0)),((152 160 3,148 160 3,150 159 5,152 160 3)),((152 160 3,150 159 5,153 158 5,152 160 3)),((153 158 5,150 159 5,151 157 7,153 158 5)),((153 158 5,151 157 7,154 156 7,153 158 5)),((154 156 7,151 157 7,152 154 9,154 156 7)),((151 157 7,150 155 9,152 154 9,151 157 7)),((150 155 9,150 153 10,152 154 9,150 155 9)),((150 153 10,147 152 10,150 150 10,150 153 10)),((152 154 9,150 153 10,153 152 10,152 154 9)),((150 153 10,150 150 10,153 152 10,150 153 10)),((150 150 10,150 50 10,153 48 10,150 150 10)),((153 152 10,150 150 10,153 48 10,153 152 10)),((147 143 10,147 48 10,150 50 10,147 143 10)),((150 150 10,147 143 10,150 50 10,150 150 10)),((150 150 10,50 50 10,53 48 10,150 150 10)),((147 143 10,150 150 10,53 48 10,147 143 10)),((50 50 10,50 47 10,53 48 10,50 50 10)),((53 48 10,50 47 10,52 46 9,53 48 10)),((50 47 10,50 45 9,52 46 9,50 47 10)),((52 46 9,50 45 9,51 43 7,52 46 9)),((52 46 9,51 43 7,54 44 7,52 46 9)),((54 44 7,51 43 7,53 42 5,54 44 7)),((52 40 3,50 40 0,53 40 0,52 40 3)),((53 40 0,50 40 0,52 40 -3,53 40 0)),((53 42 5,52 40 3,54 41 2,53 42 5)),((54 41 2,52 40 3,53 40 0,54 41 2)),((53 40 0,52 40 -3,54 41 -2,53 40 0)),((54 41 -2,52 40 -3,53 42 -5,54 41 -2)),((54 44 7,53 42 5,56 43 4,54 44 7)),((56 43 4,53 42 5,54 41 2,56 43 4)),((54 41 -2,53 42 -5,56 43 -4,54 41 -2)),((56 43 -4,53 42 -5,54 44 -7,56 43 -4)),((53 42 -5,51 43 -7,54 44 -7,53 42 -5)),((54 44 -7,51 43 -7,52 46 -9,54 44 -7)),((51 43 -7,50 45 -9,52 46 -9,51 43 -7)),((52 46 -9,50 45 -9,50 47 -10,52 46 -9)),((52 46 -9,50 47 -10,53 48 -10,52 46 -9)),((53 48 -10,50 47 -10,50 50 -10,53 48 -10)),((50 50 -10,150 150 -10,53 48 -10,50 50 -10)),((53 48 -10,150 150 -10,147 143 -10,53 48 -10)),((147 48 -10,147 143 -10,150 50 -10,147 48 -10)),((150 50 -10,147 143 -10,150 150 -10,150 50 -10)),((150 50 -10,150 150 -10,153 48 -10,150 50 -10)),((153 48 -10,150 150 -10,153 152 -10,153 48 -10)),((153 152 -10,150 150 -10,150 153 -10,153 152 -10)),((150 150 -10,147 152 -10,150 153 -10,150 150 -10)),((153 152 -10,150 153 -10,152 154 -9,153 152 -10)),((152 154 -9,150 153 -10,150 155 -9,152 154 -9)),((152 154 -9,150 155 -9,151 157 -7,152 154 -9)),((152 154 -9,151 157 -7,154 156 -7,152 154 -9)),((154 156 -7,151 157 -7,153 158 -5,154 156 -7)),((151 157 -7,150 159 -5,153 158 -5,151 157 -7)),((153 158 -5,150 159 -5,152 160 -3,153 158 -5)),((150 159 -5,148 160 -3,152 160 -3,150 159 -5)),((152 160 -3,148 160 -3,150 160 0,152 160 -3)),((152 160 -3,150 160 0,153 160 0,152 160 -3)),((153 160 0,150 160 0,152 160 3,153 160 0)),((153 160 0,152 160 3,154 159 2,153 160 0)),((154 159 2,152 160 3,153 158 5,154 159 2)),((154 159 2,153 158 5,156 157 4,154 159 2)),((156 157 4,153 158 5,154 156 7,156 157 4)),((156 157 4,154 156 7,157 154 6,156 157 4)),((157 154 6,154 156 7,155 153 8,157 154 6)),((154 156 7,152 154 9,155 153 8,154 156 7)),((155 153 8,152 154 9,153 152 10,155 153 8)),((155 153 8,153 152 10,155 150 9,155 153 8)),((153 152 10,153 48 10,155 50 9,153 152 10)),((155 150 9,153 152 10,155 50 9,155 150 9)),((150 50 10,150 47 10,153 48 10,150 50 10)),((155 50 9,153 48 10,155 47 8,155 50 9)),((153 48 10,152 46 9,155 47 8,153 48 10)),((153 48 10,150 47 10,152 46 9,153 48 10)),((150 50 10,147 48 10,150 47 10,150 50 10)),((145 138 9,145 50 9,147 48 10,145 138 9)),((145 138 9,145 138 9,147 48 10,145 138 9)),((147 143 10,145 138 9,147 48 10,147 143 10)),((53 48 10,52 46 9,145 138 9,53 48 10)),((147 143 10,53 48 10,145 138 9,147 143 10)),((147 48 10,145 50 9,145 47 8,147 48 10)),((150 47 10,147 48 10,148 46 9,150 47 10)),((147 48 10,145 47 8,148 46 9,147 48 10)),((145 138 9,52 46 9,55 47 8,145 138 9)),((145 138 9,145 138 9,55 47 8,145 138 9)),((144 136 8,145 138 9,55 47 8,144 136 8)),((55 47 8,52 46 9,54 44 7,55 47 8)),((55 47 8,54 44 7,143 133 7,55 47 8)),((144 136 8,55 47 8,143 133 7,144 136 8)),((143 133 7,54 44 7,56 43 4,143 133 7)),((143 133 7,143 133 7,56 43 4,143 133 7)),((141 128 4,141 130 5,56 43 4,141 128 4)),((141 130 5,143 133 7,56 43 4,141 130 5)),((54 41 2,53 40 0,55 41 0,54 41 2)),((55 41 0,53 40 0,54 41 -2,55 41 0)),((56 43 4,54 41 2,57 43 1,56 43 4)),((57 43 1,54 41 2,55 41 0,57 43 1)),((55 41 0,54 41 -2,57 43 -1,55 41 0)),((57 43 -1,54 41 -2,56 43 -4,57 43 -1)),((141 128 4,56 43 4,57 43 1,141 128 4)),((140 127 3,141 128 4,57 43 1,140 127 3)),((140 126 1,140 127 3,57 43 1,140 126 1)),((57 43 -1,56 43 -4,141 128 -4,57 43 -1)),((140 126 -1,57 43 -1,140 127 -3,140 126 -1)),((140 127 -3,57 43 -1,141 128 -4,140 127 -3)),((56 43 -4,54 44 -7,143 133 -7,56 43 -4)),((141 130 -5,56 43 -4,143 133 -7,141 130 -5)),((143 133 -7,56 43 -4,143 133 -7,143 133 -7)),((141 128 -4,56 43 -4,141 130 -5,141 128 -4)),((54 44 -7,55 47 -8,143 133 -7,54 44 -7)),((143 133 -7,55 47 -8,144 136 -8,143 133 -7)),((54 44 -7,52 46 -9,55 47 -8,54 44 -7)),((52 46 -9,145 138 -9,55 47 -8,52 46 -9)),((55 47 -8,145 138 -9,145 138 -9,55 47 -8)),((55 47 -8,145 138 -9,144 136 -8,55 47 -8)),((52 46 -9,53 48 -10,145 138 -9,52 46 -9)),((145 138 -9,53 48 -10,147 143 -10,145 138 -9)),((145 50 -9,145 138 -9,147 48 -10,145 50 -9)),((147 48 -10,145 138 -9,145 138 -9,147 48 -10)),((147 48 -10,145 138 -9,147 143 -10,147 48 -10)),((150 47 -10,147 48 -10,150 50 -10,150 47 -10)),((153 48 -10,150 47 -10,150 50 -10,153 48 -10)),((145 47 -8,145 50 -9,147 48 -10,145 47 -8)),((148 46 -9,145 47 -8,147 48 -10,148 46 -9)),((148 46 -9,147 48 -10,150 47 -10,148 46 -9)),((155 47 -8,153 48 -10,155 50 -9,155 47 -8)),((153 48 -10,153 152 -10,155 50 -9,153 48 -10)),((155 50 -9,153 152 -10,155 150 -9,155 50 -9)),((152 46 -9,150 47 -10,153 48 -10,152 46 -9)),((155 47 -8,152 46 -9,153 48 -10,155 47 -8)),((155 150 -9,153 152 -10,155 153 -8,155 150 -9)),((153 152 -10,152 154 -9,155 153 -8,153 152 -10)),((155 153 -8,152 154 -9,154 156 -7,155 153 -8)),((155 153 -8,154 156 -7,157 154 -6,155 153 -8)),((157 154 -6,154 156 -7,156 157 -4,157 154 -6)),((154 156 -7,153 158 -5,156 157 -4,154 156 -7)),((156 157 -4,153 158 -5,154 159 -2,156 157 -4)),((153 158 -5,152 160 -3,154 159 -2,153 158 -5)),((154 159 -2,152 160 -3,153 160 0,154 159 -2)),((154 159 -2,153 160 0,155 159 0,154 159 -2)),((155 159 0,153 160 0,154 159 2,155 159 0)),((155 159 0,154 159 2,157 157 1,155 159 0)),((157 157 1,154 159 2,156 157 4,157 157 1)),((157 157 1,156 157 4,158 155 3,157 157 1)),((158 155 3,156 157 4,157 154 6,158 155 3)),((158 155 3,157 154 6,159 152 4,158 155 3)),((159 152 4,157 154 6,157 151 7,159 152 4)),((157 154 6,155 153 8,157 151 7,157 154 6)),((157 151 7,155 153 8,155 150 9,157 151 7)),((155 150 9,155 50 9,157 49 7,155 150 9)),((157 151 7,155 150 9,157 49 7,157 151 7)),((155 50 9,155 47 8,157 49 7,155 50 9)),((150 47 10,150 45 9,152 46 9,150 47 10)),((150 47 10,148 46 9,150 45 9,150 47 10)),((157 49 7,155 47 8,157 46 6,157 49 7)),((155 47 8,154 44 7,157 46 6,155 47 8)),((155 47 8,152 46 9,154 44 7,155 47 8)),((152 46 9,151 43 7,154 44 7,152 46 9)),((152 46 9,150 45 9,151 43 7,152 46 9)),((143 133 7,143 49 7,145 50 9,143 133 7)),((143 133 7,143 133 7,145 50 9,143 133 7)),((145 138 9,144 136 8,145 50 9,145 138 9)),((144 136 8,143 133 7,145 50 9,144 136 8)),((145 50 9,143 49 7,145 47 8,145 50 9)),((145 47 8,143 49 7,143 46 6,145 47 8)),((148 46 9,145 47 8,146 44 7,148 46 9)),((145 47 8,143 46 6,146 44 7,145 47 8)),((150 45 9,148 46 9,149 43 7,150 45 9)),((148 46 9,146 44 7,149 43 7,148 46 9)),((141 50 5,143 49 7,141 130 5,141 50 5)),((141 130 5,143 49 7,143 133 7,141 130 5)),((140 50 3,141 50 5,140 127 3,140 50 3)),((141 128 4,141 50 5,141 130 5,141 128 4)),((140 127 3,141 50 5,141 128 4,140 127 3)),((57 43 1,55 41 0,57 43 -1,57 43 1)),((57 43 1,57 43 -1,140 126 -1,57 43 1)),((140 126 1,57 43 1,140 126 0,140 126 1)),((140 126 0,57 43 1,140 126 -1,140 126 0)),((140 50 0,140 50 3,140 126 0,140 50 0)),((140 126 1,140 50 3,140 127 3,140 126 1)),((140 126 0,140 50 3,140 126 1,140 126 0)),((140 50 0,140 126 0,140 50 -3,140 50 0)),((140 50 -3,140 126 0,140 126 -1,140 50 -3)),((140 50 -3,140 126 -1,140 127 -3,140 50 -3)),((140 50 -3,140 127 -3,141 50 -5,140 50 -3)),((141 50 -5,140 127 -3,141 128 -4,141 50 -5)),((141 50 -5,141 128 -4,141 130 -5,141 50 -5)),((141 50 -5,141 130 -5,143 49 -7,141 50 -5)),((143 49 -7,141 130 -5,143 133 -7,143 49 -7)),((143 49 -7,143 133 -7,145 50 -9,143 49 -7)),((145 50 -9,143 133 -7,143 133 -7,145 50 -9)),((145 50 -9,143 133 -7,144 136 -8,145 50 -9)),((144 136 -8,145 138 -9,145 50 -9,144 136 -8)),((145 47 -8,143 49 -7,145 50 -9,145 47 -8)),((150 45 -9,148 46 -9,150 47 -10,150 45 -9)),((152 46 -9,150 45 -9,150 47 -10,152 46 -9)),((143 46 -6,143 49 -7,145 47 -8,143 46 -6)),((146 44 -7,143 46 -6,145 47 -8,146 44 -7)),((146 44 -7,145 47 -8,148 46 -9,146 44 -7)),((149 43 -7,146 44 -7,148 46 -9,149 43 -7)),((149 43 -7,148 46 -9,150 45 -9,149 43 -7)),((157 46 -6,155 47 -8,157 49 -7,157 46 -6)),((157 49 -7,155 47 -8,155 50 -9,157 49 -7)),((154 44 -7,152 46 -9,155 47 -8,154 44 -7)),((157 46 -6,154 44 -7,155 47 -8,157 46 -6)),((155 50 -9,155 150 -9,157 49 -7,155 50 -9)),((157 49 -7,155 150 -9,157 151 -7,157 49 -7)),((155 150 -9,155 153 -8,157 151 -7,155 150 -9)),((151 43 -7,150 45 -9,152 46 -9,151 43 -7)),((154 44 -7,151 43 -7,152 46 -9,154 44 -7)),((157 151 -7,155 153 -8,157 154 -6,157 151 -7)),((157 151 -7,157 154 -6,159 152 -4,157 151 -7)),((159 152 -4,157 154 -6,158 155 -3,159 152 -4)),((157 154 -6,156 157 -4,158 155 -3,157 154 -6)),((158 155 -3,156 157 -4,157 157 -1,158 155 -3)),((156 157 -4,154 159 -2,157 157 -1,156 157 -4)),((157 157 -1,154 159 -2,155 159 0,157 157 -1)),((157 157 -1,155 159 0,157 157 1,157 157 -1)),((159 155 0,157 157 -1,157 157 1,159 155 0)),((159 155 0,157 157 1,158 155 3,159 155 0)),((159 155 0,158 155 3,160 153 2,159 155 0)),((160 153 2,158 155 3,159 152 4,160 153 2)),((160 153 2,159 152 4,160 150 3,160 153 2)),((159 152 4,159 150 5,160 150 3,159 152 4)),((159 152 4,157 151 7,159 150 5,159 152 4)),((157 151 7,157 49 7,159 50 5,157 151 7)),((159 150 5,157 151 7,159 50 5,159 150 5)),((159 50 5,157 49 7,159 48 4,159 50 5)),((157 49 7,157 46 6,159 48 4,157 49 7)),((150 45 9,149 43 7,151 43 7,150 45 9)),((159 48 4,157 46 6,158 45 3,159 48 4)),((157 46 6,156 43 4,158 45 3,157 46 6)),((157 46 6,154 44 7,156 43 4,157 46 6)),((154 44 7,153 42 5,156 43 4,154 44 7)),((154 44 7,151 43 7,153 42 5,154 44 7)),((151 43 7,149 43 7,150 41 5,151 43 7)),((151 43 7,150 41 5,153 42 5,151 43 7)),((141 50 5,141 48 4,143 49 7,141 50 5)),((143 49 7,141 48 4,143 46 6,143 49 7)),((143 46 6,141 48 4,142 45 3,143 46 6)),((146 44 7,143 46 6,144 43 4,146 44 7)),((143 46 6,142 45 3,144 43 4,143 46 6)),((149 43 7,146 44 7,147 42 5,149 43 7)),((146 44 7,144 43 4,147 42 5,146 44 7)),((149 43 7,147 42 5,150 41 5,149 43 7)),((141 50 5,140 50 3,141 48 4,141 50 5)),((140 50 3,140 50 0,140 47 2,140 50 3)),((141 48 4,140 50 3,140 47 2,141 48 4)),((140 47 2,140 50 0,140 47 -2,140 47 2)),((140 47 -2,140 50 0,140 50 -3,140 47 -2)),((141 48 -4,140 50 -3,141 50 -5,141 48 -4)),((140 47 -2,140 50 -3,141 48 -4,140 47 -2)),((143 49 -7,141 48 -4,141 50 -5,143 49 -7)),((143 46 -6,141 48 -4,143 49 -7,143 46 -6)),((151 43 -7,149 43 -7,150 45 -9,151 43 -7)),((142 45 -3,141 48 -4,143 46 -6,142 45 -3)),((144 43 -4,142 45 -3,143 46 -6,144 43 -4)),((144 43 -4,143 46 -6,146 44 -7,144 43 -4)),((147 42 -5,144 43 -4,146 44 -7,147 42 -5)),((147 42 -5,146 44 -7,149 43 -7,147 42 -5)),((150 41 -5,149 43 -7,151 43 -7,150 41 -5)),((150 41 -5,147 42 -5,149 43 -7,150 41 -5)),((158 45 -3,157 46 -6,159 48 -4,158 45 -3)),((159 48 -4,157 46 -6,157 49 -7,159 48 -4)),((156 43 -4,154 44 -7,157 46 -6,156 43 -4)),((158 45 -3,156 43 -4,157 46 -6,158 45 -3)),((159 48 -4,157 49 -7,159 50 -5,159 48 -4)),((159 50 -5,157 49 -7,157 151 -7,159 50 -5)),((159 150 -5,159 50 -5,157 151 -7,159 150 -5)),((153 42 -5,151 43 -7,154 44 -7,153 42 -5)),((156 43 -4,153 42 -5,154 44 -7,156 43 -4)),((159 150 -5,157 151 -7,159 152 -4,159 150 -5)),((153 42 -5,150 41 -5,151 43 -7,153 42 -5)),((160 150 -3,159 150 -5,159 152 -4,160 150 -3)),((160 150 -3,159 152 -4,160 153 -2,160 150 -3)),((159 152 -4,158 155 -3,160 153 -2,159 152 -4)),((160 153 -2,158 155 -3,159 155 0,160 153 -2)),((158 155 -3,157 157 -1,159 155 0,158 155 -3)),((160 153 -2,159 155 0,160 153 2,160 153 -2)),((160 150 0,160 153 -2,160 153 2,160 150 0)),((160 150 0,160 153 2,160 150 3,160 150 0)),((159 150 5,159 50 5,160 50 3,159 150 5)),((160 150 3,159 150 5,160 50 3,160 150 3)),((160 150 3,160 50 3,160 50 0,160 150 3)),((160 150 0,160 150 3,160 50 0,160 150 0)),((160 50 3,159 50 5,159 48 4,160 50 3)),((160 50 3,159 48 4,160 47 2,160 50 3)),((159 48 4,158 45 3,160 47 2,159 48 4)),((160 47 2,158 45 3,159 45 0,160 47 2)),((158 45 3,157 43 1,159 45 0,158 45 3)),((158 45 3,156 43 4,157 43 1,158 45 3)),((156 43 4,154 41 2,157 43 1,156 43 4)),((156 43 4,153 42 5,154 41 2,156 43 4)),((153 42 5,152 40 3,154 41 2,153 42 5)),((153 42 5,150 41 5,152 40 3,153 42 5)),((150 41 5,147 42 5,148 40 3,150 41 5)),((150 41 5,148 40 3,152 40 3,150 41 5)),((141 48 4,140 47 2,142 45 3,141 48 4)),((142 45 3,140 47 2,141 45 0,142 45 3)),((144 43 4,142 45 3,143 43 1,144 43 4)),((142 45 3,141 45 0,143 43 1,142 45 3)),((147 42 5,144 43 4,146 41 2,147 42 5)),((144 43 4,143 43 1,146 41 2,144 43 4)),((147 42 5,146 41 2,148 40 3,147 42 5)),((140 47 2,140 47 -2,141 45 0,140 47 2)),((141 45 0,140 47 -2,142 45 -3,141 45 0)),((142 45 -3,140 47 -2,141 48 -4,142 45 -3)),((143 43 -1,141 45 0,142 45 -3,143 43 -1)),((143 43 -1,142 45 -3,144 43 -4,143 43 -1)),((146 41 -2,143 43 -1,144 43 -4,146 41 -2)),((146 41 -2,144 43 -4,147 42 -5,146 41 -2)),((148 40 -3,146 41 -2,147 42 -5,148 40 -3)),((148 40 -3,147 42 -5,150 41 -5,148 40 -3)),((152 40 -3,150 41 -5,153 42 -5,152 40 -3)),((152 40 -3,148 40 -3,150 41 -5,152 40 -3)),((159 45 0,158 45 -3,160 47 -2,159 45 0)),((160 47 -2,158 45 -3,159 48 -4,160 47 -2)),((157 43 -1,156 43 -4,158 45 -3,157 43 -1)),((159 45 0,157 43 -1,158 45 -3,159 45 0)),((160 47 -2,159 48 -4,160 50 -3,160 47 -2)),((159 48 -4,159 50 -5,160 50 -3,159 48 -4)),((154 41 -2,153 42 -5,156 43 -4,154 41 -2)),((157 43 -1,154 41 -2,156 43 -4,157 43 -1)),((160 50 -3,159 50 -5,159 150 -5,160 50 -3)),((160 150 -3,160 50 -3,159 150 -5,160 150 -3)),((154 41 -2,152 40 -3,153 42 -5,154 41 -2)),((160 50 0,160 50 -3,160 150 -3,160 50 0)),((160 150 0,160 50 0,160 150 -3,160 150 0)),((160 150 -3,160 153 -2,160 150 0,160 150 -3)),((160 50 3,160 47 2,160 50 0,160 50 3)),((160 50 0,160 47 -2,160 50 -3,160 50 0)),((160 47 2,160 47 -2,160 50 0,160 47 2)),((160 47 2,159 45 0,160 47 -2,160 47 2)),((157 43 1,157 43 -1,159 45 0,157 43 1)),((157 43 1,155 41 0,157 43 -1,157 43 1)),((157 43 1,154 41 2,155 41 0,157 43 1)),((154 41 2,153 40 0,155 41 0,154 41 2)),((154 41 2,152 40 3,153 40 0,154 41 2)),((152 40 3,148 40 3,150 40 0,152 40 3)),((152 40 3,150 40 0,153 40 0,152 40 3)),((148 40 3,146 41 2,147 40 0,148 40 3)),((148 40 3,147 40 0,150 40 0,148 40 3)),((143 43 1,141 45 0,143 43 -1,143 43 1)),((143 43 1,143 43 -1,145 41 0,143 43 1)),((146 41 2,143 43 1,145 41 0,146 41 2)),((146 41 2,145 41 0,147 40 0,146 41 2)),((145 41 0,143 43 -1,146 41 -2,145 41 0)),((147 40 0,145 41 0,146 41 -2,147 40 0)),((147 40 0,146 41 -2,148 40 -3,147 40 0)),((150 40 0,148 40 -3,152 40 -3,150 40 0)),((150 40 0,147 40 0,148 40 -3,150 40 0)),((153 40 0,152 40 -3,154 41 -2,153 40 0)),((153 40 0,150 40 0,152 40 -3,153 40 0)),((155 41 0,154 41 -2,157 43 -1,155 41 0)),((155 41 0,153 40 0,154 41 -2,155 41 0)))</screen>

       <para>A square buffer around the same line using 32 segments.</para>
       <programlisting language="sql" role="documented-output">SELECT
  'LINESTRING(50 50,150 150,150 50)'::geometry AS input_geometry,
  CG_3DBuffer('LINESTRING(50 50,150 150,150 50)'::geometry, 10, 32, 2) AS buffer;</programlisting>
<screen role="visual-primary geometry-output-precision-0">LINESTRING(50 50,150 150,150 50) | POLYHEDRALSURFACE Z (((50 36 0,50 36 -2,140 126 -2,140 126 0,50 36 0)),((140 126 -2,50 36 -2,49 36 -4,141 128 -4,140 126 -2)),((141 128 -4,49 36 -4,49 37 -6,142 130 -6,141 128 -4)),((142 130 -6,49 37 -6,48 38 -7,143 133 -7,142 130 -6)),((143 133 -7,48 38 -7,47 39 -8,144 137 -8,143 133 -7)),((144 137 -8,47 39 -8,46 40 -9,146 141 -9,144 137 -8)),((146 141 -9,46 40 -9,44 42 -10,148 145 -10,146 141 -9)),((148 145 -10,44 42 -10,43 43 -10,150 150 -10,148 145 -10)),((150 150 -10,43 43 -10,42 44 -10,152 155 -10,150 150 -10)),((152 155 -10,42 44 -10,40 46 -9,154 159 -9,152 155 -10)),((154 159 -9,40 46 -9,39 47 -8,156 163 -8,154 159 -9)),((156 163 -8,39 47 -8,38 48 -7,157 167 -7,156 163 -8)),((157 167 -7,38 48 -7,37 49 -6,158 170 -6,157 167 -7)),((158 170 -6,37 49 -6,36 49 -4,159 172 -4,158 170 -6)),((159 172 -4,36 49 -4,36 50 -2,160 174 -2,159 172 -4)),((160 174 -2,36 50 -2,36 50 -1e-15,160 174 -1e-15,160 174 -2)),((160 174 -1e-15,36 50 -1e-15,36 50 2,160 174 2,160 174 -1e-15)),((160 174 2,36 50 2,36 49 4,159 172 4,160 174 2)),((159 172 4,36 49 4,37 49 6,158 170 6,159 172 4)),((158 170 6,37 49 6,38 48 7,157 167 7,158 170 6)),((157 167 7,38 48 7,39 47 8,156 163 8,157 167 7)),((156 163 8,39 47 8,40 46 9,154 159 9,156 163 8)),((154 159 9,40 46 9,42 44 10,152 155 10,154 159 9)),((152 155 10,42 44 10,43 43 10,150 150 10,152 155 10)),((150 150 10,43 43 10,44 42 10,148 145 10,150 150 10)),((148 145 10,44 42 10,46 40 9,146 141 9,148 145 10)),((146 141 9,46 40 9,47 39 8,144 137 8,146 141 9)),((144 137 8,47 39 8,48 38 7,143 133 7,144 137 8)),((143 133 7,48 38 7,49 37 6,142 130 6,143 133 7)),((142 130 6,49 37 6,49 36 4,141 128 4,142 130 6)),((141 128 4,49 36 4,50 36 2,140 126 2,141 128 4)),((50 36 0,140 126 0,140 126 2,50 36 2,50 36 0)),((140 126 0,140 126 -2,140 40 -2,140 40 0,140 126 0)),((140 40 -2,140 126 -2,141 128 -4,141 40 -4,140 40 -2)),((141 40 -4,141 128 -4,142 130 -6,142 40 -6,141 40 -4)),((142 40 -6,142 130 -6,143 133 -7,143 40 -7,142 40 -6)),((143 40 -7,143 133 -7,144 137 -8,144 40 -8,143 40 -7)),((144 40 -8,144 137 -8,146 141 -9,146 40 -9,144 40 -8)),((146 40 -9,146 141 -9,148 145 -10,148 40 -10,146 40 -9)),((148 40 -10,148 145 -10,150 150 -10,150 40 -10,148 40 -10)),((150 40 -10,150 150 -10,152 155 -10,152 40 -10,150 40 -10)),((152 40 -10,152 155 -10,154 159 -9,154 40 -9,152 40 -10)),((154 40 -9,154 159 -9,156 163 -8,156 40 -8,154 40 -9)),((156 40 -8,156 163 -8,157 167 -7,157 40 -7,156 40 -8)),((157 40 -7,157 167 -7,158 170 -6,158 40 -6,157 40 -7)),((158 40 -6,158 170 -6,159 172 -4,159 40 -4,158 40 -6)),((159 40 -4,159 172 -4,160 174 -2,160 40 -2,159 40 -4)),((160 40 -2,160 174 -2,160 174 -1e-15,160 40 -1e-15,160 40 -2)),((160 40 -1e-15,160 174 -1e-15,160 174 2,160 40 2,160 40 -1e-15)),((160 40 2,160 174 2,159 172 4,159 40 4,160 40 2)),((159 40 4,159 172 4,158 170 6,158 40 6,159 40 4)),((158 40 6,158 170 6,157 167 7,157 40 7,158 40 6)),((157 40 7,157 167 7,156 163 8,156 40 8,157 40 7)),((156 40 8,156 163 8,154 159 9,154 40 9,156 40 8)),((154 40 9,154 159 9,152 155 10,152 40 10,154 40 9)),((152 40 10,152 155 10,150 150 10,150 40 10,152 40 10)),((150 40 10,150 150 10,148 145 10,148 40 10,150 40 10)),((148 40 10,148 145 10,146 141 9,146 40 9,148 40 10)),((146 40 9,146 141 9,144 137 8,144 40 8,146 40 9)),((144 40 8,144 137 8,143 133 7,143 40 7,144 40 8)),((143 40 7,143 133 7,142 130 6,142 40 6,143 40 7)),((142 40 6,142 130 6,141 128 4,141 40 4,142 40 6)),((141 40 4,141 128 4,140 126 2,140 40 2,141 40 4)),((140 126 0,140 40 0,140 40 2,140 126 2,140 126 0)),((50 36 -2,50 36 0,50 36 2,49 36 4,49 37 6,48 38 7,47 39 8,46 40 9,44 42 10,43 43 10,42 44 10,40 46 9,39 47 8,38 48 7,37 49 6,36 49 4,36 50 2,36 50 -1e-15,36 50 -2,36 49 -4,37 49 -6,38 48 -7,39 47 -8,40 46 -9,42 44 -10,43 43 -10,44 42 -10,46 40 -9,47 39 -8,48 38 -7,49 37 -6,49 36 -4,50 36 -2)),((140 40 0,140 40 -2,141 40 -4,142 40 -6,143 40 -7,144 40 -8,146 40 -9,148 40 -10,150 40 -10,152 40 -10,154 40 -9,156 40 -8,157 40 -7,158 40 -6,159 40 -4,160 40 -2,160 40 -1e-15,160 40 2,159 40 4,158 40 6,157 40 7,156 40 8,154 40 9,152 40 10,150 40 10,148 40 10,146 40 9,144 40 8,143 40 7,142 40 6,141 40 4,140 40 2,140 40 0)))</screen>
   </refsection>
   <refsection>
       <title>See Also</title>
        <para><xref linkend="ST_Buffer"/>, <xref linkend="CG_3DConvexHull"/>, <xref linkend="ST_AsX3D" /></para>
   </refsection>
</refentry>

<refentry xml:id="CG_Rotate">
   <refnamediv>
       <refname>CG_Rotate</refname>
       <refpurpose>Rotates a geometry by a given angle around the origin (0,0).</refpurpose>
   </refnamediv>
   <refsynopsisdiv>
       <funcsynopsis>
           <funcprototype>
               <funcdef>geometry <function>CG_Rotate</function></funcdef>
               <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>angle</parameter></paramdef>
           </funcprototype>
       </funcsynopsis>
   </refsynopsisdiv>
   <refsection>
       <title>Description</title>
       <para>Rotates the input geometry <parameter>geom</parameter> by <parameter>angle</parameter> radians around the origin point (0,0).
       The rotation is performed in 2D space; Z coordinates are not modified.
       Positive angles rotate the geometry counter-clockwise.</para>
       <para role="availability" conformance="3.6.0">Availability: 3.6.0 - requires SFCGAL &gt;= 2.0.0</para>
       <para>&sfcgal_required;</para>
   </refsection>
   <refsection>
       <title>Examples</title>
       <programlisting language="sql">SELECT CG_Rotate('LINESTRING(1 0,0 1)', pi()/2);</programlisting>
<screen role="visual-primary text-primary">LINESTRING(6.123233995736766e-17 1,-1 6.123233995736766e-17)</screen>
   </refsection>
   <refsection>
       <title>See Also</title>
       <para><xref linkend="CG_2DRotate"/>, <xref linkend="ST_Rotate"/></para>
   </refsection>
</refentry>

<refentry xml:id="CG_2DRotate">
   <refnamediv>
       <refname>CG_2DRotate</refname>
       <refpurpose>Rotates a geometry by a given angle around a specified point in 2D.</refpurpose>
   </refnamediv>
   <refsynopsisdiv>
       <funcsynopsis>
           <funcprototype>
               <funcdef>geometry <function>CG_2DRotate</function></funcdef>
               <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>angle</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>cx</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>cy</parameter></paramdef>
           </funcprototype>
       </funcsynopsis>
   </refsynopsisdiv>
   <refsection>
       <title>Description</title>
       <para>Rotates the input geometry <parameter>geom</parameter> by <parameter>angle</parameter> radians around the point (<parameter>cx</parameter>, <parameter>cy</parameter>).
       The rotation is performed in 2D space; Z coordinates are dropped.
       Positive angles rotate the geometry counter-clockwise.</para>
       <para role="availability" conformance="3.6.0">Availability: 3.6.0 - requires SFCGAL &gt;= 2.0.0</para>
       <para>&sfcgal_required;</para>
   </refsection>
   <refsection>
       <title>Examples</title>
       <programlisting language="sql">SELECT CG_2DRotate('POINT(1 0)', pi()/2, 1, 1);</programlisting>
<screen role="visual-primary text-primary">POINT(2 1)</screen>
   </refsection>
   <refsection>
       <title>See Also</title>
       <para><xref linkend="CG_Rotate"/>, <xref linkend="CG_3DRotate"/></para>
   </refsection>
</refentry>

<refentry xml:id="CG_3DRotate">
   <refnamediv>
       <refname>CG_3DRotate</refname>
       <refpurpose>Rotates a geometry in 3D space around an axis vector.</refpurpose>
   </refnamediv>
   <refsynopsisdiv>
       <funcsynopsis>
           <funcprototype>
               <funcdef>geometry <function>CG_3DRotate</function></funcdef>
               <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>angle</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>ax</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>ay</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>az</parameter></paramdef>
           </funcprototype>
       </funcsynopsis>
   </refsynopsisdiv>
   <refsection>
       <title>Description</title>
       <para>Rotates the input geometry <parameter>geom</parameter> by <parameter>angle</parameter> radians around an axis defined by the vector (<parameter>ax</parameter>, <parameter>ay</parameter>, <parameter>az</parameter>) passing through the origin (0,0,0).
       </para>
       <para role="availability" conformance="3.6.0">Availability: 3.6.0 - requires SFCGAL &gt;= 2.0.0</para>
       <para>&sfcgal_required;</para>
       <para>&Z_support;</para>
   </refsection>
   <refsection>
       <title>Examples</title>
       <programlisting language="sql">SELECT CG_3DRotate('POINT(1 0 0)', pi()/2, 0, 0, 1);</programlisting>
<screen role="visual-primary text-primary">POINT Z (6.123233995736766e-17 1 0)</screen>
   </refsection>
   <refsection>
       <title>See Also</title>
       <para><xref linkend="CG_RotateX"/>, <xref linkend="CG_RotateY"/>, <xref linkend="CG_RotateZ"/></para>
   </refsection>
</refentry>

<refentry xml:id="CG_RotateX">
   <refnamediv>
       <refname>CG_RotateX</refname>
       <refpurpose>Rotates a geometry around the X-axis by a given angle.</refpurpose>
   </refnamediv>
   <refsynopsisdiv>
       <funcsynopsis>
           <funcprototype>
               <funcdef>geometry <function>CG_RotateX</function></funcdef>
               <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>angle</parameter></paramdef>
           </funcprototype>
       </funcsynopsis>
   </refsynopsisdiv>
   <refsection>
       <title>Description</title>
       <para>Rotates the input geometry <parameter>geom</parameter> by <parameter>angle</parameter> radians around the X-axis.
       </para>
       <para role="availability" conformance="3.6.0">Availability: 3.6.0 - requires SFCGAL &gt;= 2.0.0</para>
       <para>&sfcgal_required;</para>
       <para>&Z_support;</para>
   </refsection>
   <refsection>
       <title>Examples</title>
       <programlisting language="sql">SELECT CG_RotateX('POINT(0 1 0)', pi()/2);</programlisting>
<screen role="visual-primary text-primary">POINT Z (0 6.123233995736766e-17 1)</screen>
   </refsection>
   <refsection>
       <title>See Also</title>
       <para><xref linkend="CG_RotateY"/>, <xref linkend="CG_RotateZ"/>, <xref linkend="CG_3DRotate"/></para>
   </refsection>
</refentry>

<refentry xml:id="CG_RotateY">
   <refnamediv>
       <refname>CG_RotateY</refname>
       <refpurpose>Rotates a geometry around the Y-axis by a given angle.</refpurpose>
   </refnamediv>
   <refsynopsisdiv>
       <funcsynopsis>
           <funcprototype>
               <funcdef>geometry <function>CG_RotateY</function></funcdef>
               <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>angle</parameter></paramdef>
           </funcprototype>
       </funcsynopsis>
   </refsynopsisdiv>
   <refsection>
       <title>Description</title>
       <para>Rotates the input geometry <parameter>geom</parameter> by <parameter>angle</parameter> radians around the Y-axis passing.
       </para>
       <para role="availability" conformance="3.6.0">Availability: 3.6.0 - requires SFCGAL &gt;= 2.0.0</para>
       <para>&sfcgal_required;</para>
       <para>&Z_support;</para>
   </refsection>
   <refsection>
       <title>Examples</title>
       <programlisting language="sql">SELECT CG_RotateY('POINT(1 0 0)', pi()/2);</programlisting>
<screen role="visual-primary text-primary">POINT Z (6.123233995736766e-17 0 -1)</screen>
   </refsection>
   <refsection>
       <title>See Also</title>
       <para><xref linkend="CG_RotateX"/>, <xref linkend="CG_RotateZ"/>, <xref linkend="CG_3DRotate"/></para>
   </refsection>
</refentry>

<refentry xml:id="CG_RotateZ">
   <refnamediv>
       <refname>CG_RotateZ</refname>
       <refpurpose>Rotates a geometry around the Z-axis by a given angle.</refpurpose>
   </refnamediv>
   <refsynopsisdiv>
       <funcsynopsis>
           <funcprototype>
               <funcdef>geometry <function>CG_RotateZ</function></funcdef>
               <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>angle</parameter></paramdef>
           </funcprototype>
       </funcsynopsis>
   </refsynopsisdiv>
   <refsection>
       <title>Description</title>
       <para>Rotates the input geometry <parameter>geom</parameter> by <parameter>angle</parameter> radians around the Z-axis.
       </para>
       <para role="availability" conformance="3.6.0">Availability: 3.6.0 - requires SFCGAL &gt;= 2.0.0</para>
       <para>&sfcgal_required;</para>
       <para>&Z_support;</para>
   </refsection>
   <refsection>
       <title>Examples</title>
       <programlisting language="sql">SELECT CG_RotateZ('POINT(1 0 0)', pi()/2);</programlisting>
<screen role="visual-primary text-primary">POINT Z (6.123233995736766e-17 1 0)</screen>
   </refsection>
   <refsection>
       <title>See Also</title>
       <para><xref linkend="CG_RotateX"/>, <xref linkend="CG_RotateY"/>, <xref linkend="CG_3DRotate"/></para>
   </refsection>
</refentry>

<refentry xml:id="CG_Scale">
   <refnamediv>
       <refname>CG_Scale</refname>
       <refpurpose>Scales a geometry uniformly in all dimensions by a given factor.</refpurpose>
   </refnamediv>
   <refsynopsisdiv>
       <funcsynopsis>
           <funcprototype>
               <funcdef>geometry <function>CG_Scale</function></funcdef>
               <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>factor</parameter></paramdef>
           </funcprototype>
       </funcsynopsis>
   </refsynopsisdiv>
   <refsection>
       <title>Description</title>
       <para>Scales the input geometry <parameter>geom</parameter> by a uniform scale <parameter>factor</parameter> in all dimensions (X, Y, and Z).
       The scaling is performed relative to the origin point (0,0,0).</para>
       <para role="availability" conformance="3.6.0">Availability: 3.6.0 - requires SFCGAL &gt;= 2.0.0</para>
       <para>&sfcgal_required;</para>
   </refsection>
   <refsection>
       <title>Examples</title>
       <programlisting language="sql">SELECT CG_Scale('LINESTRING(1 1,2 2)', 2);</programlisting>
<screen role="visual-primary text-primary">LINESTRING(2 2,4 4)</screen>
   </refsection>
   <refsection>
       <title>See Also</title>
       <para><xref linkend="CG_3DScale"/>, <xref linkend="CG_3DScaleAroundCenter"/>, <xref linkend="ST_Scale"/></para>
   </refsection>
</refentry>

<refentry xml:id="CG_3DScale">
   <refnamediv>
       <refname>CG_3DScale</refname>
       <refpurpose>Scales a geometry by separate factors along X, Y, and Z axes.</refpurpose>
   </refnamediv>
   <refsynopsisdiv>
       <funcsynopsis>
           <funcprototype>
               <funcdef>geometry <function>CG_3DScale</function></funcdef>
               <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>factorX</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>factorY</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>factorZ</parameter></paramdef>
           </funcprototype>
       </funcsynopsis>
   </refsynopsisdiv>
   <refsection>
       <title>Description</title>
       <para>Scales the input geometry <parameter>geom</parameter> by different factors along the X, Y, and Z axes.
       The scaling is performed relative to the origin point (0,0,0).</para>
       <para role="availability" conformance="3.6.0">Availability: 3.6.0 - requires SFCGAL &gt;= 2.0.0</para>
       <para>&sfcgal_required;</para>
       <para>&Z_support;</para>
   </refsection>
   <refsection>
       <title>Examples</title>
       <programlisting language="sql">SELECT CG_3DScale('POINT(1 1 1)', 2, 3, 4);</programlisting>
<screen role="visual-primary text-primary">POINT Z (2 3 4)</screen>
   </refsection>
   <refsection>
       <title>See Also</title>
       <para><xref linkend="CG_Scale"/>, <xref linkend="CG_3DScaleAroundCenter"/></para>
   </refsection>
</refentry>

<refentry xml:id="CG_3DScaleAroundCenter">
   <refnamediv>
       <refname>CG_3DScaleAroundCenter</refname>
       <refpurpose>Scales a geometry in 3D space around a specified center point.</refpurpose>
   </refnamediv>
   <refsynopsisdiv>
       <funcsynopsis>
           <funcprototype>
               <funcdef>geometry <function>CG_3DScaleAroundCenter</function></funcdef>
               <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>factorX</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>factorY</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>factorZ</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>centerX</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>centerY</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>centerZ</parameter></paramdef>
           </funcprototype>
       </funcsynopsis>
   </refsynopsisdiv>
   <refsection>
       <title>Description</title>
       <para>Scales the input geometry <parameter>geom</parameter> by different factors along the X, Y, and Z axes, relative to a specified center point (<parameter>centerX</parameter>, <parameter>centerY</parameter>, <parameter>centerZ</parameter>).</para>
       <para role="availability" conformance="3.6.0">Availability: 3.6.0 - requires SFCGAL &gt;= 2.0.0</para>
       <para>&sfcgal_required;</para>
       <para>&Z_support;</para>
   </refsection>
   <refsection>
       <title>Examples</title>
       <programlisting language="sql">SELECT CG_3DScaleAroundCenter('POINT(2 2 2)', 0.5, 0.5, 0.5, 1, 1, 1);</programlisting>
<screen role="visual-primary text-primary">POINT Z (1.5 1.5 1.5)</screen>
   </refsection>
   <refsection>
       <title>See Also</title>
       <para><xref linkend="CG_Scale"/>, <xref linkend="CG_3DScale"/></para>
   </refsection>
</refentry>

<refentry xml:id="CG_Translate">
   <refnamediv>
       <refname>CG_Translate</refname>
       <refpurpose>Translates (moves) a geometry by given offsets in 2D space.</refpurpose>
   </refnamediv>
   <refsynopsisdiv>
       <funcsynopsis>
           <funcprototype>
               <funcdef>geometry <function>CG_Translate</function></funcdef>
               <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>deltaX</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>deltaY</parameter></paramdef>
           </funcprototype>
       </funcsynopsis>
   </refsynopsisdiv>
   <refsection>
       <title>Description</title>
       <para>Translates the input geometry <parameter>geom</parameter> by adding <parameter>deltaX</parameter> to the X coordinates and <parameter>deltaY</parameter> to the Y coordinates.
       Z coordinates are dropped.</para>
       <para role="availability" conformance="3.6.0">Availability: 3.6.0 - requires SFCGAL &gt;= 2.0.0</para>
       <para>&sfcgal_required;</para>
   </refsection>
   <refsection>
       <title>Examples</title>
       <programlisting language="sql">SELECT CG_Translate('LINESTRING(1 1,2 2)', 1, -1);</programlisting>
<screen role="visual-primary text-primary">LINESTRING(2 0,3 1)</screen>
   </refsection>
   <refsection>
       <title>See Also</title>
       <para><xref linkend="CG_3DTranslate"/>, <xref linkend="ST_Translate"/></para>
   </refsection>
</refentry>

<refentry xml:id="CG_3DTranslate">
   <refnamediv>
       <refname>CG_3DTranslate</refname>
       <refpurpose>Translates (moves) a geometry by given offsets in 3D space.</refpurpose>
   </refnamediv>
   <refsynopsisdiv>
       <funcsynopsis>
           <funcprototype>
               <funcdef>geometry <function>CG_3DTranslate</function></funcdef>
               <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>deltaX</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>deltaY</parameter></paramdef>
               <paramdef><type>float8</type> <parameter>deltaZ</parameter></paramdef>
           </funcprototype>
       </funcsynopsis>
   </refsynopsisdiv>
   <refsection>
       <title>Description</title>
       <para>Translates the input geometry <parameter>geom</parameter> by adding <parameter>deltaX</parameter> to the X coordinates, <parameter>deltaY</parameter> to the Y coordinates, and <parameter>deltaZ</parameter> to the Z coordinates.</para>
       <para role="availability" conformance="3.6.0">Availability: 3.6.0 - requires SFCGAL &gt;= 2.0.0</para>
       <para>&sfcgal_required;</para>
       <para>&Z_support;</para>
   </refsection>
   <refsection>
       <title>Examples</title>
       <programlisting language="sql">SELECT CG_3DTranslate('POINT(1 1 1)', 1, -1, 2);</programlisting>
<screen role="visual-primary text-primary">POINT Z (2 0 3)</screen>
   </refsection>
   <refsection>
       <title>See Also</title>
       <para><xref linkend="CG_Translate"/>, <xref linkend="ST_Translate"/></para>
   </refsection>
</refentry>

<refentry xml:id="CG_Simplify">
  <refnamediv>
    <refname>CG_Simplify</refname>
    <refpurpose>Reduces the complexity of a geometry while preserving essential features and Z/M values.</refpurpose>
  </refnamediv>

  <refsynopsisdiv>
    <funcsynopsis>
      <funcprototype>
        <funcdef>geometry <function>CG_Simplify</function></funcdef>
        <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
        <paramdef><type>double precision</type> <parameter>threshold</parameter></paramdef>
        <paramdef choice="opt"><type>boolean</type> <parameter>preserveTopology = false</parameter></paramdef>
      </funcprototype>
    </funcsynopsis>
  </refsynopsisdiv>

  <refsection>
    <title>Description</title>
    <para>
      Simplifies a geometry using SFCGAL's simplification algorithm, which reduces the number of points or vertices while preserving the essential features of the geometry. This function preserves Z and M values during simplification.
    </para>
    <para>
      The algorithm is based on constrained triangulation and uses the <link xlink:href="https://doc.cgal.org/latest/Polyline_simplification_2/index.html">CGAL Polyline Simplification 2</link> library with additional handling to preserve Z and M coordinates.
      When topology is preserved and geometries intersect, Z and M values are interpolated at intersection points.
    </para>
    <para>
      This function works well with 3D terrain-like geometries (2.5D) but is not designed for vertical surfaces like walls.
    </para>
    <para role="availability" conformance="3.6.0">Availability: 3.6.0 - requires SFCGAL &gt;= 2.1.0</para>
    <para>&sfcgal_required;</para>
    <para>&Z_support;</para>
    <para>&M_support;</para>
  </refsection>

  <refsection>
    <title>Parameters</title>
    <variablelist>
      <varlistentry>
        <term><parameter>geom</parameter></term>
        <listitem>
          <para>Input geometry</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><parameter>threshold</parameter></term>
        <listitem>
          <para>Maximum distance threshold (in geometry unit) for simplification. The higher this value, the more simplified the resulting geometry will be.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><parameter>preserveTopology</parameter></term>
        <listitem>
          <para>If set to true, the function ensures that the topology of the geometry is preserved. When geometries intersect in this mode, Z and M values at intersection points are interpolated. The default value is false.</para>
        </listitem>
      </varlistentry>
    </variablelist>
  </refsection>

  <refsection>
    <title>Return Value</title>
    <para>
      Returns a simplified geometry with preserved Z and M values.
    </para>
  </refsection>

  <refsection>
    <title>Examples</title>
    <para>This example simplifies a polygon with a threshold of 0.5.</para>
    <programlisting language="sql">SELECT CG_Simplify(
    'POLYGON((0 0,0 1,0.1 1,0.2 1,0.3 1,0.4 1,0.5 1,1 1,1 0,0 0))',
    0.5
  );</programlisting>
    <screen role="visual-primary text-primary">POLYGON((0 0,0 1,1 1,1 0,0 0))</screen>

    <para>Preserving topology can keep additional support points in a mixed ZM collection.</para>
    <programlisting language="sql">SELECT CG_Simplify(
    'GEOMETRYCOLLECTION ZM(
      LINESTRING ZM(-1 -1 3 4,0 0 10 100,1 1 20 200,0 2 15 150,0 5 30 300,2 19 25 250,-4 20 15 150),
      POLYGON ZM((0 0 10 100,1 1 20 200,0 2 15 150,0 5 30 300,2 19 25 250,-4 20 15 150,0 0 10 100))
    )',
    2,
    false
  );</programlisting>
    <screen role="visual-primary text-primary">GEOMETRYCOLLECTION ZM (LINESTRING ZM (-1 -1 3 4,2 19 25 250,-4 20 15 150),POLYGON ZM ((0 0 10 100,2 19 25 250,-4 20 15 150,0 0 10 100)))</screen>

    <para>The topology-preserving variant keeps the shared anchor point at the collection intersection.</para>
    <programlisting language="sql">SELECT CG_Simplify(
    'GEOMETRYCOLLECTION ZM(
      LINESTRING ZM(-1 -1 3 4,0 0 10 100,1 1 20 200,0 2 15 150,0 5 30 300,2 19 25 250,-4 20 15 150),
      POLYGON ZM((0 0 10 100,1 1 20 200,0 2 15 150,0 5 30 300,2 19 25 250,-4 20 15 150,0 0 10 100))
    )',
    2,
    true
  );</programlisting>
    <screen role="visual-primary text-primary">GEOMETRYCOLLECTION ZM (LINESTRING ZM (-1 -1 3 4,0 0 10 100,2 19 25 250,-4 20 15 150),POLYGON ZM ((0 0 10 100,2 19 25 250,-4 20 15 150,0 0 10 100)))</screen>

    <para>Compare simplification with and without topology preservation, using a threshold of 50.</para>
    <programlisting language="sql">WITH data AS (
  SELECT ST_GeomFromText('GEOMETRYCOLLECTION(
    POLYGON((88.46 158.85,90.77 171.54,147.31 173.85,146.15 145,173.85 119.62,146.15 103.46,112.69 118.46,91.92 93.08,65.38 101.15,34.23 121.92,41.15 142.69,49.23 143.85,88.46 158.85)),
    POLYGON((112.69 118.46,146.15 103.46,190 60.77,185.38 43.46,126.54 26.15,83.85 28.46,67.69 64.23,43.46 58.46,10 83.85,34.23 121.92,65.38 101.15,91.92 93.08,112.69 118.46)))
  ') AS geom
)
SELECT geom AS input_geometry,
       CG_Simplify(geom, 50, true) AS topology_preserved,
       CG_Simplify(geom, 50, false) AS topology_not_preserved
FROM data;</programlisting>
    <screen role="visual-primary docbook-qa-ignore-wide-lines">GEOMETRYCOLLECTION(POLYGON((88.46 158.85,90.77 171.54,147.31 173.85,146.15 145,173.85 119.62,146.15 103.46,112.69 118.46,91.92 93.08,65.38 101.15,34.23 121.92,41.15 142.69,49.23 143.85,88.46 158.85)), POLYGON((112.69 118.46,146.15 103.46,190 60.77,185.38 43.46,126.54 26.15,83.85 28.46,67.69 64.23,43.46 58.46,10 83.85,34.23 121.92,65.38 101.15,91.92 93.08,112.69 118.46))) | GEOMETRYCOLLECTION(POLYGON((88.46 158.85,147.31 173.85,146.15 103.46,112.69 118.46,34.23 121.92,88.46 158.85)), POLYGON((112.69 118.46,146.15 103.46,185.38 43.46,10 83.85,34.23 121.92,112.69 118.46))) | GEOMETRYCOLLECTION(POLYGON((88.46 158.85,173.85 119.62,34.23 121.92,88.46 158.85)), POLYGON((112.69 118.46,190 60.77,10 83.85,112.69 118.46)))</screen>
  </refsection>

  <refsection>
    <title>See Also</title>
    <para>
      <xref linkend="ST_Simplify"/>, <xref linkend="ST_SimplifyPreserveTopology"/>
    </para>
   </refsection>
</refentry>

<refentry xml:id="CG_3DAlphaWrapping">
   <refnamediv>
       <refname>CG_3DAlphaWrapping</refname>
       <refpurpose>Computes a 3D Alpha-wrapping strictly enclosing a geometry.</refpurpose>
   </refnamediv>
   <refsynopsisdiv>
       <funcsynopsis>
           <funcprototype>
               <funcdef>geometry <function>CG_3DAlphaWrapping</function></funcdef>
               <paramdef><type>geometry</type> <parameter>geom</parameter></paramdef>
               <paramdef><type>integer</type> <parameter>relative_alpha</parameter></paramdef>
               <paramdef><type>integer</type> <parameter>relative_offset</parameter></paramdef>
           </funcprototype>
       </funcsynopsis>
   </refsynopsisdiv>
   <refsection>
       <title>Description</title>
       <para>Computes the <link xlink:href="https://doc.cgal.org/latest/Alpha_wrap_3/index.html">3D Alpha Wrapping</link> of the points in a geometry. An alpha wrapping is a watertight and orientable surface mesh that strictly encloses the input. It can be seen as an extension or refinement of an <link linkend="CG_AlphaShape">alpha-shape</link>.</para>
       <para>
            The <varname>relative_alpha</varname> parameter controls which features will appear in the output.
            It can have values from 0 to infinity.
            Higher relative_alpha values produce coarser wraps; lower values retain more detail.
        </para>
       <para>
            The <varname>relative_offset</varname> parameter controls the tightness of the result.
            It can have values from 0 to infinity.
            If this parameter is set to 0, its value is automatically determined based on the relative_alpha parameter.
        </para>
       <para role="availability" conformance="3.6.0">Availability: 3.6.0 - requires SFCGAL &gt;= 2.1.0</para>
       <para>&sfcgal_required;</para>
       <para>&Z_support;</para>
   </refsection>
   <refsection>
       <title>Examples</title>
       <para>Wrap a tetrahedral surface and show the native 3D input beside the actual enclosing mesh.</para>
       <programlisting language="sql">WITH data AS (
  SELECT 'POLYHEDRALSURFACE Z (
    ((0 0 0,4 0 0,0 4 0,0 0 0)),
    ((0 0 0,0 0 4,4 0 0,0 0 0)),
    ((0 0 0,0 4 0,0 0 4,0 0 0)),
    ((4 0 0,0 0 4,0 4 0,4 0 0))
  )'::geometry AS input_geometry
)
SELECT input_geometry AS input_geometry,
       CG_3DAlphaWrapping(input_geometry, 1)
         AS wrapped_geometry
FROM data;</programlisting>
       <screen role="visual-primary visual-separate-output docbook-qa-ignore-wide-lines">POLYHEDRALSURFACE Z (((0 0 0,4 0 0,0 4 0,0 0 0)),((0 0 0,0 0 4,4 0 0,0 0 0)),((0 0 0,0 4 0,0 0 4,0 0 0)),((4 0 0,0 0 4,0 4 0,4 0 0))) | POLYHEDRALSURFACE Z (((-0.193 0.127 4,-0.035 -0.228 4.004,0.087 0.087 4.195,-0.193 0.127 4)),((0.083 0.082 3.801,0.087 0.087 4.195,-0.035 -0.228 4.004,0.083 0.082 3.801)),((0.087 0.087 4.195,0.083 0.082 3.801,-0.193 0.127 4,0.087 0.087 4.195)),((0.048 3.84 0.16,3.867 0.133 0.133,0.091 3.926 -0.199,0.048 3.84 0.16)),((3.92 0.08 -0.201,0.037 -0.007 -0.228,0.091 3.926 -0.199,3.92 0.08 -0.201)),((3.867 0.133 0.133,3.92 0.08 -0.201,0.091 3.926 -0.199,3.867 0.133 0.133)),((3.867 0.133 0.133,3.877 -0.195 0.012,4.228 -0.006 0.037,3.867 0.133 0.133)),((3.867 0.133 0.133,4.228 -0.006 0.037,3.92 0.08 -0.201,3.867 0.133 0.133)),((3.877 -0.195 0.012,3.92 0.08 -0.201,4.228 -0.006 0.037,3.877 -0.195 0.012)),((0.012 -0.196 0.121,-0.035 -0.228 4.004,-0.202 0.079 0.078,0.012 -0.196 0.121)),((-0.202 0.079 0.078,0.037 -0.007 -0.228,0.012 -0.196 0.121,-0.202 0.079 0.078)),((3.867 0.133 0.133,0.083 0.082 3.801,3.877 -0.195 0.012,3.867 0.133 0.133)),((0.091 3.926 -0.199,0.101 4.199 0.06,0.048 3.84 0.16,0.091 3.926 -0.199)),((0.101 4.199 0.06,-0.228 4.028 -0.021,0.048 3.84 0.16,0.101 4.199 0.06)),((0.091 3.926 -0.199,-0.228 4.028 -0.021,0.101 4.199 0.06,0.091 3.926 -0.199)),((3.867 0.133 0.133,0.048 3.84 0.16,0.083 0.082 3.801,3.867 0.133 0.133)),((3.877 -0.195 0.012,0.037 -0.007 -0.228,3.92 0.08 -0.201,3.877 -0.195 0.012)),((0.012 -0.196 0.121,0.037 -0.007 -0.228,3.877 -0.195 0.012,0.012 -0.196 0.121)),((0.083 0.082 3.801,0.048 3.84 0.16,-0.193 0.127 4,0.083 0.082 3.801)),((-0.228 4.028 -0.021,-0.193 0.127 4,0.048 3.84 0.16,-0.228 4.028 -0.021)),((-0.228 4.028 -0.021,-0.202 0.079 0.078,-0.193 0.127 4,-0.228 4.028 -0.021)),((-0.202 0.079 0.078,-0.035 -0.228 4.004,-0.193 0.127 4,-0.202 0.079 0.078)),((3.877 -0.195 0.012,0.083 0.082 3.801,-0.035 -0.228 4.004,3.877 -0.195 0.012)),((0.012 -0.196 0.121,3.877 -0.195 0.012,-0.035 -0.228 4.004,0.012 -0.196 0.121)),((0.091 3.926 -0.199,0.037 -0.007 -0.228,-0.228 4.028 -0.021,0.091 3.926 -0.199)),((-0.228 4.028 -0.021,0.037 -0.007 -0.228,-0.202 0.079 0.078,-0.228 4.028 -0.021)))</screen>
   </refsection>
   <refsection>
       <title>See Also</title>
       <para><xref linkend="CG_AlphaShape"/></para>
   </refsection>
</refentry>

<refentry xml:id="CG_NurbsCurveInterpolate">
    <refnamediv>
        <refname>CG_NurbsCurveInterpolate</refname>
        <refpurpose>Creates an interpolating NURBS curve passing through all given data points</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
        <funcsynopsis>
            <funcprototype>
                <funcdef>geometry <function>CG_NurbsCurveInterpolate</function></funcdef>
                <paramdef><type>geometry</type> <parameter>data_points</parameter></paramdef>
                <paramdef><type>integer</type> <parameter>degree</parameter></paramdef>
            </funcprototype>
        </funcsynopsis>
    </refsynopsisdiv>

    <refsection>
        <title>Description</title>

        <para>Creates a NURBS curve that interpolates through all provided data points. The resulting curve passes exactly through each point in the input geometry.</para>

        <para>Parameters:</para>
        <itemizedlist>
            <listitem><para><varname>data_points</varname> - A LINESTRING geometry containing the points to interpolate through.</para></listitem>
            <listitem><para><varname>degree</varname> - Polynomial degree of the NURBS curve (typically 2 or 3).</para></listitem>
        </itemizedlist>

        <para role="availability" conformance="3.7.0">Availability: 3.7.0 - requires SFCGAL &gt;= 2.3.0.</para>
        <para>&sfcgal_required;</para>
        <para>&Z_support;</para>
    </refsection>

    <refsection>
        <title>Examples</title>
        <para>Interpolate a degree-3 NURBS curve through four 2D points.</para>
        <programlisting language="sql">WITH data AS (
  SELECT 'LINESTRING(0 0,2 5,5 3,8 1)'::geometry AS input_points
)
SELECT input_points AS input_points,
       CG_NurbsCurveInterpolate(input_points, 3) AS interpolated_curve
FROM data;</programlisting>
        <screen role="visual-primary visual-overlay text-primary">LINESTRING(0 0,2 5,5 3,8 1) | NURBSCURVE(DEGREE 3, CONTROLPOINTS(NURBSPOINT(WEIGHTEDPOINT(0 0),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT(-0.43 10.29),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT(4.95 1.9),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT(8 1),WEIGHT 1)),KNOTS (KNOT(0,4), KNOT(1,4)))</screen>

        <para>Interpolate a 3D degree-3 NURBS curve through the documented control points.</para>
        <programlisting language="sql">WITH data AS (
  SELECT 'LINESTRING Z (0 0 0,2 5 2,5 3 1,8 1 0)'::geometry AS input_points
)
SELECT input_points AS input_points,
       CG_NurbsCurveInterpolate(input_points, 3) AS interpolated_curve
FROM data;</programlisting>
        <screen role="visual-primary visual-overlay text-primary">LINESTRING Z (0 0 0,2 5 2,5 3 1,8 1 0) | NURBSCURVE Z (DEGREE 3,CONTROLPOINTS Z (NURBSPOINT(WEIGHTEDPOINT Z (0 0 0),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT Z (-0.43 10.29 4.36),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT Z (4.95 1.9 0.54),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT Z (8 1 0),WEIGHT 1)),KNOTS (KNOT(0,4), KNOT(1,4)))</screen>
    </refsection>

    <refsection>
        <title>See Also</title>
        <para><xref linkend="CG_NurbsCurveApproximate"/>, <xref linkend="ST_MakeNurbsCurve"/></para>
    </refsection>
</refentry>

<refentry xml:id="CG_NurbsCurveApproximate">
    <refnamediv>
        <refname>CG_NurbsCurveApproximate</refname>
        <refpurpose>Creates an approximating NURBS curve fitting data points within a tolerance</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
        <funcsynopsis>
            <funcprototype>
                <funcdef>geometry <function>CG_NurbsCurveApproximate</function></funcdef>
                <paramdef><type>geometry</type> <parameter>data_points</parameter></paramdef>
                <paramdef><type>integer</type> <parameter>degree</parameter></paramdef>
                <paramdef><type>float8</type> <parameter>tolerance</parameter></paramdef>
                <paramdef choice="opt"><type>integer</type> <parameter>max_control_points=100</parameter></paramdef>
            </funcprototype>
        </funcsynopsis>
    </refsynopsisdiv>

    <refsection>
        <title>Description</title>

        <para>Creates a NURBS curve that approximates the given data points within the specified tolerance. Unlike interpolation, the curve does not necessarily pass through all points but provides a smooth fit with fewer control points.</para>

        <para>Parameters:</para>
        <itemizedlist>
            <listitem><para><varname>data_points</varname> - A LINESTRING geometry containing the points to approximate.</para></listitem>
            <listitem><para><varname>degree</varname> - Polynomial degree of the NURBS curve.</para></listitem>
            <listitem><para><varname>tolerance</varname> - Maximum allowed distance between the curve and data points.</para></listitem>
            <listitem><para><varname>max_control_points</varname> - Optional maximum number of control points (default: 100). Limits curve complexity.</para></listitem>
        </itemizedlist>

        <para role="availability" conformance="3.7.0">Availability: 3.7.0 - requires SFCGAL &gt;= 2.3.0.</para>
        <para>&sfcgal_required;</para>
        <para>&Z_support;</para>
    </refsection>

    <refsection>
        <title>Examples</title>
        <para>Approximate noisy 2D data with a degree-2 curve and a tolerance of 0.5.</para>
        <programlisting language="sql">WITH data AS (
  SELECT 'LINESTRING(0 0,1 2.1,2 1.9,3 3.2,4 2.8,5 1)'::geometry AS input_points
)
SELECT input_points AS input_points,
       CG_NurbsCurveApproximate(input_points, 2, 0.5) AS approximated_curve
FROM data;</programlisting>
        <screen role="visual-primary visual-overlay text-primary">LINESTRING(0 0,1 2.1,2 1.9,3 3.2,4 2.8,5 1) | NURBSCURVE(DEGREE 2, CONTROLPOINTS(NURBSPOINT(WEIGHTEDPOINT(0 0),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT(-0.05 2.64),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT(2.24 1.65),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT(2.79 3.48),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT(4.84 2.43),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT(5 1),WEIGHT 1)),KNOTS (KNOT(0,3), KNOT(0.35,1), KNOT(0.51,1), KNOT(0.68,1), KNOT(1,3)))</screen>

        <para>Approximate a 3D point set while preserving the Z dimension in the fitted curve.</para>
        <programlisting language="sql">WITH data AS (
  SELECT 'LINESTRING Z (0 0 0,1 2 1,2 3 2,3 2 1,4 1 0,5 0 0)'::geometry AS input_points
)
SELECT input_points AS input_points,
       CG_NurbsCurveApproximate(input_points, 3, 0.1) AS approximated_curve
FROM data;</programlisting>
        <screen role="visual-primary visual-overlay text-primary">LINESTRING Z (0 0 0,1 2 1,2 3 2,3 2 1,4 1 0,5 0 0) | NURBSCURVE Z (DEGREE 3,CONTROLPOINTS Z (NURBSPOINT(WEIGHTEDPOINT Z (0 0 0),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT Z (0.18 -0.15 -1.29),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT Z (1.49 4.36 3.35),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT Z (3.33 1.33 0.38),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT Z (4.34 0.83 -0.44),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT Z (5 0 0),WEIGHT 1)),KNOTS (KNOT(0,4), KNOT(0.46,1), KNOT(0.64,1), KNOT(1,4)))</screen>
    </refsection>

    <refsection>
        <title>See Also</title>
        <para><xref linkend="CG_NurbsCurveInterpolate"/>, <xref linkend="ST_MakeNurbsCurve"/></para>
    </refsection>
</refentry>

<refentry xml:id="CG_NurbsCurveDerivative">
    <refnamediv>
        <refname>CG_NurbsCurveDerivative</refname>
        <refpurpose>Computes the derivative (tangent, curvature) of a NURBS curve at a given parameter</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
        <funcsynopsis>
            <funcprototype>
                <funcdef>geometry <function>CG_NurbsCurveDerivative</function></funcdef>
                <paramdef><type>geometry</type> <parameter>nurbscurve</parameter></paramdef>
                <paramdef><type>float8</type> <parameter>parameter</parameter></paramdef>
                <paramdef><type>integer</type> <parameter>derivative_order</parameter></paramdef>
            </funcprototype>
        </funcsynopsis>
    </refsynopsisdiv>

    <refsection>
        <title>Description</title>

        <para>Computes the derivative of a NURBS curve at a specific parameter value. The derivative represents the rate of change at that point:</para>
        <itemizedlist>
            <listitem><para>Order 1: Tangent vector (direction and speed)</para></listitem>
            <listitem><para>Order 2: Curvature vector (how the tangent changes)</para></listitem>
            <listitem><para>Order 3: Third-order derivative (supported maximum)</para></listitem>
        </itemizedlist>

        <para>Parameters:</para>
        <itemizedlist>
            <listitem><para><varname>nurbscurve</varname> - A NURBS curve geometry.</para></listitem>
            <listitem><para><varname>parameter</varname> - Parameter value for evaluation (typically 0.0 to 1.0).</para></listitem>
            <listitem><para><varname>derivative_order</varname> - Order of derivative to compute (1, 2, or 3).</para></listitem>
        </itemizedlist>

        <para>Returns a POINT geometry representing the derivative vector at the specified parameter.</para>

        <para role="availability" conformance="3.7.0">Availability: 3.7.0 - requires SFCGAL &gt;= 2.3.0.</para>
        <para>&sfcgal_required;</para>
        <para>&Z_support;</para>
    </refsection>

    <refsection>
        <title>Examples</title>
        <para>The first derivative gives the tangent vector at the evaluation parameter.</para>
        <programlisting language="sql">WITH data AS (
  SELECT 'NURBSCURVE (2, (0.00 0.00, 5.00 10.00, 10.00 0.00))'::geometry AS input_curve
)
SELECT input_curve AS input_curve,
       CG_NurbsCurveDerivative(input_curve, 0.5, 1) AS tangent
FROM data;</programlisting>
        <screen role="visual-primary visual-overlay text-primary">NURBSCURVE(DEGREE 2, CONTROLPOINTS(NURBSPOINT(WEIGHTEDPOINT(0 0),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT(5 10),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT(10 0),WEIGHT 1)),KNOTS (KNOT(0,3), KNOT(1,3))) | POINT Z (10 0 0)</screen>

        <para>The second derivative exposes curvature change for a higher-degree curve.</para>
        <programlisting language="sql">WITH data AS (
  SELECT 'NURBSCURVE (3, (0.00 0.00, 2.00 8.00, 5.00 5.00, 8.00 2.00, 10.00 0.00))'::geometry AS input_curve
)
SELECT input_curve AS input_curve,
       CG_NurbsCurveDerivative(input_curve, 0.5, 2) AS curvature
FROM data;</programlisting>
        <screen role="visual-primary visual-overlay text-primary">NURBSCURVE(DEGREE 3, CONTROLPOINTS(NURBSPOINT(WEIGHTEDPOINT(0 0),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT(2 8),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT(5 5),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT(8 2),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT(10 0),WEIGHT 1)),KNOTS (KNOT(0,4), KNOT(0.5,1), KNOT(1,4))) | POINT Z (9 -9 0)</screen>

        <para>The same derivative call also works for 3D NURBS curves.</para>
        <programlisting language="sql">WITH data AS (
  SELECT 'NURBSCURVE Z (2, (0.00 0.00 0.00, 5.00 10.00 5.00, 10.00 0.00 0.00))'::geometry AS input_curve
)
SELECT input_curve AS input_curve,
       CG_NurbsCurveDerivative(input_curve, 0.5, 1) AS tangent
FROM data;</programlisting>
        <screen role="visual-primary visual-overlay text-primary">NURBSCURVE Z (DEGREE 2,CONTROLPOINTS Z (NURBSPOINT(WEIGHTEDPOINT Z (0 0 0),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT Z (5 10 5),WEIGHT 1), NURBSPOINT(WEIGHTEDPOINT Z (10 0 0),WEIGHT 1)),KNOTS (KNOT(0,3), KNOT(1,3))) | POINT Z (10 0 0)</screen>
    </refsection>

    <refsection>
        <title>See Also</title>
        <para><xref linkend="ST_Evaluate"/>, <xref linkend="ST_MakeNurbsCurve"/></para>
    </refsection>
</refentry>

    </section>
    &reference_sfcgal_legacy;
</chapter>
