📄 directedline.cc
字号:
/*
** License Applicability. Except to the extent portions of this file are
** made subject to an alternative license as permitted in the SGI Free
** Software License B, Version 1.1 (the "License"), the contents of this
** file are subject only to the provisions of the License. You may not use
** this file except in compliance with the License. You may obtain a copy
** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
**
** http://oss.sgi.com/projects/FreeB
**
** Note that, as provided in the License, the Software is distributed on an
** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
**
** Original Code. The Original Code is: OpenGL Sample Implementation,
** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
** Copyright in any portions created by third parties is as indicated
** elsewhere herein. All Rights Reserved.
**
** Additional Notice Provisions: The application programming interfaces
** established by SGI in conjunction with the Original Code are The
** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
** Window System(R) (Version 1.3), released October 19, 1998. This software
** was created using the OpenGL(R) version 1.2.1 Sample Implementation
** published by SGI, but has not been independently verified as being
** compliant with the OpenGL(R) version 1.2.1 Specification.
**
*/
/*
*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "glimports.h"
#include "zlassert.h"
#include "quicksort.h"
#include "directedLine.h"
#include "polyDBG.h"
#ifdef __WATCOMC__
#pragma warning 726 10
#endif
//we must return the newLine
directedLine* directedLine::deleteChain(directedLine* begin, directedLine* end)
{
if(begin->head()[0] == end->tail()[0] &&
begin->head()[1] == end->tail()[1]
)
{
directedLine *ret = begin->prev;
begin->prev->next = end->next;
end->next->prev = begin->prev;
delete begin->sline;
delete end->sline;
delete begin;
delete end;
return ret;
}
directedLine* newLine;
sampledLine* sline = new sampledLine(begin->head(), end->tail());
newLine = new directedLine(INCREASING, sline);
directedLine *p = begin->prev;
directedLine *n = end->next;
p->next = newLine;
n->prev = newLine;
newLine->prev = p;
newLine->next = n;
delete begin->sline;
delete end->sline;
delete begin;
delete end;
return newLine;
}
void directedLine::deleteSingleLine(directedLine* dline)
{
//make sure that dline->prev->tail is the same as
//dline->next->head. This is for numerical erros.
//for example, if we delete a line which is almost degeneate
//within (epsilon), then we want to make that the polygon after deletion
//is still a valid polygon
dline->next->head()[0] = dline->prev->tail()[0];
dline->next->head()[1] = dline->prev->tail()[1];
dline->prev->next = dline->next;
dline->next->prev = dline->prev;
delete dline;
}
static Int myequal(Real a[2], Real b[2])
{
/*
if(a[0]==b[0] && a[1] == b[1])
return 1;
else
return 0;
*/
if(fabs(a[0]-b[0]) < 0.00001 &&
fabs(a[1]-b[1]) < 0.00001)
return 1;
else
return 0;
}
directedLine* directedLine::deleteDegenerateLines()
{
//if there is only one edge or two edges, don't do anything
if(this->next == this)
return this;
if(this->next == this->prev)
return this;
//find a nondegenerate line
directedLine* temp;
directedLine* first = NULL;
if(! myequal(head(), tail()))
/*
if(head()[0] != tail()[0] ||
head()[1] != tail()[1])
*/
first = this;
else
{
for(temp = this->next; temp != this; temp = temp->next)
{
/*
if(temp->head()[0] != temp->tail()[0] ||
temp->head()[1] != temp->tail()[1])
*/
if(! myequal(temp->head(), temp->tail()))
{
first = temp;
break;
}
}
}
//if there are no non-degenerate lines, then we simply return NULL.
if(first == NULL)
{
deleteSinglePolygonWithSline();
return NULL;
}
directedLine* tempNext = NULL;
for(temp =first->next; temp != first; temp = tempNext)
{
tempNext = temp->getNext();
/*
if(temp->head()[0] == temp->tail()[0] &&
temp->head()[1] == temp->tail()[1])
*/
if(myequal(temp->head(), temp->tail()))
deleteSingleLine(temp);
}
return first;
}
directedLine* directedLine::deleteDegenerateLinesAllPolygons()
{
directedLine* temp;
directedLine *tempNext = NULL;
directedLine* ret= NULL;
directedLine* retEnd = NULL;
for(temp=this; temp != NULL; temp = tempNext)
{
tempNext = temp->nextPolygon;
temp->nextPolygon = NULL;
if(ret == NULL)
{
ret = retEnd = temp->deleteDegenerateLines();
}
else
{
directedLine *newPolygon = temp->deleteDegenerateLines();
if(newPolygon != NULL)
{
retEnd->nextPolygon = temp->deleteDegenerateLines();
retEnd = retEnd->nextPolygon;
}
}
}
return ret;
}
directedLine* directedLine::cutIntersectionAllPoly(int &cutOccur)
{
directedLine* temp;
directedLine *tempNext = NULL;
directedLine* ret= NULL;
directedLine* retEnd = NULL;
cutOccur = 0;
for(temp=this; temp != NULL; temp = tempNext)
{
int eachCutOccur=0;
tempNext = temp->nextPolygon;
temp->nextPolygon = NULL;
if(ret == NULL)
{
ret = retEnd = DBG_cutIntersectionPoly(temp, eachCutOccur);
if(eachCutOccur)
cutOccur = 1;
}
else
{
retEnd->nextPolygon = DBG_cutIntersectionPoly(temp, eachCutOccur);
retEnd = retEnd->nextPolygon;
if(eachCutOccur)
cutOccur = 1;
}
}
return ret;
}
void directedLine::deleteSinglePolygonWithSline()
{
directedLine *temp, *tempNext;
prev->next = NULL;
for(temp=this; temp != NULL; temp = tempNext)
{
tempNext = temp->next;
delete temp->sline;
delete temp;
}
}
void directedLine::deletePolygonListWithSline()
{
directedLine *temp, *tempNext;
for(temp=this; temp != NULL; temp=tempNext)
{
tempNext = temp->nextPolygon;
temp->deleteSinglePolygonWithSline();
}
}
void directedLine::deleteSinglePolygon()
{
directedLine *temp, *tempNext;
prev->next = NULL;
for(temp=this; temp != NULL; temp = tempNext)
{
tempNext = temp->next;
delete temp;
}
}
void directedLine::deletePolygonList()
{
directedLine *temp, *tempNext;
for(temp=this; temp != NULL; temp=tempNext)
{
tempNext = temp->nextPolygon;
temp->deleteSinglePolygon();
}
}
/*a loop by itself*/
directedLine::directedLine(short dir, sampledLine* sl)
{
direction = dir;
sline = sl;
next = this;
prev = this;
nextPolygon = NULL;
// prevPolygon = NULL;
rootBit = 0;/*important to initilzae to 0 meaning not root yet*/
rootLink = NULL;
}
void directedLine::init(short dir, sampledLine* sl)
{
direction = dir;
sline = sl;
}
directedLine::directedLine()
{
next = this;
prev = this;
nextPolygon = NULL;
rootBit = 0;/*important to initilzae to 0 meaning not root yet*/
rootLink = NULL;
}
directedLine::~directedLine()
{
}
Real* directedLine::head()
{
return (direction==INCREASING)? (sline->get_points())[0] : (sline->get_points())[sline->get_npoints()-1];
}
/*inline*/ Real* directedLine::getVertex(Int i)
{
return (direction==INCREASING)? (sline->get_points())[i] : (sline->get_points())[sline->get_npoints() - 1 -i];
}
Real* directedLine::tail()
{
return (direction==DECREASING)? (sline->get_points())[0] : (sline->get_points())[sline->get_npoints()-1];
}
/*insert a new line between prev and this*/
void directedLine::insert(directedLine* nl)
{
nl->next = this;
nl->prev = prev;
prev->next = nl;
prev = nl;
nl->rootLink = this; /*assuming that 'this' is the root!!!*/
}
Int directedLine::numEdges()
{
Int ret=0;
directedLine* temp;
if(next == this) return 1;
ret = 1;
for(temp = next; temp != this; temp = temp->next)
ret++;
return ret;
}
Int directedLine::numEdgesAllPolygons()
{
Int ret=0;
directedLine* temp;
for(temp=this; temp!= NULL; temp=temp->nextPolygon)
{
ret += temp->numEdges();
}
return ret;
}
/*return 1 if the double linked list forms a polygon.
*/
short directedLine::isPolygon()
{
directedLine* temp;
/*a polygon contains at least 3 edges*/
if(numEdges() <=2) return 0;
/*check this edge*/
if(! isConnected()) return 0;
/*check all other edges*/
for(temp=next; temp != this; temp = temp->next){
if(!isConnected()) return 0;
}
return 1;
}
/*check if the head of this edge is connected to
*the tail of the prev
*/
short directedLine::isConnected()
{
if( (head()[0] == prev->tail()[0]) && (head()[1] == prev->tail()[1]))
return 1;
else
return 0;
}
Int compV2InY(Real A[2], Real B[2])
{
if(A[1] < B[1]) return -1;
if(A[1] == B[1] && A[0] < B[0]) return -1;
if(A[1] == B[1] && A[0] == B[0]) return 0;
return 1;
}
Int compV2InX(Real A[2], Real B[2])
{
if(A[0] < B[0]) return -1;
if(A[0] == B[0] && A[1] < B[1]) return -1;
if(A[0] == B[0] && A[1] == B[1]) return 0;
return 1;
}
/*compare two vertices NOT lines!
*A vertex is the head of a directed line.
*(x_1, y_1) <= (x_2, y_2) if
*either y_1 < y_2
*or y_1 == y_2 && x_1 < x_2.
*return -1 if this->head() <= nl->head(),
*return 1 otherwise
*/
Int directedLine::compInY(directedLine* nl)
{
if(head()[1] < nl->head()[1]) return -1;
if(head()[1] == nl->head()[1] && head()[0] < nl->head()[0]) return -1;
return 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -