GIS算法基础——计算点到直线、射线、线段的距离
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
点到线距离的计算
1、作业说明
1.1 任务
点到线距离的计算(包括直线、射线、线段)
1.2 要求
人机交互,鼠标屏幕取点进行计算,输出计算结果
2、程序说明
2.1 大体上分三步进行:
2.1.1 首先进行画线操作:鼠标在屏幕上取两点(鼠标左键两点)
1、画线段
直接利用DrawLine函数,将在屏幕上获取的两点坐标传递给函数的参数即可。
2、画直线
由于直线是无限的,所以此时要借助于屏幕上所取两点的直线方程,通过求出
与所在容器边缘的交点,结合具体情况,将求出的交点的坐标传递给DrawLine
函数的参数,即可画出当前范围内的直线形状。
3、画射线
画射线与画直线的思路大致相同,不过需判断射线的方向,此处借助所取的第
二个点和第一个点的位置关系判断方向,最后再将所取的第一个点和求得的射
线方向与容器边缘的交点坐标传递给DrawLine函数的参数即可。
2.1.2 开始绘制第三个点(鼠标右键取该点)
借助于DrawEllipse函数(详情参见代码部分)
2.1.3 线和点绘制完成后,开始进行距离的计算
1、点到直线的距离:可直接利用点到线之间的距离公式
2、点到线段的距离:由于点在线段上的投影可能不在线段上,故还需要求出点到
线段两端点坐标的距离,再将最小值作为结果输出
3、点到射线的距离:同理,若点的投影不在射线上,则其最小距离为点到射线起
始端点的距离
2.2 窗体界面介绍
首先是ComeBox,对其添加三项:计算点到线段的距离、计算点到直线的距离、计算点到射线的距离
在PictureBox里进行点和线的绘制,在TextBox里显示点到线的距离值
3、源代码
using System;
using System.Collections.Generic;
using ponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace me
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//首先定义两个变量:屏幕上所取的两个点
private Point m_ptStart; private Point m_ptEnd;
//定义两个集合:myplist存放用于画线的两个点,pt存放第三个点
List
List
//result用来存放点到线的距离值
double result;
//自定义方法:两点之间的距离
double ptdis(Point p0, Point p1)
{
return System.Math.Sqrt((p1.X - p0.X) * (p1.X - p0.X) + (p1.Y - p0.Y) * (p1.Y - p0.Y));
}
//自定义最大最小值函数
double max(double x, double y)
{
return x > y ? x : y;
}
double min(double x, double y)
{
return x > y ? y : x;
}
//自定义方法:点和线之间的距离
double pldis(Point p0, Point p1, Point p2)
{
double result;
double A = p2.Y - p1.Y;
double B = p1.X - p2.X;
double C = p2.X * p1.Y - p1.X * p2.Y;
result = System.Math.Abs(A * p0.X + B * p0.Y + C) /
System.Math.Sqrt(A * A + B * B);
return result;
}
//自定义方法:获取点在线上的投影
Point GetProjectPt(Point p0, Point p1, Point p2)
{
Point ProjectPt=new Point();
if (p2.X == p1.X)
{
ProjectPt.X = p1.X;
ProjectPt.Y = p0.Y;
}
else
{
double k = (p2.Y - p1.Y) / (p2.X - p1.X);
ProjectPt.X = (int)((k * p1.X + p0.X / k + p0.Y - p1.Y)/(k+1/k));
ProjectPt.Y = (int)(-1 / k * (ProjectPt.X - p0.X) + p0.Y);
}
return ProjectPt;
}
/*当comboBox1里面的项改变时,清除之前的所有数据
比如计算点到直线的距离时,清除点到线段的距离*/
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
myplist.Clear();
textBox1.Text = "";
Graphics g = pictureBox1.CreateGraphics();
g.Clear(Color.White);
}
// 对pictureBox1的MouseDown事件进行编辑,当鼠标按下时,会产生哪些操作
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
Pen blue = new Pen(Color.Blue, 3);
Graphics g = pictureBox1.CreateGraphics();
//当按下鼠标左键时,在屏幕上取两点画线
if (e.Button == MouseButtons.Left)
{
Point p = new Point(e.X, e.Y);
myplist.Add(p);
}
//当按下鼠标右键时,在屏幕上取第三个点
if (e.Button == MouseButtons.Right)
{
Point p = new Point(e.X, e.Y);
pt.Clear();//改变所取的第三个点时,清除上一次的数据(距离)和图形(点)
g.Clear(Color.White);
pt.Add(p);
//此处将第三个点画成椭圆形式
g.DrawEllipse(blue, pt[0].X, pt[0].Y, 1, 1);
//在取点的同时,进行点到线距离的计算,并将结果值显示在textBox1上
Point p3 = new Point();
p3 = GetProjectPt(pt[0], m_ptStart,m_ptEnd);//获取点在线上的投影点
//分情况讨论
if(comboBox1.Text=="计算点到线段的距离")
{
if (p3.X >max(m_ptStart.X,m_ptEnd.X ) || p3.X < min( m_ptStart.Y,m_ptEnd.Y))