/* * =================================================================== * Functions for polygons (polygon.c). * * Copyright (C) 1993 by Mark Austin. * Institute for Systems Research, * University of Maryland, MD 20742 * * This software is provided "as is" without express or implied warranty. * Permission is granted to use this software for any on any computer * system, and to redistribute it freely, subject to the following * restrictions: * * 1. The author is not responsible for the consequences of use of * this software, even if they arise from defects in the software. * 2. The origin of this software must not be misrepresented, either * by explicit claim or by omission. * 3. Altered versions must be plainly marked as such, and must not * be misrepresented as being the original software. * 4. This notice is to remain intact. * * Written by: Mark Austin March 1994 * =================================================================== */ #include #include #include #include #include "polygon.h" #include "miscellaneous.h" #define DEBUG /* * ================================================ * Allocate Memory for Vertex, Edge, and Polygon * ================================================ */ VERTEX *polyAllocVertex() { VERTEX *spVertex = (VERTEX *) safeMalloc (sizeof (VERTEX), __FILE__, __LINE__ ); spVertex->fXcoord = 0.0; spVertex->fYcoord = 0.0; spVertex->fZcoord = 0.0; spVertex->fWcoord = 1.0; return ( spVertex ); } EDGE *polyAllocEdge() { EDGE *spEdge = (EDGE *) safeMalloc (sizeof (EDGE), __FILE__ , __LINE__ ); spEdge->spVertex = NULL; spEdge->spNext = NULL; spEdge->sParam.fA = 0.0; spEdge->sParam.fB = 0.0; spEdge->sParam.fC = 0.0; return ( spEdge ); } POLYGON *polyAlloc() { POLYGON *spPolygon = (POLYGON *) safeMalloc (sizeof (POLYGON), __FILE__, __LINE__ ); spPolygon->eTypeOfLoop = Perimeter; spPolygon->uPolygon.spChild = NULL; spPolygon->uPolygon.spParent = NULL; spPolygon->spEdge = NULL; spPolygon->spNext = NULL; return ( spPolygon ); } /* * ======================================= * Create edge with one vertex. * * Input : float fXcoord -- X coordinate * : float fYcoord -- Y coordinate * : float fZcoord -- Z coordinate * ======================================= */ EDGE *polyCreateEdge( float fXcoord, float fYcoord , float fZcoord ) { EDGE *spEdge; spEdge = polyAllocEdge(); spEdge->spVertex = polyAllocVertex(); spEdge->spVertex->fXcoord = fXcoord; spEdge->spVertex->fYcoord = fYcoord; spEdge->spVertex->fZcoord = fZcoord; return ( spEdge ); } /* * ============================================================= * Create polygon with one edge and one vertex * * Input : char *cpName -- Name of Polygon * : EDGE *spEdge -- Pointer to edge data structure * Output : POLYGON *spPolygon -- Pointer to new polygon * ============================================================= */ POLYGON *polyCreate( char *cpName, EDGE *spEdge ) { POLYGON *spPolygon; /* [a] : Allocate polygon */ spPolygon = polyAlloc(); spPolygon->cpName = saveString( cpName, __FILE__, __LINE__ ); /* [b] : Create edge; close and link circular list */ spPolygon->spEdge = spEdge; spPolygon->spEdge->spNext = spPolygon->spEdge; spPolygon->spEdge->spPolygon = spPolygon; return ( spPolygon ); } /* * ============================================================= * Add edge to polygon * * Input : POLYGON *spPolygon -- Pointer to new polygon * : EDGE *spEdge -- Pointer to edge data structure * Output : void * ============================================================= */ void polyAddEdge( POLYGON *spPolygon, EDGE *spEdge ) { EDGE *spTemp; /* Link new edge into end of edge list */ spTemp = spPolygon->spEdge; while(spTemp->spNext != spPolygon->spEdge ) { spTemp = spTemp->spNext; } spEdge->spPolygon = spPolygon;; spEdge->spNext = spPolygon->spEdge; spTemp->spNext = spEdge; } /* * ============================================================= * Print contents of polygon family and members * * Input : POLYGON *spPolygon -- Pointer to polygon (list) * Output : void * ============================================================= */ void polyPrint( POLYGON *spPolygon ) { POLYGON *spPoly; for(spPoly = spPolygon; spPoly != NULL; spPoly = spPoly->spNext) polyPrintMember( spPoly ); } void polyPrintMember( POLYGON *spPolygon ) { POLYGON *spPoly; EDGE *spTemp; int iEdgeNo = 1; /* [a] : Print name of polygon */ printf("\nPolygon Name : %s\n\n", spPolygon->cpName); /* [b] : Print vertices of polygon exterior */ spTemp = spPolygon->spEdge; printf("Edge %3d : (X,Y,Z) = (%10.3f, %10.3f, %10.3f)\n", iEdgeNo, spTemp->spVertex->fXcoord, spTemp->spVertex->fYcoord, spTemp->spVertex->fZcoord ); while( spTemp->spNext != spPolygon->spEdge ) { spTemp = spTemp->spNext; iEdgeNo = iEdgeNo + 1; printf("Edge %3d : (X,Y,Z) = (%10.3f, %10.3f, %10.3f)\n", iEdgeNo, spTemp->spVertex->fXcoord, spTemp->spVertex->fYcoord, spTemp->spVertex->fZcoord ); } /* [c] : Print vertices in polygon holes */ spPoly = spPolygon->uPolygon.spChild; while(spPoly != NULL ) { printf("\nLoop Name : %s\n\n", spPoly->cpName); spTemp = spPoly->spEdge; iEdgeNo = iEdgeNo + 1; printf("Edge %3d : (X,Y,Z) = (%10.3f, %10.3f, %10.3f)\n", iEdgeNo, spTemp->spVertex->fXcoord, spTemp->spVertex->fYcoord, spTemp->spVertex->fZcoord ); while( spTemp->spNext != spPoly->spEdge ) { spTemp = spTemp->spNext; iEdgeNo = iEdgeNo + 1; printf("Edge %3d : (X,Y,Z) = (%10.3f, %10.3f, %10.3f)\n", iEdgeNo, spTemp->spVertex->fXcoord, spTemp->spVertex->fYcoord, spTemp->spVertex->fZcoord ); } spPoly = spPoly->spNext; } } /* * ============================================================= * Add Hole to Polygon List * * Input : POLYGON *spPolygon -- Pointer to parent polygon. * : POLYGON *spHole -- Pointer to polygon hole. * Output : void * ============================================================= */ void polyAddHole( POLYGON *spPolygon, POLYGON *spHole ) { POLYGON *spTemp; int iEdgeNo = 1; /* [a] : Make sure polygon is oriented anti-clockwise */ /* ....... add details later ......... */ /* [b] : Make sure hole does not intersect exterior boundary */ /* ....... add details later ......... */ /* [c] : Link new polygon hole to end of List */ spHole->eTypeOfLoop = Hole; spHole->uPolygon.spParent = spPolygon; spTemp = spPolygon->uPolygon.spChild; if( spTemp == NULL ) spPolygon->uPolygon.spChild = spHole; else { while(spTemp->spNext != NULL ) spTemp = spTemp->spNext; spTemp->spNext = spHole; } } /* * ============================================================= * Append Polygon to Display List * * Input : POLYGON *spPolygon -- Pointer to parent polygon. * : POLYGON *spHole -- Pointer to polygon hole. * Output : void * ============================================================= */ void polyAppend( POLYGON *spPolygon, POLYGON *spNewPolygon ) { POLYGON *spTemp; /* [a] : Test for NULL polygon */ if( spPolygon == NULL ) { spPolygon = spNewPolygon; return; } /* [b] : Add new polygon to end of list */ spTemp = spPolygon->spNext; if( spTemp == NULL ) spPolygon->spNext = spNewPolygon; else { while(spTemp->spNext != NULL ) spTemp = spTemp->spNext; spTemp->spNext = spNewPolygon; } }