<script type="text/JavaScript"> alimama_pid="mm_10249644_1605763_4929893"; alimama_titlecolor="0000FF"; alimama_descolor ="000000"; alimama_bgcolor="FFFFFF"; alimama_bordercolor="E6E6E6"; alimama_linkcolor="008000"; alimama_bottomcolor="FFFFFF"; alimama_anglesize="0"; alimama_bgpic="0"; alimama_icon="0"; alimama_sizecode="16"; alimama_width=658; alimama_height=60; alimama_type=2; </script> <script src="http://a.alimama.cn/inf.js" type=text/javascript> </script>
点在面算法,就是放射线算法,原理很简单,就是把一个点向任意方向发射(本程序是向下),如果跟这个面有奇数个交点,证明点在面里面,若是偶数个,则是在外面(包括0),算法主要是优化效率。本人水平有限,算法中肯定有不足之处,请大家海涵!
主要函数如下。<script type="text/JavaScript"> alimama_pid="mm_10249644_1605763_5018464"; alimama_type="f"; alimama_sizecode ="tl_1x1_8"; alimama_fontsize=12; alimama_bordercolor="FFFFFF"; alimama_bgcolor="FFFFFF"; alimama_titlecolor="0000FF"; alimama_underline=0; alimama_height=22; alimama_width=0; </script> <script src="http://a.alimama.cn/inf.js" type=text/javascript> </script>
- struct TabPoint
- {
- private double x;
- public double X
- {
- get { return x; }
- set { x = value; }
- }
- private double y;
- public double Y
- {
- get { return y; }
- set { y = value; }
- }
- }
- struct Polygon
- {
- public ArrayList pointsArray;
- private double minx;
- public double MinX
- {
- get { return minx; }
- set { minx = value; }
- }
- private double miny;
- public double MinY
- {
- get { return miny; }
- set { miny = value; }
- }
- private double maxx;
- public double MaxX
- {
- get { return maxx; }
- set { maxx = value; }
- }
- private double maxy;
- public double MaxY
- {
- get { return maxy; }
- set { maxy = value; }
- }
- }
- class Analyse
- {
- private readonly double dis = 0.0000000001;
- //返回值:true点在面内 false点在面外
- public bool JudgeMeetPoint(TabPoint tpt, ArrayList polygonPtArray)
- {
- int MeetPointNum = 0;
- int PolygonPtSize = polygonPtArray.Count;
- for (int k = 1; k < PolygonPtSize; k++)
- {
- TabPoint pt1 = (TabPoint)polygonPtArray[k - 1];
- TabPoint pt2 = (TabPoint)polygonPtArray[k];
- if (((tpt.X <= pt1.X && tpt.X >= pt2.X) ||
- (tpt.X >= pt1.X && tpt.X <= pt2.X)) &
- (tpt.Y >= pt1.Y || tpt.Y >= pt2.Y) &
- (pt1.X != pt2.X && pt1.Y != pt2.Y))
- {
- //判断点是否在线上
- if (JudgePtInLine(pt1, pt2, tpt))
- {
- return true;
- }
- //处理特殊情况,交点是端点的情况
- double temp;
- //temp相当于被除数(斜率的分母)
- temp = pt1.X - pt2.X;
- if (temp >= -dis && temp <= dis)
- {
- //处理交点情况
- double dx = tpt.X - pt1.X;
- if (dx >= -dis && dx <= dis)
- {
- int[] indexs = new int[2];
- indexs[0] = 0;
- indexs[1] = 0;
- GetNotSame(polygonPtArray, k, ref indexs);
- TabPoint linePt1, linePt2;
- linePt1 = (TabPoint)polygonPtArray[indexs[0]];
- linePt2 = (TabPoint)polygonPtArray[indexs[1]];
- if (k > indexs[0])
- {
- break;
- }
- else
- {
- k = indexs[0] + 1;
- }
- if (tpt.Y > pt1.Y && ((tpt.X >= linePt1.X && tpt.X <= linePt2.X) ||
- (tpt.X >= linePt2.X && tpt.X <= linePt1.X)))
- MeetPointNum++;
- }
- }
- else
- {
- double kk, bb;
- double MeetPtY, MeetPtX;
- kk = (pt1.Y - pt2.Y) / (pt1.X - pt2.X);
- bb = pt1.Y - kk * pt1.X;
- MeetPtY = kk * tpt.X + bb;
- MeetPtX = tpt.X;
- //处理特殊情况,交点是端点的情况
- double dx, dy, dx2, dy2;
- dx = MeetPtX - pt1.X;
- dy = MeetPtY - pt1.Y;
- dx2 = MeetPtX - pt2.X;
- dy2 = MeetPtY - pt2.Y;
- if ((dx >= -dis && dx <= dis && dy >= -dis
- && dy <= dis))
- {
- TabPoint pt3;
- if (k == 1)
- {
- pt3 = (TabPoint)polygonPtArray[PolygonPtSize - 2];
- }
- else
- {
- pt3 = (TabPoint)polygonPtArray[k - 2];
- }
- //提取交点的上下两点分别在垂线的两侧
- if (tpt.Y > MeetPtY && ((MeetPtX >= pt3.Y && MeetPtX <= pt2.X) ||
- (MeetPtX >= pt2.X && MeetPtX <= pt3.X)))
- MeetPointNum++;
- }
- else if (!(dx2 >= -dis && dx2 <= dis && dy2 >= -dis
- && dy2 <= dis))
- {
- if (tpt.Y > MeetPtY)
- MeetPointNum++;
- }
- }
- }
- }
- if (MeetPointNum % 2 == 1)
- return true;
- else
- return false;
- }
- //判断点是否在线上
- private bool JudgePtInLine(TabPoint tpt1, TabPoint tpt2, TabPoint tpt)
- {
- double dx1 = GetDistance(tpt1, tpt2);
- double dx2 = GetDistance(tpt, tpt1);
- double dx3 = GetDistance(tpt, tpt2);
- double dx = dx3 + dx2 - dx1;
- if (dx >= -0.0000000001 && dx <= 0.0000000001)
- {
- return true;
- }
- return false;
- }
- //求取两点之间的距离
- private double GetDistance(TabPoint tpt1, TabPoint tpt2)
- {
- double x = tpt1.X - tpt2.X;
- if (x <= 0)
- {
- x = -x;
- }
- double y = tpt1.Y - tpt2.Y;
- if (y <= 0)
- {
- y = -y;
- }
- return System.Math.Sqrt(x * x + y * y);
- }
- //在链表中获取x轴不相同的点
- private void GetNotSame(ArrayList pointArray, int index, ref int[] indexs)
- {
- indexs[0] = indexs[1] = -1;
- int size = pointArray.Count;
- TabPoint buftpt, tpt;
- tpt = (TabPoint)pointArray[index];
- for (int i = index; i < size; i++)
- {
- buftpt = (TabPoint)pointArray[i];
- if (buftpt.X != tpt.X)
- {
- indexs[0] = i;
- break;
- }
- }
- if (indexs[0] == -1)
- {
- for (int i = 0; i < size; i++)
- {
- buftpt = (TabPoint)pointArray[i];
- if (buftpt.X != tpt.X)
- {
- indexs[0] = i;
- break;
- }
- }
- }
- for (int j = index; j >= 0; j--)
- {
- buftpt = (TabPoint)pointArray[j];
- if (buftpt.X != tpt.X)
- {
- indexs[1] = j;
- break;
- }
- }
- if (indexs[1] == -1)
- {
- for (int j = size - 1; j >= 0; j--)
- {
- buftpt = (TabPoint)pointArray[j];
- if (buftpt.X != tpt.X)
- {
- indexs[1] = j;
- break;
- }
- }
- }
- }
- public bool JudgeInRect(TabPoint minPt,TabPoint maxPt,TabPoint pt)
- {
- if (pt.X >= minPt.X && pt.X <= maxPt.X && pt.Y >= minPt.Y && pt.Y <= maxPt.Y)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- <script type="text/JavaScript"> alimama_pid="mm_10249644_1605763_5027492"; alimama_type="f"; alimama_sizecode ="tl_1x5_8"; alimama_fontsize=12; alimama_bordercolor="FFFFFF"; alimama_bgcolor="FFFFFF"; alimama_titlecolor="0000FF"; alimama_underline=0; alimama_height=22; alimama_width=0; </script> <script src="http://a.alimama.cn/inf.js" type=text/javascript> </script> }