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

📄 mathsubs.cpp

📁 连接oracle
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
//#include "CubSurface.h"
#include "drawcli.h"
#include "math.h"
#include "SideLine.h"
//#define MIN_DISTANCE	10		//最小跨度

/*
	判断“点”是否在任意多边形内:
	

	本算法采用射线追踪法:
	
	  过待测点的一条射线与多边形边的交点的个数,若为奇数,则在
	多边形内,否则为外部。

	实际上,我们只关心交点个数,没必要真正求出射线与边的交点。
	改进的射线与边判断是否相交的方法如下:
	
	被检测的点P(x,y)向y= -∞方向作射线。对边PiPi+1按以下顺序检测:


	若(y>=yi and  y>=yi+1)		//边在被测点P的下方
	{
		//在左右之间或过右端点:
		若( xi<x 且 x<=xi+1 ) 或 ( xi+1<x 且 x<=xi ) )
			射线与边相交。
	}
	else 若(y>=yi ||  y>=yi+1) //被测点P在边的上、下之间
	{

		//在左右之间或过右端点:
		若( (xi<x 且 x<=xi+1 ) 或 ( xi+1<x 且 x<=xi ) )
		{
			求射线(垂线)与边的交点yc
			若yc<=y
				射线与边相交。
		}
	}

*/

BOOL insideEx(float *XPV, float *YPV, int N,  double x, double y, int &LOCP)
{
	if (N<3) return 0;
	float xi,yi, xj,yj;
	xi = XPV[N-1];
	yi = YPV[N-1];
	
	int p=0;
	
	LOCP = 0;

	for (int i=0; i<N; i++)
	{
		xj = XPV[i];
		yj = YPV[i];

		if (y>=yi && y>=yj)   //点在上面 
		{
			//在左右方向之间或过右边顶点(线段其它部分在左边)
			if ( ( xi<x && x<=xj ) || ( xj<x && x<=xi)  )
			{
				p++;
			}
			if (y==yi && y==yj)	LOCP = 1;

		}
		else  if (y>=yi || y>=yj)   //点在上、下之间
		{
			if (xi==xj && x==xi)	//在垂线上
			{
				LOCP = 1;
				p++;
			}
			else if ( ( xi<x && x<=xj ) || ( xj<x && x<=xi)  )
			{
				//计算射线(垂直向下的直线)与边的交点:
				//由边的直线方程:yc = y1+(xc-x1)*(y1-y2)/(x1-x2);
				//令xc为待测点x
				double yd = yi+(x-xi)*(yi-yj)/(xi-xj);
				if (yd<=y)
				{
					if (yd==y) LOCP = 1;

					p++;
				}
			}

		}
		xi = xj;
		yi = yj;
	}

	return  (p & 1);
	
}
//整数数组的实现:

BOOL insideEx(int *XPV, int *YPV, int N,  int x, int y, int &LOCP)
{
	if (N<3) return 0;

	int xi,yi, xj,yj;

	xi = XPV[N-1];
	yi = YPV[N-1];
	
	int p=0;
	
	LOCP = 0;

	for (int i=0; i<N; i++)
	{
		xj = XPV[i];
		yj = YPV[i];

		if (y>=yi && y>=yj)   //点在上面 
		{
			//在左右方向之间或过右边顶点(线段其它部分在左边)
			if ( ( xi<x && x<=xj ) || ( xj<x && x<=xi)  )
			{
				p++;
			}
			if (y==yi && y==yj)	LOCP = 1;

		}
		else  if (y>=yi || y>=yj)   //点在上、下之间
		{
			if (xi==xj && x==xi)	//在垂线上
			{
				LOCP = 1;
				p++;
			}
			else if ( ( xi<x && x<=xj ) || ( xj<x && x<=xi)  )
			{
				//计算射线(垂直向下的直线)与边的交点:
				//由边的直线方程:yc = y1+(xc-x1)*(y1-y2)/(x1-x2);
				//令xc为待测点x
				float yd = yi+(float)(x-xi)*(yi-yj)/(xi-xj);
				if (yd<=y)
				{
					if (yd==y) LOCP = 1;

					p++;
				}
			}

		}
		xi = xj;
		yi = yj;
	}

	return  (p & 1);
	
}


//点数组的实现:

BOOL insideEx(CPoint *XYP, int N,  int x, int y, int &LOCP)
{
	if (N<3) return 0;

	int xi,yi, xj,yj;

	xi = XYP[N-1].x;
	yi = XYP[N-1].y;
	
	int p=0;
	
	LOCP = 0;

	for (int i=0; i<N; i++)
	{
		xj = XYP[i].x;
		yj = XYP[i].y;

		if (y>=yi && y>=yj)   //点在上面 
		{
			//在左右方向之间或过右边顶点(线段其它部分在左边)
			if ( ( xi<x && x<=xj ) || ( xj<x && x<=xi)  )
			{
				p++;
			}
			if (y==yi && y==yj)	LOCP = 1;

		}
		else  if (y>=yi || y>=yj)   //点在上、下之间
		{
			if (xi==xj && x==xi)	//在垂线上
			{
				LOCP = 1;
				p++;
			}
			else if ( ( xi<x && x<=xj ) || ( xj<x && x<=xi)  )
			{
				//计算射线(垂直向下的直线)与边的交点:
				//由边的直线方程:yc = y1+(xc-x1)*(y1-y2)/(x1-x2);
				//令xc为待测点x
				float yd = yi+(float)(x-xi)*(yi-yj)/(xi-xj);
				if (yd<=y)
				{
					if (yd==y) LOCP = 1;

					p++;
				}
			}

		}
		xi = xj;
		yi = yj;
	}

	return  (p & 1);
	
}

//计算曲线的长度(整数):
double calcLength(int *x, int *y, int n)
{
	int l;
 	double   lm;

	lm = 0; 
	 
	for (l=0; l<n-1; l++)
	{
 		lm = lm + sqrt( (double)(x[l+1]-x[l])*(x[l+1]-x[l])
			    +       (double)(y[l+1]-y[l])*(y[l+1]-y[l]) );
	}
	return lm;	
 
}

//计算曲线的长度(浮点):

double calcLength(float *x, float *y, int n)
{
	int l;
 	double   lm;

	lm = 0; 
	 
	for (l=0; l<n-1; l++)
	{
 		lm = lm + sqrt( (x[l+1]-x[l])*(x[l+1]-x[l])
			    +       (y[l+1]-y[l])*(y[l+1]-y[l]) );
	}
	return lm;	
 
}

 
//判断是否相交(数学意义的直线)
int testCrossed(float xa, float ya, float xb, float yb,
				float xA, float yA, float xB, float yB,
				float &xc, float &yc)
{

	double A1 = ya-yb;
	double B1 = xb-xa;
	double C1 = -xa*A1-ya*B1;

	double A2 = yA-yB;
	double B2 = xB-xA;
	double C2 = -xA*A2-yA*B2;

	double CC=A2*B1-A1*B2;
	if (CC==0) return 0;

	xc = (float)((B2*C1-B1*C2)/CC);
	yc = (float)((A1*C2-A2*C1)/CC);

	return 1;
}

//判断是否相交于第一条直线:
int testCross1( float xa, float ya, float xb, float yb,
				float xA, float yA, float xB, float yB,
				float &xc, float &yc)
{

	if (! testCrossed(	xa, ya, xb, yb, xA, yA, xB, yB, xc, yc)) return 0;
	
	//是否落在第一条线上
	if (xa<xb)
	{
		if ( xc<xa ||  xc>xb) return 0;
	}
	else
	{
		if ( xc>xa ||  xc<xb) return 0;
	}
	if (ya<yb)
	{
		if ( yc<ya ||  yc>yb) return 0;
	}
	else
	{
		if ( yc>ya ||  yc<yb) return 0;
	}
	return 1;
}

//判断是否相交于第二条直线
int testCross2( float xa, float ya, float xb, float yb,
				float xA, float yA, float xB, float yB,
				float &xc, float &yc)
{
	if (! testCrossed(	xa, ya, xb, yb, xA, yA, xB, yB, xc, yc)) return 0;


	//是否落在第二条线上
	if (xA<xB)
	{
		if ( xc<xA ||  xc>xB) return 0;
	}
	else
	{
		if ( xc>xA ||  xc<xB) return 0;
	}
	if (yA<yB)
	{
		if ( yc<yA ||  yc>yB) return 0;
	}
	else
	{
		if ( yc>yA ||  yc<yB) return 0;
	}

	return 1;
}


//判断是否相交点在二条直线上:
int testCross(	float xa, float ya, float xb, float yb,
				float xA, float yA, float xB, float yB,
				float &xc, float &yc)
{
	 
	if (! testCrossed(	xa, ya, xb, yb, xA, yA, xB, yB,  xc, yc)) return 0;

	if (xa<xb)
	{
		if (xc<xa || xc>xb) return 0;
	}
	else
	{
		if (xc>xa || xc<xb) return 0;
	}
	if (ya<yb)
	{
		if (yc<ya || yc>yb) return 0;
	}
	else
	{
		if (yc>ya || yc<yb) return 0;
	}

	if (xA<xB)
	{
		if (xc<xA || xc>xB) return 0;
	}
	else
	{
		if (xc>xA || xc<xB) return 0;
	}
	if (yA<yB)
	{
		if (yc<yA || yc>yB) return 0;
	}
	else
	{
		if (yc>yA || yc<yB) return 0;
	}
 
	return 1;
}

//判断是否相交点在二条直线上:
int testCross(	long xa, long ya, long xb, long yb,
			  long xA, long yA, long xB, long yB,
			  long &xc, long &yc)
{
	float _xc = (float)xc;
	float _yc = (float)yc;
	return testCross((float)xa, (float)ya, (float)xb, (float)yb,
		(float)xA, (float)yA, (float)xB, (float)yB,
		_xc,_yc);
}

//直线是否与多边型相交:
int crossXY(float *x, float *y, 
			float X, float Y,
			float X1,float Y1,
			float &XC, float &YC, int np)
{
	//判断是否相交于在二条直线上:
	for (int i=0; i<np; i++)
	{
		int t= testCross(
			x[i],	y[i],
			x[i+1], y[i+1],
			X,  Y,
			X1, Y1,
	 		XC, YC);
		if (t) return 1;
	}
	return 0;

}

/*
	判断一个点,是否与一条曲线(多线段)的垂直交线的交点,落在该曲线上.
	
	一个约束条件是,点到各个线段的距离(垂直距离)要小于给定的值。
*/
BOOL isVCrossAtLine(CPoint po, CPoint ps[], int nps, int &smin, int &ipos,
					double &x0,  double &y0)
{
	CPoint p1,p2;
	double A2,B2,C2;
	double s;
	double xk;
	
	double A,B,C;
	
	int issel = 0;

	nps--;

	for (int j=0; j<nps; j++)
	{
		p1 = ps[j];
		p2 = ps[j+1];

		A =  p1.y - p2.y;
		B =  p2.x - p1.x;	
		if (A==0 && B==0)
		{
			if (po.x == p1.x && po.y==p1.y)
			{
				ipos = j;
				return true;
			}
			continue;
		}

		C = -p1.x*A - p1.y*B;

		//点到直线的距离:
		s = fabs(A*po.x + B*po.y +C)/sqrt( B*B+ A*A);
 
		if (s>=smin ) continue;
	
		if (A==0) //水平线段,则过鼠标点的垂线为垂直线
		{
			x0 = po.x;
			y0 = p1.y;

			if (p1.x < p2.x)
			{
				if (po.x<p1.x || po.x>p2.x)
 					continue;
			}
			else
			{
				if (po.x<p2.x || po.x>p1.x)
					continue;
			}

			ipos = j;
			smin  = (int)s;		
			issel = true;
		}
		else if (B==0)
		{
			x0 = p1.x;
			y0 = po.y;
			
			if (p1.y < p2.y)
			{
				if (po.y<p1.y || po.y>p2.y)
					continue;
			}
			else
			{
				if (po.y<p2.y || po.y>p1.y)
					continue;
			}

			ipos = j;
			smin  = (int)s;		
			issel = true;
		}
		else
		{

			//点斜式
			xk = (float)B/A; 
			A2 = xk;
			B2 = -1;
			C2 = po.y - xk * po.x;

			x0 = - (C *B2-C2*B )/(A *B2-A2*B );
			y0 = - (C2*A -C *A2)/(A *B2-A2*B );

			if (p1.x < p2.x)
			{
				if (x0<p1.x || x0>p2.x)
					continue;
			}
 			else
			{
				if (x0<p2.x || x0>p1.x)
					continue;
			}
			if (p1.y < p2.y)
			{
				if (y0<p1.y || y0>p2.y)
					continue;
			}
			else
			{
				if (y0<p2.y || y0>p1.y)
					continue;
			}

			ipos = j;
 			smin = (int)s;		
			issel = true;
		 
		}	//end of dip-line


	}	//end for

	return issel;

}


/*
	分离的X,Y整数数组版本
*/
BOOL isVCrossAtLine(int pox, int poy, int psx[], int psy[],
					int nps, int &smin, int &ipos,
						double &x0,  double &y0)
{
	int p1x, p1y;
	int p2x, p2y;

	double A2,B2,C2;
	double s;
	double xk;
	
	double A,B,C;
	
	int issel = 0;

	nps--;
 
	for (int j=0; j<nps; j++)
	{
		p1x = psx[j];
		p1y = psy[j];

		p2x = psx[j+1];
		p2y = psy[j+1];

		A =  p1y - p2y;
		B =  p2x - p1x;
		
		if (A==0 && B==0)
		{
			if (pox == p1x && poy==p1y)
			{
				ipos = j;
				smin = 0;
				return true;
			}
			continue;
		}

		C = -p1x*A - p1y*B;

		//点到直线的距离:
		s = fabs(A*pox + B*poy +C)/sqrt( B*B+ A*A);
 
		if (s>=smin ) continue;
		if (A==0) //水平线段,则过鼠标点的垂线为垂直线
		{
			x0 = pox;
			y0 = p1y;


			if (p1x < p2x)
			{
				if (pox<p1x || pox>p2x)
 					continue;
			}
			else
			{
				if (pox<p2x || pox>p1x)
					continue;
			}

			ipos = j;
			smin  = (int)s;		
			issel = true;
		}
		else if (B==0)
		{
			x0 = p1x;
			y0 = poy;

			
			if (p1y < p2y)
			{
				if (poy<p1y || poy>p2y)
					continue;
			}
			else
			{
				if (poy<p2y || poy>p1y)
					continue;
			}

			ipos = j;
			smin  = (int)s;		
			issel = true;
		}
		else
		{

			//点斜式
			xk = B/A; 
			A2 = xk;
			B2 = -1;
			C2 = poy - xk * pox;

			if (A *B2-A2*B==0)
			{
				j=j;
			}

			x0 = - (C *B2-C2*B )/(A *B2-A2*B );
			y0 = - (C2*A -C *A2)/(A *B2-A2*B );

 
			if (p1x < p2x)
			{
				if (x0<p1x || x0>p2x)
					continue;
			}
 			else
			{
				if (x0<p2x || x0>p1x)
					continue;
			}
			if (p1y < p2y)
			{
				if (y0<p1y || y0>p2y)
					continue;
			}
			else
			{
				if (y0<p2y || y0>p1y)
					continue;
			}

			ipos = j;
 			smin = (int)s;		
			issel = true;
		 
		}	//end of dip-line


	}	//end for


	return issel;

}


/*
	分离的X,Y浮点数组版本
*/
BOOL isVCrossAtLine(float pox, float poy, float psx[], float psy[],
					int nps, float &smin, int &ipos,
						double &x0,  double &y0)
{
	float p1x, p1y;
	float p2x, p2y;

	double A2,B2,C2;
	double s;
	double xk;
	
	double A,B,C;
	
	int issel = 0;

	nps--;
 
	for (int j=0; j<nps; j++)
	{
		p1x = psx[j];
		p1y = psy[j];

		p2x = psx[j+1];
		p2y = psy[j+1];

		A =  p1y - p2y;
		B =  p2x - p1x;
		
		if (A==0 && B==0)
		{
			if (pox == p1x && poy==p1y)
			{
				ipos = j;
				smin = 0;
				return true;
			}
			continue;
		}

		C = -p1x*A - p1y*B;

		//点到直线的距离:
		s = fabs(A*pox + B*poy +C)/sqrt( B*B+ A*A);
 
		if (s>=smin ) continue;

⌨️ 快捷键说明

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