postgis/liblwgeom/lwtriangle.c
Paul Ramsey 4bd609aeff Remove orphaned _compute_box3d functions
git-svn-id: http://svn.osgeo.org/postgis/trunk@8029 b70326c6-7e19-0410-871a-916f4a2858ee
2011-10-28 17:44:00 +00:00

210 lines
4.5 KiB
C

/**********************************************************************
*
* PostGIS - Spatial Types for PostgreSQL
* http://postgis.refractions.net
*
* Copyright (C) 2010 - Oslandia
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU General Public Licence. See the COPYING file.
*
**********************************************************************/
/* basic LWTRIANGLE manipulation */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "liblwgeom_internal.h"
#include "lwgeom_log.h"
/* construct a new LWTRIANGLE.
* use SRID=SRID_UNKNOWN for unknown SRID (will have 8bit type's S = 0)
*/
LWTRIANGLE*
lwtriangle_construct(int srid, GBOX *bbox, POINTARRAY *points)
{
LWTRIANGLE *result;
result = (LWTRIANGLE*) lwalloc(sizeof(LWTRIANGLE));
result->type = TRIANGLETYPE;
result->flags = points->flags;
FLAGS_SET_BBOX(result->flags, bbox?1:0);
result->srid = srid;
result->points = points;
result->bbox = bbox;
return result;
}
LWTRIANGLE*
lwtriangle_construct_empty(int srid, char hasz, char hasm)
{
LWTRIANGLE *result = lwalloc(sizeof(LWTRIANGLE));
result->type = TRIANGLETYPE;
result->flags = gflags(hasz,hasm,0);
result->srid = srid;
result->points = ptarray_construct_empty(hasz, hasm, 1);
result->bbox = NULL;
return result;
}
void lwtriangle_free(LWTRIANGLE *triangle)
{
if (triangle->bbox)
lwfree(triangle->bbox);
if (triangle->points)
ptarray_free(triangle->points);
lwfree(triangle);
}
void printLWTRIANGLE(LWTRIANGLE *triangle)
{
if (triangle->type != TRIANGLETYPE)
lwerror("printLWTRIANGLE called with something else than a Triangle");
lwnotice("LWTRIANGLE {");
lwnotice(" ndims = %i", (int)FLAGS_NDIMS(triangle->flags));
lwnotice(" SRID = %i", (int)triangle->srid);
printPA(triangle->points);
lwnotice("}");
}
/* @brief Clone LWTRIANGLE object. Serialized point lists are not copied.
*
* @see ptarray_clone
*/
LWTRIANGLE *
lwtriangle_clone(const LWTRIANGLE *g)
{
LWDEBUGF(2, "lwtriangle_clone called with %p", g);
return (LWTRIANGLE *)lwline_clone((const LWLINE *)g);
}
void
lwtriangle_force_clockwise(LWTRIANGLE *triangle)
{
if ( ptarray_isccw(triangle->points) )
ptarray_reverse(triangle->points);
}
void
lwtriangle_reverse(LWTRIANGLE *triangle)
{
if( lwtriangle_is_empty(triangle) ) return;
ptarray_reverse(triangle->points);
}
void
lwtriangle_release(LWTRIANGLE *lwtriangle)
{
lwgeom_release(lwtriangle_as_lwgeom(lwtriangle));
}
/* check coordinate equality */
char
lwtriangle_same(const LWTRIANGLE *t1, const LWTRIANGLE *t2)
{
char r = ptarray_same(t1->points, t2->points);
LWDEBUGF(5, "returning %d", r);
return r;
}
/*
* Construct a triangle from a LWLINE being
* the shell
* Pointarray from intput geom are cloned.
* Input line must have 4 points, and be closed.
*/
LWTRIANGLE *
lwtriangle_from_lwline(const LWLINE *shell)
{
LWTRIANGLE *ret;
POINTARRAY *pa;
if ( shell->points->npoints != 4 )
lwerror("lwtriangle_from_lwline: shell must have exactly 4 points");
if ( (!FLAGS_GET_Z(shell->flags) && !ptarray_isclosed2d(shell->points)) ||
(FLAGS_GET_Z(shell->flags) && !ptarray_isclosed3d(shell->points)) )
lwerror("lwtriangle_from_lwline: shell must be closed");
pa = ptarray_clone_deep(shell->points);
ret = lwtriangle_construct(shell->srid, NULL, pa);
if (lwtriangle_is_repeated_points(ret))
lwerror("lwtriangle_from_lwline: some points are repeated in triangle");
return ret;
}
char
lwtriangle_is_repeated_points(LWTRIANGLE *triangle)
{
char ret;
POINTARRAY *pa;
pa = ptarray_remove_repeated_points(triangle->points);
ret = ptarray_same(pa, triangle->points);
ptarray_free(pa);
return ret;
}
int lwtriangle_is_empty(const LWTRIANGLE *triangle)
{
if ( !triangle->points || triangle->points->npoints == 0 )
return LW_TRUE;
return LW_FALSE;
}
/**
* Find the area of the outer ring
*/
double
lwtriangle_area(const LWTRIANGLE *triangle)
{
double area=0.0;
int i;
POINT2D p1;
POINT2D p2;
if (! triangle->points->npoints) return area; /* empty triangle */
for (i=0; i < triangle->points->npoints-1; i++)
{
getPoint2d_p(triangle->points, i, &p1);
getPoint2d_p(triangle->points, i+1, &p2);
area += ( p1.x * p2.y ) - ( p1.y * p2.x );
}
area /= 2.0;
return fabs(area);
}
double
lwtriangle_perimeter(const LWTRIANGLE *triangle)
{
if( triangle->points )
return ptarray_length(triangle->points);
else
return 0.0;
}
double
lwtriangle_perimeter_2d(const LWTRIANGLE *triangle)
{
if( triangle->points )
return ptarray_length_2d(triangle->points);
else
return 0.0;
}