vs2010程序求两点间的距离_...单击“确定”按钮时显示两点之间的距离。
《PCL点云库学习&VS2010(X64)》Part 30 空间中求一点到两点所构成的直线的距离
参考1
最近在做叶面重建的工作,构建叶面TIN的算法中会用到3维中点到直线的距离方程,一开始以为像二维一样有公式之类的,后来找了一下没有找到,就写了一个函数,分享一下。
double dis_3D(Point a,Point b,Point s){
double ab=sqrt(pow((a.X-b.X),2.0)+pow((a.Y-b.Y),2.0)+pow((a.Z-b.Z),2.0));
double as=sqrt(pow((a.X-s.X),2.0)+pow((a.Y-s.Y),2.0)+pow((a.Z-s.Z),2.0));
double bs=sqrt(pow((s.X-b.X),2.0)+pow((s.Y-b.Y),2.0)+pow((s.Z-b.Z),2.0));
double cos_A=(pow(as,2.0)+pow(ab,2.0)-pow(bs,2.0))/(2*ab*as);
double sin_A=sqrt(1-pow(cos_A,2.0));
return as*sin_A;
}
基本数学原理就是用余弦定理求出夹角,再求正弦值,然后求出高,
即点到线的距离。
注1:该函数是利用一点到两点确定的直线的距离来计算的,为空间中的S点到空间中A、B两点所成直线的距离。
当然,PCL提供了一个计算角度的函数,个人觉得比上述的合理,上面的函数可以稍作修改即可。
函数如下:
double pcl::getAngle3D(const Eigen::Vector4f &v1, const Eigen::Vector4f &v2, const bool in_degree)
{
//compute the actural angle
double rad = v1.normalized().dot(v2.normalized());//分别将方向向量归一化,然后点乘,得到余弦角,注:此处得到的是弧度角
if( rad < -1.0 )
rad = -1.0;
else if( rad > 1.0 )
rad = 1.0;
return (in_degree ? acos(rad) * 180.0 / M_PI : acos(rad));
}
上面函数是Eigen::Vector4f格式的向量,最后一个值是用0填充的,用来补齐矩阵,方便运算。当然,还提供了三个值格式的向量:Eigen::Vector3f,同时提供了对应的getAngle3D函数,其实两个是一样的,只要有方向向量就可以得到这两个向量。两者也可以相互转换,详细的内容参照矩阵平移旋转章节。
函数如下:
double pcl::getAngle3D(const Eigen::Vector3f &v1, const Eigen::Vector3f &v2, const bool in_degree)
{
//compute the actural angle
double rad = v1.normalized().dot(v2.normalized());//分别将方向向量归一化,然后点乘,得到余弦角,注:此处得到的是弧度角
if( rad < -1.0 )
rad = -1.0;
else if( rad > 1.0 )
rad = 1.0;
return (in_degree ? acos(rad) * 180.0 / M_PI : acos(rad));
}
注2:
bool in_degree这个函数变量表示以角度输出还是以弧度输出,函数最后一句很明显。
要求定义一个Point类,包括
(1)两个私有字段表示两个坐标值。
(2)一个构造函数通过传入的参数对坐标值初始化
(3)两个只读属性对坐标值的读取
(4)一个方法包含一个Point类对象作为参数对象和自己的距离
?
设计界面
?
编写如下代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;
namespace g { ? ? public partial class Form1 : Form ? ? { ? ? ? ? public Form1() ? ? ? ? { ? ? ? ? ? ? InitializeComponent(); ? ? ? ? }
? ? ? ? private void Form1_Load(object sender, EventArgs e) ? ? ? ? {
? ? ? ? }
? ? ? ? private void button1_Click(object sender, EventArgs e) ? ? ? ? { ? ? ? ? ? ? Point p1 = new Point(Convert.ToInt32( textBox1.Text) ,Convert .ToInt32( textBox2.Text)); ? ? ? ? ? ? Point p2 = new Point(Convert .ToInt32(textBox3.Text ),Convert .ToInt32(textBox4 .Text )); ? ? ? ? ? ? label8.Text = p1.Distance(p2).ToString (); ? ? ? ? } ? ? } ? ? class Point? ? ? { ? ? ? ? private int x; ? ? ? ? private int y; ? ? ? ? public Point(int x,int y) ? ? ? ? { ? ? ? ? ? ? this.x = x; ? ? ? ? ? ? this.y = y; ? ? ? ? } ? ? ? ? public int X? ? ? ? ? { ? ? ? ? ? ? get? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? return x; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? public int Y ? ? ? ? { ? ? ? ? ? ? get? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? return y; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? public double Distance(Point p) ? ? ? ? { ? ? ? ? ? ? return System.Math.Sqrt((this.X - p.X) * (this.X - p.X) + (this.Y - p.Y) * (this.Y - p.Y)); ? ? ? ? } ? ? } }
运行结果:
从Google Map上弄来的根据经纬度求地球表面两点间距离的实现,?稍微改编了一下,对于我国境内空间距离计算,该实现已经够用,以米为单位。.Net2.0,C#实现。
????? ?public static double DistanceOfTwoPoints(double lng1,double lat1,? double lng2, double lat2, GaussSphere gs)??????? {??????????? ??????????? double radLat1 = Rad(lat1);??????????? double radLat2 = Rad(lat2);??????????? double a = radLat1 - radLat2;??????????? double b = Rad(lng1) - Rad(lng2);??????????? double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) +???????????? Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2)));??????????? s = s * (gs == GaussSphere.WGS84 ? 6378137.0 : (gs == GaussSphere.Xian80 ? 6378140.0 : 6378245.0));??????????? s = Math.Round(s * 10000) / 10000;??????????? return s;??????? }??????? ??????? private static double Rad(double d)??????? {??????????? return d * Math.PI / 180.0;??????? }
??? GaussSphere 为自定义枚举类型??? ///