求空间内两条直线的最近距离以及最近点的坐标(C++)

关键词:空间几何

用途:总有地方会用到吧

文章类型:C++函数展示

@Author:V_Shawn

@Date:2016-11-19

@Lab: [email protected]

对于空间内的两条直线A,B我假设他们一定不平行,也不相交。若已知A上两点A1、A2,B上两点B1、B2,那么可以很容易得到两条直线的方程。

然后调用函数即可解得结果:

下面提供了一个用于解决这个问题的类:

#include <math.h>

//用于求解两条空间直线的最近距离,以及他们最近的两点坐标
//author @vshawn
//url:http://www.cnblogs.com/singlex/p/6091659.html
//date:2016-11-22
class GetDistanceOf2linesIn3D
{
public:
	//输入直线A的两个点,以便获得A的方程
	void SetLineA(double A1x, double A1y, double A1z, double A2x, double A2y, double A2z)
	{
		a1_x = A1x;
		a1_y = A1y;
		a1_z = A1z;

		a2_x = A2x;
		a2_y = A2y;
		a2_z = A2z;
	}

	//输入直线B的两个点,以便获得B的方程
	void SetLineB(double B1x, double B1y, double B1z, double B2x, double B2y, double B2z)
	{
		b1_x = B1x;
		b1_y = B1y;
		b1_z = B1z;

		b2_x = B2x;
		b2_y = B2y;
		b2_z = B2z;
	}

	//用SetLineA、SetLineB输入A、B方程后
	//调用本函数解出结果
	void GetDistance()
	{
		//方法来自:http://blog.csdn.net/pi9nc/article/details/11820545

		double d1_x = a2_x - a1_x;
		double d1_y = a2_y - a1_y;
		double d1_z = a2_z - a1_z;

		double d2_x = b2_x - b1_x;
		double d2_y = b2_y - b1_y;
		double d2_z = b2_z - b1_z;

		double e_x = b1_x - a1_x;
		double e_y = b1_y - a1_y;
		double e_z = b1_z - a1_z;

		double cross_e_d2_x, cross_e_d2_y, cross_e_d2_z;
		cross(e_x, e_y, e_z, d2_x, d2_y, d2_z, cross_e_d2_x, cross_e_d2_y, cross_e_d2_z);
		double cross_e_d1_x, cross_e_d1_y, cross_e_d1_z;
		cross(e_x, e_y, e_z, d1_x, d1_y, d1_z, cross_e_d1_x, cross_e_d1_y, cross_e_d1_z);
		double cross_d1_d2_x, cross_d1_d2_y, cross_d1_d2_z;
		cross(d1_x, d1_y, d1_z, d2_x, d2_y, d2_z, cross_d1_d2_x, cross_d1_d2_y, cross_d1_d2_z);

		double t1, t2;
		t1 = dot(cross_e_d2_x, cross_e_d2_y, cross_e_d2_z, cross_d1_d2_x, cross_d1_d2_y, cross_d1_d2_z);
		t2 = dot(cross_e_d1_x, cross_e_d1_y, cross_e_d1_z, cross_d1_d2_x, cross_d1_d2_y, cross_d1_d2_z);
		double dd = norm(cross_d1_d2_x, cross_d1_d2_y, cross_d1_d2_z);
		t1 /= dd*dd;
		t2 /= dd*dd;

		//得到最近的位置
		PonA_x = (a1_x + (a2_x - a1_x)*t1);
		PonA_y = (a1_y + (a2_y - a1_y)*t1);
		PonA_z = (a1_z + (a2_z - a1_z)*t1);

		PonB_x = (b1_x + (b2_x - b1_x)*t2);
		PonB_y = (b1_y + (b2_y - b1_y)*t2);
		PonB_z = (b1_z + (b2_z - b1_z)*t2);

		distance = norm(PonB_x - PonA_x, PonB_y - PonA_y, PonB_z - PonA_z);
	}

	double PonA_x;//两直线最近点之A线上的点的x坐标
	double PonA_y;//两直线最近点之A线上的点的y坐标
	double PonA_z;//两直线最近点之A线上的点的z坐标
	double PonB_x;//两直线最近点之B线上的点的x坐标
	double PonB_y;//两直线最近点之B线上的点的y坐标
	double PonB_z;//两直线最近点之B线上的点的z坐标
	double distance;//两直线距离
private:
	//直线A的第一个点
	double a1_x ;
	double a1_y ;
	double a1_z ;
	//直线A的第二个点
	double a2_x ;
	double a2_y ;
	double a2_z ;

	//直线B的第一个点
	double b1_x;
	double b1_y ;
	double b1_z ;

	//直线B的第二个点
	double b2_x;
	double b2_y ;
	double b2_z ;

	//点乘
	double dot(double ax, double ay, double az, double bx, double by, double bz) { return ax*bx + ay*by + az*bz; }
	//向量叉乘得到法向量,最后三个参数为输出参数
	void cross(double ax, double ay, double az, double bx, double by, double bz, double& x, double& y, double& z)
	{
		x = ay*bz - az*by;
		y = az*bx - ax*bz;
		z = ax*by - ay*bx;
	}
	//向量取模
	double norm(double ax, double ay, double az) { return sqrt(dot(ax, ay, az, ax, ay, az)); }
};

使用方法:

		GetDistanceOf2linesIn3D g;//初始化
		g.SetLineA(a1.x, a1.y, a1.z, a2.x, a2.y, a2.z);//输入直线A上的两个点坐标
		g.SetLineB(b1.x, b1.y, b1.z, b2.x, b2.y, b2.z);//输入直线B上的两个点坐标
		g.GetDistance();//计算距离
		double d = g.distance;//获得距离
		double x = g.PonA_x;//获得AB间最近的两点中A线上的点的x坐标
		double y = g.PonA_y;//获得AB间最近的两点中A线上的点的y坐标
		double z = g.PonA_z;//获得AB间最近的两点中A线上的点的z坐标

 

下载:

https://1drv.ms/u/s!AmjBsmo7u4eFmDpYL9FSBJurEQQ7

时间: 2024-08-05 11:16:04

求空间内两条直线的最近距离以及最近点的坐标(C++)的相关文章

求平面内两条直线的交点

The  and  coordinates of the point of intersection of two non-vertical lines can easily be found using the following substitutions and rearrangements. Suppose that two lines have the equations  and  where  and  are the slopes (gradients) of the lines

求两条直线(线段)的交点

转自: http://blog.csdn.net/dgq8211/article/details/7952825 如图,如何求得直线 AB 与直线 CD 的交点P? 以上内容摘自<算法艺术与信息学竞赛>. 思路就是利用叉积求得点P分线段DC的比,然后利用高中学习的定比分点坐标公式求得分点P的坐标. 看不懂的可以去复习下 定比分点 的知识. 1 #include <math.h> 2 #include <stdio.h> 3 #include <string.h&g

poj1039——计算几何 求直线与线段交点,判断两条直线是否相交

poj1039——计算几何  求直线与线段交点,判断两条直线是否相交 Pipe Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9439   Accepted: 2854 Description The GX Light Pipeline Company started to prepare bent pipes for the new transgalactic light pipeline. During the de

【图形】点与直线位置判断(求点位于那两条直线之间)

应用情况: 给出一系列车道线(首尾端点),希望找出车位于哪个车道上.由于数据来源于图像投影,车道线彼此并不平行. 方案A: 假设车道线都在90度左右,则可直接利用点的x坐标与车道线两端平均x坐标距离进行判断.取x坐标距离最近的两条直线 方案B: 进一步推广到任意方向的直线,则可求点到车道线的距离.取点到直线距离最近的两条 参考:Point到直线 y = kx + b 距离 distance = abs(k * Point.x -  Point.y + b)/sqrt(k * k + 1); 方案

判断两条直线是否相交点

#pragma mark ------------ 判断两条直线是否相交 + (BOOL)checkLineIntersection:(CGPoint)p1 p2:(CGPoint)p2 p3:(CGPoint)p3 p4:(CGPoint)p4 {     CGFloat denominator = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y);          if (denominator == 0.0f) {

POJ1269:Intersecting Lines(判断两条直线的关系)

题目:POJ1269 题意:给你两条直线的坐标,判断两条直线是否共线.平行.相交,若相交,求出交点. 思路:直线相交判断.如果相交求交点. 首先先判断是否共线,之后判断是否平行,如果都不是就直接求交点了. #include <iostream> #include <string.h> #include <stdio.h> #include <algorithm> #include <math.h> #include <queue> #

判断两条直线的位置关系 POJ 1269 Intersecting Lines

两条直线可能有三种关系:1.共线     2.平行(不包括共线)    3.相交. 那给定两条直线怎么判断他们的位置关系呢.还是用到向量的叉积 例题:POJ 1269 题意:这道题是给定四个点p1, p2, p3, p4,直线L1,L2分别穿过前两个和后两个点.来判断直线L1和L2的关系 这三种关系一个一个来看: 1. 共线. 如果两条直线共线的话,那么另外一条直线上的点一定在这一条直线上.所以p3在p1p2上,所以用get_direction(p1, p2, p3)来判断p3相对于p1p2的关

计算两条直线的交点(C#)

从其他地方看到的源码是有问题的. /// <summary> /// 计算两条直线的交点 /// </summary> /// <param name="lineFirstStar">L1的点1坐标</param> /// <param name="lineFirstEnd">L1的点2坐标</param> /// <param name="lineSecondStar"

渐行渐远的两条直线

两条直线曾经交汇过,之后便渐行渐远.毫无交集的两个时空,要怎样才可以相遇.除非,以光年的速度.一直努力屏蔽内心真实的需求,只为了固执地想维持曾经的美好.就好像,你不愿意走,可是还是会被时间推着往前走,心境和认知最终还是超越了爱情.想扑腾几下,却也终究是徒劳无功,因为,时光无法倒流.