剑侠情缘剧情分集介绍:判断点是否在线上的方法(线段的点选)

来源:百度文库 编辑:偶看新闻 时间:2024/05/05 06:31:00

// 绿色的是4个点;本代码真实可用,同事从网络上面得到,出处不详,经kiseigo整理
// 其中的关键点在于,不要用测量坐标来表示容许误差(单位:m),而应该把测量坐标先转换成象素,这样就可以很清楚的知道应该是多少个象素范围内(如5个象素),不随着比例尺的变化而变化。
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
///
/// 点是否点中了线
///

class ClickOnLine
{
///
/// 点是否在直线上
///

///
/// 线的起点
///
/// 容许误差
/// 在线上返回true
public static bool IsPtInLine(Point ptCurr, Point pStart, Point pEnd, int allowErr)
{
CCADCoord pt = new CCADCoord(ptCurr.X, ptCurr.Y);
CCADCoord p1 = new CCADCoord(pStart.X, pStart.Y);
CCADCoord p2 = new CCADCoord(pEnd.X, pEnd.Y);
int n = PtInPolyLine(pt, p1, p2, allowErr);
if (n == 1)
{
return true;
}
else
{
return false;
}
}
///
/// 判断给定点 pt 是否在折线上: 1:在折线上;0:不在折线上
///

/// 待判断的点
/// 折线坐标列表
/// 容差值(该值应包括线的宽度,如为零则表示精确匹配)
/// 1:在折线上;0:不在折线上
public static int PtInPolyLine(CCADCoord pt, CCADCoord l1, CCADCoord l2, double allowError)
{
//如果选择的点与当前点重合
if (Math.Abs(l2.X - pt.X) <= allowError && Math.Abs(l2.Y - pt.Y) <= allowError)
return 1;
if (Math.Min(l1.X, l2.X) <= pt.X && Math.Min(l1.Y, l2.Y) <= pt.Y &&
Math.Max(l1.X, l2.X) >= pt.X && Math.Max(l1.Y, l2.Y) >= pt.Y)
{
//精确匹配判断的话
if (Math.Abs(allowError - 0.0) <= 0.0001)
{
#region 该方法理论上是100%可行的,但是在实际过程中,用户的点击往往是模糊的,大概的,所以该方法就会出现问题
CCADCoord tp1 = new CCADCoord(l2.X - pt.X, l2.Y - pt.Y);  //矢量减法
CCADCoord tp2 = new CCADCoord(pt.X - l1.X, pt.Y - l1.Y);  //矢量减法
if (Math.Abs(Math.Abs(tp1.X * tp2.Y - tp2.X * tp1.Y) - 0.0) <= 0.00000001)         //矢量叉乘,平行四边形的面积
return 1;
#endregion
}
else
{
if (Math.Abs(l2.X - l1.X) <= allowError && Math.Abs(l2.X - pt.X) <= allowError)
return 1;
if (Math.Abs(l2.Y - l1.Y) <= allowError && Math.Abs(l2.Y - pt.Y) <= allowError)
return 1;
if (DistancePointToSegment(pt, l1, l2) <= allowError)
return 1;
//如果点到线段的距离在容差范围内,则选取成功
if (DistancePointToSegment(pt, l1, l2) <= allowError)
return 1;
}
}
return 0;
}
///
/// 点到线段的距离公式(利用平行四边形的面积算法,非常牛叉)
///

/// 目标点
/// 线段端点A
/// 线段端点B
///
public static double DistancePointToSegment(CCADCoord P, CCADCoord A, CCADCoord B)
{
//计算点到线段(a,b)的距离
double l = 0.0;
double s = 0.0;
l = DistancePointToPoint(A, B);
s = ((A.Y - P.Y) * (B.X - A.X) - (A.X - P.X) * (B.Y - A.Y)) / (l * l);
return (Math.Abs(s * l));
}
///
/// 点到点的距离
///

///
///
///
private static double DistancePointToPoint(CCADCoord ptA, CCADCoord ptB)
{
return Math.Sqrt(Math.Pow(ptA.X - ptB.X, 2) + Math.Pow(ptA.Y - ptB.Y, 2));
}
///
/// 坐标
///

public struct CCADCoord
{
public double X;
public double Y;
///
/// 构造函数
///

///
///
public CCADCoord(double x, double y)
{
X = x;
Y = y;
}
}
}
使用的时候:鼠标点击在picturebox上
private void picWork_MouseUp(object sender, MouseEventArgs e)
{
Point pMouse = new Point(e.X, e.Y);
int idInShapes = -1;
int idInLine = -1;
bool bln = GetIndexInShapesAndLine(pMouse, _drawGrid._shapes, 5, ref idInShapes, ref idInLine);
if (bln)
{
this.Text = "第" + idInShapes.ToString() + "个图形上, 点中此折线第" + idInLine.ToString() + "条线段";
}
else
{
this.Text = "没有找到图形";
}
}
///
/// 点是否在线上,返回在第n个图形(点,线,圆)上
///

///
/// 所有图形
/// 容许误差,单位:象素
/// 第n个图形(圆),如果不在,返回-1
/// 折线的第n条直线,第一条是0
/// 在线上返回true
private bool GetIndexInShapesAndLine(Point pMouse, List shapes, int allowErr,
ref int idInShape, ref int idInLine)
{
int x = 0;
int y = 0;
Point pStart = new Point();
Point pEnd = new Point();
bool isInLine = false;
int id = -1;
int id2 = -1;
foreach (KiseiShape sh in shapes)
{
id++;
if (sh is KiseiGrapLine)
{
isInLine = false;
id2 = -1;
for (int i = 0; i <= (sh as KiseiGrapLine).m_line.Count - 2; i++)
{
id2++;
_convertor.Grid2Screen((sh as KiseiGrapLine).m_line[i].north,
(sh as KiseiGrapLine).m_line[i].east, ref x, ref y);
pStart = new Point(x, y);
_convertor.Grid2Screen((sh as KiseiGrapLine).m_line[i + 1].north,
(sh as KiseiGrapLine).m_line[i + 1].east, ref x, ref y);
pEnd = new Point(x, y);
if (ClickOnLine.IsPtInLine(pMouse, pStart, pEnd, allowErr))
{
idInShape = id;
idInLine = id2;
isInLine = true;
break;
}
}
if (isInLine)
{
break;
}
}
} // end of foreach
if (isInLine)
{
return true;
}
else
{
return false;
}
}
求证:到线段两端距离相等的点,在线段的垂直平分线上?请写出证明过程. 线段的黄金分割点是什么? 线段的轴点在那里? 判断铜球是否空心的方法 火灾起火点的判断方法 如何判断线段与矩形是否相交? 任意线段上的点和平面上的点一样多,谁能给出严格证明? 已知线段AB=10厘米,平面上有一点,若AP=6厘米,当P点在线段AB以外时,PB的长度有什么要求? 设C是线段AB的黄金分割点,在线段AC上取点D,使CD=CB,求证:D是线段CA的黄金分割点。 不在同一条直线上的四个点,五个点,最多可化成几条线段呢?? 比较两条线段长短的方法 急问:什么是线段的黄金分割点 几何问题:线段AB上有点C,点C使AC:CB=2:3,点M和点N分别是线段AC和线段CB的中点,若MN=3,则AN的长是( ) CAD如何在一条线段上均分几个点了的?急 不在同一直线上的四个点最多可以连成几条线段 请问有没有简便的方法判断是否患有抑郁症 判断一个个体是否是纯和体的方法 液晶显示屏上出来一条白色的线段 点C是线段AB上一点,M是线段BC的中点,可以有AM=1/2(AB+AC)的结论吗? 如图所示,点C,D是线段AB上的两点。CD:AB=2:5,AD+BC=14cm求线段CD和AB的长。 知道线段的端点的坐标和一个点的坐标,求点到线段的距离? A,M,B,C,N,D这几个点在线段上依次排列.B,C是线段上任意两点,且AM=BM,CN=ND,若MN=a,BC=b,求AD的长 "因为1厘米的线段上有无数个点,而太平洋上也有无数个点,所以1厘米线段上的点和与太平洋上的点一样多."对吗 用AfxMessageBox弹出的对话框,如何用判断条件来判断是否点了OK