⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lineintersector.cpp

📁 一个很好的vc底层代码
💻 CPP
字号:
/********************************************************************** * $Id: LineIntersector.cpp,v 1.19.2.2 2005/05/23 19:01:52 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. * **********************************************************************/#include <geos/geosAlgorithm.h>#include <geos/util.h>#include <geos/geom.h>#include <cmath>#ifndef DEBUG_INTERSECT#define DEBUG_INTERSECT 0#endif#define DEBUG 0namespace geos {/** * Computes the "edge distance" of an intersection point p in an edge. * The edge distance is a metric of the point along the edge. * The metric used is a robust and easy to compute metric function. * It is <b>not</b> equivalent to the usual Euclidean metric. * It relies on the fact that either the x or the y ordinates of the * points in the edge are unique, depending on whether the edge is longer in * the horizontal or vertical direction. *  * NOTE: This function may produce incorrect distances *  for inputs where p is not precisely on p1-p2 * (E.g. p = (139,9) p1 = (139,10), p2 = (280,1) produces distanct * 0.0, which is incorrect. *  * My hypothesis is that the function is safe to use for points which are the * result of <b>rounding</b> points which lie on the line, * but not safe to use for <b>truncated</b> points. */doubleLineIntersector::computeEdgeDistance(const Coordinate& p,const Coordinate& p0,const Coordinate& p1){	double dx=fabs(p1.x-p0.x);	double dy=fabs(p1.y-p0.y);	double dist=-1.0;	// sentinel value	if (p==p0) {		dist=0.0;	} else if (p==p1) {		if (dx>dy)			dist=dx;		else			dist=dy;	} 
	else {		double pdx=fabs(p.x - p0.x);		double pdy=fabs(p.y - p0.y);		if (dx > dy)			dist = pdx;		else			dist = pdy;		// <FIX>		// hack to ensure that non-endpoints always have a non-zero distance		if (dist == 0.0 && !(p==p0)) {			dist=max(pdx,pdy);		}	}	Assert::isTrue(!(dist == 0.0 && !(p==p0)), "Bad distance calculation");	return dist;}/* * This function is non-robust, since it may compute the square * of large numbers. * Currently not sure how to improve this. */doubleLineIntersector::nonRobustComputeEdgeDistance(const Coordinate& p,const Coordinate& p1,const Coordinate& p2){	double dx=p.x-p1.x;	double dy=p.y-p1.y;	double dist=sqrt(dx*dx+dy*dy);   // dummy value	Assert::isTrue(!(dist==0.0 && !(p==p1)), "Invalid distance calculation");	return dist;}LineIntersector::LineIntersector(): pa(intPt[0]), pb(intPt[1]){	precisionModel=NULL;	// alias the intersection points for ease of reference	//pa=intPt[0];	//pb=intPt[1];	result=0;}LineIntersector::~LineIntersector(){}/** * Force computed intersection to be rounded to a given precision model * @param newPM * @deprecated use <code>setPrecisionModel</code> instead */voidLineIntersector::setMakePrecise(const PrecisionModel *newPM){	precisionModel=newPM;}/** * Force computed intersection to be rounded to a given precision model. * No getter is provided, because the precision model is not required * to be specified. * @param precisionModel */voidLineIntersector::setPrecisionModel(const PrecisionModel *newPM){	precisionModel=newPM;}boolLineIntersector::isCollinear() const{	return result==COLLINEAR;}/* * Computes the intersection of the lines p1-p2 and p3-p4 */voidLineIntersector::computeIntersection(const Coordinate& p1,const Coordinate& p2,const Coordinate& p3,const Coordinate& p4){	inputLines[0][0]=p1;	inputLines[0][1]=p2;	inputLines[1][0]=p3;	inputLines[1][1]=p4;	result=computeIntersect(p1,p2,p3,p4);	//numIntersects++;}stringLineIntersector::toString() const{	string str=inputLines[0][0].toString()+"_"			  +inputLines[0][1].toString()+" "			  +inputLines[1][0].toString()+"_"			  +inputLines[1][1].toString()+" : ";	if (isEndPoint()) {		str+=" endpoint";	}	if (isProperVar) {		str+=" proper";	}	if (isCollinear()) {		str+=" collinear";	}	return str;}boolLineIntersector::isEndPoint() const{	return hasIntersection()&&!isProperVar;}/** * Tests whether the input geometries intersect. * * @return true if the input geometries intersect */boolLineIntersector::hasIntersection() const{	return result!=DONT_INTERSECT;}/** * Returns the number of intersection points found. * This will be either 0, 1 or 2. */intLineIntersector::getIntersectionNum() const{	return result;}/** * Returns the intIndex'th intersection point * * @param intIndex is 0 or 1 * * @return the intIndex'th intersection point */const Coordinate&LineIntersector::getIntersection(int intIndex) const{#if DEBUG_INTERSECT	cerr<<"LineIntersector::getIntersection("<<intIndex<<"): "<<intPt[intIndex].toString()<<endl;#endif	return intPt[intIndex];}/** * @return true if both numbers are positive or if both numbers are negative. * Returns false if both numbers are zero. */boolLineIntersector::isSameSignAndNonZero(double a,double b){	if (a==0 || b==0) {		return false;	}	return (a<0 && b<0) || (a>0 && b>0);}voidLineIntersector::computeIntLineIndex() {//	if (intLineIndex==null) {//	intLineIndex=new int[2][2];	computeIntLineIndex(0);	computeIntLineIndex(1);//}}/** * Test whether a point is a intersection point of two line segments. * Note that if the intersection is a line segment, this method only tests for * equality with the endpoints of the intersection segment. * It does <b>not</b> return true if * the input point is internal to the intersection segment. * * @return true if the input point is one of the intersection points. */boolLineIntersector::isIntersection(const Coordinate& pt) const{	for (int i=0;i<result;i++) {		if (intPt[i].equals2D(pt)) {			return true;		}	}	return false;}/** * Tests whether an intersection is proper. *  * The intersection between two line segments is considered proper if * they intersect in a single point in the interior of both segments * (e.g. the intersection is a single point and is not equal to any of the * endpoints). *  * The intersection between a point and a line segment is considered proper * if the point lies in the interior of the segment (e.g. is not equal to * either of the endpoints). * * @return true if the intersection is proper */boolLineIntersector::isProper() const{	return hasIntersection()&&isProperVar;}/** * Computes the intIndex'th intersection point in the direction of * a specified input line segment * * @param segmentIndex is 0 or 1 * @param intIndex is 0 or 1 * * @return the intIndex'th intersection point in the direction of the *         specified input line segment */const Coordinate&LineIntersector::getIntersectionAlongSegment(int segmentIndex,int intIndex){	// lazily compute int line array	computeIntLineIndex();	return intPt[intLineIndex[segmentIndex][intIndex]];}/** * Computes the index of the intIndex'th intersection point in the direction of * a specified input line segment * * @param segmentIndex is 0 or 1 * @param intIndex is 0 or 1 * * @return the index of the intersection point along the segment (0 or 1) */intLineIntersector::getIndexAlongSegment(int segmentIndex,int intIndex){	computeIntLineIndex();	return intLineIndex[segmentIndex][intIndex];}voidLineIntersector::computeIntLineIndex(int segmentIndex){	double dist0=getEdgeDistance(segmentIndex,0);	double dist1=getEdgeDistance(segmentIndex,1);	if (dist0>dist1)
	{		intLineIndex[segmentIndex][0]=0;		intLineIndex[segmentIndex][1]=1;	} 
	else {		intLineIndex[segmentIndex][0]=1;		intLineIndex[segmentIndex][1]=0;	}}/** * Computes the "edge distance" of an intersection point along the specified * input line segment. * * @param segmentIndex is 0 or 1 * @param intIndex is 0 or 1 * * @return the edge distance of the intersection point */doubleLineIntersector::getEdgeDistance(int segmentIndex,int intIndex) const{	double dist=computeEdgeDistance(intPt[intIndex],		inputLines[segmentIndex][0],		inputLines[segmentIndex][1]);	return dist;}/** * Tests whether either intersection point is an interior point of one of * the input segments. * * @return <code>true</code> if either intersection point is in the interior * of one of the input segments */boolLineIntersector::isInteriorIntersection(){	if (isInteriorIntersection(0))
		return true;	if (isInteriorIntersection(1)) 
		return true;	return false;}/** * Tests whether either intersection point is an interior point of the * specified input segment. * * @return <code>true</code> if either intersection point is in the interior * of the input segment */boolLineIntersector::isInteriorIntersection(int inputLineIndex){	for (int i=0; i<result; i++)	{		if (!(intPt[i].equals2D(inputLines[inputLineIndex][0])            		|| intPt[i].equals2D(inputLines[inputLineIndex][1])))	    	{			return true;		}	}	return false;}doubleLineIntersector::interpolateZ(const Coordinate &p,	const Coordinate &p1, const Coordinate &p2){#if DEBUG	cerr<<"LineIntersector::interpolateZ("<<p.toString()<<", "<<p1.toString()<<", "<<p2.toString()<<")"<<endl;#endif	if ( ISNAN(p1.z) )	{#if DEBUG		cerr<<" p1 do not have a Z"<<endl;#endif		return p2.z; // might be DoubleNotANumber again	}	if ( ISNAN(p2.z) )	{#if DEBUG		cerr<<" p2 do not have a Z"<<endl;#endif		return p1.z; // might be DoubleNotANumber again	}	if (p==p1)	{#if DEBUG		cerr<<" p==p1, returning "<<p1.z<<endl;#endif		return p1.z;	}	if (p==p2)	{#if DEBUG		cerr<<" p==p2, returning "<<p2.z<<endl;#endif		return p2.z;	}	//double zgap = fabs(p2.z - p1.z);	double zgap = p2.z - p1.z;	if ( ! zgap )	{#if DEBUG		cerr<<" no zgap, returning "<<p2.z<<endl;#endif		return p2.z;	}	double xoff = (p2.x-p1.x);	double yoff = (p2.y-p1.y);	double seglen = (xoff*xoff+yoff*yoff);	xoff = (p.x-p1.x);	yoff = (p.y-p1.y);	double pdist = (xoff*xoff+yoff*yoff);	double fract = sqrt(pdist/seglen);	double zoff = zgap*fract;	//double interpolated = p1.z < p2.z ? p1.z+zoff : p1.z-zoff;	double interpolated = p1.z+zoff;#if DEBUG	cerr<<" zgap:"<<zgap<<" seglen:"<<seglen<<" pdist:"<<pdist		<<" fract:"<<fract<<" z:"<<interpolated<<endl;#endif	return interpolated;}} // namespace geos/********************************************************************** * $Log: LineIntersector.cpp,v $ * Revision 1.19.2.2  2005/05/23 19:01:52  strk * Back-ported fix in Z interpolation * * Revision 1.19.2.1  2005/05/23 17:10:08  strk * Stricter C++ syntax (math.h=>cmath, ieeefp.h in "C" block) * * Revision 1.19  2004/11/29 16:05:33  strk * Fixed a bug in LineIntersector::interpolateZ causing NaN values * to come out. * Handled dimensional collapses in ElevationMatrix. * Added ISNAN macro and changed ISNAN/FINITE macros to avoid * dispendious isnan() and finite() calls. * * Revision 1.18  2004/11/26 09:53:48  strk * Added more FINITE calls, and added inf and -inf to FINITE checks * * Revision 1.17  2004/11/24 18:10:23  strk * Cleanup of interpolateZ * * Revision 1.16  2004/11/23 19:53:06  strk * Had LineIntersector compute Z by interpolation. * * Revision 1.15  2004/10/21 22:29:54  strk * Indentation changes and some more COMPUTE_Z rules * * Revision 1.14  2004/10/20 17:32:14  strk * Initial approach to 2.5d intersection() * * Revision 1.13  2004/07/02 13:28:26  strk * Fixed all #include lines to reflect headers layout change. * Added client application build tips in README. * * Revision 1.12  2004/03/17 02:00:33  ybychkov * "Algorithm" upgraded to JTS 1.4 * * Revision 1.11  2003/11/07 01:23:42  pramsey * Add standard CVS headers licence notices and copyrights to all cpp and h * files. * * **********************************************************************/

⌨️ 快捷键说明

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