rightmostedgefinder.cpp

来自「一个很好的vc底层代码」· C++ 代码 · 共 168 行

CPP
168
字号
/********************************************************************** * $Id: RightmostEdgeFinder.cpp,v 1.9 2004/07/08 19:34:49 strk Exp $ * * GEOS - Geometry Engine Open Source * http://geos.refractions.net * * Copyright (C) 2001-2002 Vivid Solutions Inc. * * This is free software; you can redistribute and/or modify it under * the terms of the GNU Lesser General Public Licence as published * by the Free Software Foundation.  * See the COPYING file for more information. * ********************************************************************** * $Log: RightmostEdgeFinder.cpp,v $ * Revision 1.9  2004/07/08 19:34:49  strk * Mirrored JTS interface of CoordinateSequence, factory and * default implementations. * Added DefaultCoordinateSequenceFactory::instance() function. * * Revision 1.8  2004/07/02 13:28:28  strk * Fixed all #include lines to reflect headers layout change. * Added client application build tips in README. * * Revision 1.7  2004/04/10 08:40:01  ybychkov * "operation/buffer" upgraded to JTS 1.4 * * Revision 1.6  2003/11/07 01:23:42  pramsey * Add standard CVS headers licence notices and copyrights to all cpp and h * files. * * Revision 1.5  2003/10/15 16:39:03  strk * Made Edge::getCoordinates() return a 'const' value. Adapted code set. * **********************************************************************/#include <geos/opBuffer.h>#include <geos/util.h>namespace geos {RightmostEdgeFinder::RightmostEdgeFinder(CGAlgorithms *newCga){	cga=newCga;	minIndex=-1;	minDe=NULL;	orientedDe=NULL;	minCoord.setNull();}DirectedEdge* RightmostEdgeFinder::getEdge() {	return orientedDe;}Coordinate& RightmostEdgeFinder::getCoordinate() {	return minCoord;}void RightmostEdgeFinder::findEdge(vector<DirectedEdge*>* dirEdgeList){	/**	* Check all forward DirectedEdges only.  This is still general,	* because each edge has a forward DirectedEdge.	*/	for(int i=0;i<(int)dirEdgeList->size();i++) {		DirectedEdge *de=(*dirEdgeList)[i];		if (!de->isForward())			continue;		checkForRightmostCoordinate(de);	}	/**	* If the rightmost point is a node, we need to identify which of	* the incident edges is rightmost.	*/	Assert::isTrue(minIndex!=0 || minCoord==minDe->getCoordinate(), "inconsistency in rightmost processing");	if (minIndex==0 ) {		findRightmostEdgeAtNode();	} else {		findRightmostEdgeAtVertex();	}	/**	* now check that the extreme side is the R side.	* If not, use the sym instead.	*/	orientedDe=minDe;	int rightmostSide=getRightmostSide(minDe,minIndex);	if (rightmostSide==Position::LEFT) {		orientedDe=minDe->getSym();	}}void RightmostEdgeFinder::findRightmostEdgeAtNode(){	Node *node=minDe->getNode();	DirectedEdgeStar *star=(DirectedEdgeStar*) node->getEdges();	minDe=star->getRightmostEdge();	// the DirectedEdge returned by the previous call is not	// necessarily in the forward direction. Use the sym edge if it isn't.	if (!minDe->isForward()) {		minDe=minDe->getSym();		minIndex=minDe->getEdge()->getCoordinates()->getSize()-1;	}}void RightmostEdgeFinder::findRightmostEdgeAtVertex() {	/**	* The rightmost point is an interior vertex, so it has a segment on either side of it.	* If these segments are both above or below the rightmost point, we need to	* determine their relative orientation to decide which is rightmost.	*/	const CoordinateSequence *pts=minDe->getEdge()->getCoordinates();	Assert::isTrue(minIndex>0 && minIndex<pts->getSize(), "rightmost point expected to be interior vertex of edge");	const Coordinate& pPrev=pts->getAt(minIndex-1);	const Coordinate& pNext=pts->getAt(minIndex+1);	int orientation=cga->computeOrientation(minCoord,pNext,pPrev);	bool usePrev=false;	// both segments are below min point	if (pPrev.y<minCoord.y && pNext.y<minCoord.y		&& orientation==CGAlgorithms::COUNTERCLOCKWISE) {			usePrev=true;	} else if (pPrev.y>minCoord.y && pNext.y>minCoord.y		&& orientation==CGAlgorithms::CLOCKWISE) {			usePrev=true;	}	// if both segments are on the same side, do nothing - either is safe	// to select as a rightmost segment	if (usePrev) {		minIndex=minIndex-1;	}}void RightmostEdgeFinder::checkForRightmostCoordinate(DirectedEdge *de) {	const CoordinateSequence *coord=de->getEdge()->getCoordinates();	// only check vertices which are the starting point of a non-horizontal segment	for(int i=0;i<coord->getSize()-1;i++) {     // only check vertices which are the start or end point of a non-horizontal segment     // <FIX> MD 19 Sep 03 - NO!  we can test all vertices, since the rightmost must have a non-horiz segment adjacent to it		if (minCoord==Coordinate::getNull() || coord->getAt(i).x>minCoord.x ) {			minDe=de;			minIndex=i;			minCoord=coord->getAt(i);		}	}}int RightmostEdgeFinder::getRightmostSide(DirectedEdge *de, int index){	int side=getRightmostSideOfSegment(de,index);	if (side<0)		side=getRightmostSideOfSegment(de,index-1);	if (side<0)		// reaching here can indicate that segment is horizontal		// Assert::shouldNeverReachHere("problem with finding rightmost side of segment");		minCoord=Coordinate::nullCoord;	checkForRightmostCoordinate(de);	return side;}int RightmostEdgeFinder::getRightmostSideOfSegment(DirectedEdge *de, int i){	Edge *e=de->getEdge();	const CoordinateSequence *coord=e->getCoordinates();	if (i<0 || i+1>=coord->getSize()) return -1;	if (coord->getAt(i).y==coord->getAt(i+1).y) return -1;    // indicates edge is parallel to x-axis	int pos=Position::LEFT;	if (coord->getAt(i).y<coord->getAt(i+1).y) pos=Position::RIGHT;	return pos;}}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?