unity计算三维空间下点到线,点到面,线到线,线到面,面到面最短距离的点的方法

通用的一个方法GetDistance,计算两个点的距离,不开平方

/// <summary>
/// 获取两个点的距离,不开平方
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static float GetDistance(Vector3 a, Vector3 b)
{float num = a.x - b.x;float num2 = a.y - b.y;float num3 = a.z - b.z;return num * num + num2 * num2 + num3 * num3;
}

1.计算一条线段上到一个点距离最短的点

/// <summary>
/// 获取一个点到一条线段的最近点
/// </summary>
/// <param name="point"></param>
/// <param name="lineStart"></param>
/// <param name="lineEnd"></param>
/// <returns></returns>
public static Vector3 PointToLineSegmentDistance(Vector3 point, Vector3 lineStart, Vector3 lineEnd)
{Vector3 lineDirection = lineEnd - lineStart;Vector3 pointDirection = point - lineStart;float lineLength = lineDirection.magnitude;lineDirection.Normalize();float dotProduct = Vector3.Dot(pointDirection, lineDirection);dotProduct = Mathf.Clamp(dotProduct, 0f, lineLength);Vector3 closestPoint = lineStart + lineDirection * dotProduct;return closestPoint;
}

2.计算一个三角形内距离一个点最短的点

/// <summary>
/// 获取一个点到一个三角形内最短距离的点
/// </summary>
/// <param name="a">三角形顶点a</param>
/// <param name="b">三角形顶点b</param>
/// <param name="c">三角形顶点c</param>
/// <param name="pos"></param>
/// <returns></returns>
public static Vector3 GetPosInTriangle(Vector3 a, Vector3 b, Vector3 c, Vector3 pos)
{Vector3 normal = Vector3.Cross(b - a, c - a).normalized;Vector3 toPoint = pos - a;float distance = Vector3.Dot(toPoint, normal);Vector3 targetPos = pos - distance * normal;if(PointInTriangle(targetPos, a, b, c))return targetPos;else{Vector3 p1 = PointToLineSegmentDistance(pos, a, b);Vector3 p2 = PointToLineSegmentDistance(pos, a, c);Vector3 p3 = PointToLineSegmentDistance(pos, b, c);float d1 = Vector3.Distance(p1, pos);float d2 = Vector3.Distance(p2, pos);float d3 = Vector3.Distance(p3, pos);if (d1 <= d2 && d1 <= d3)return p1;else if (d2 <= d3 && d2 <= d1)return p2;else /*if(d3 <= d1 && d3 <= d2)*/return p3;//return default;}
}/// <summary>
/// 判断一个点是否在三角形内
/// </summary>
/// <param name="pos"></param>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="c"></param>
/// <returns></returns>
public static bool PointInTriangle(Vector3 pos, Vector3 a, Vector3 b, Vector3 c)
{var v0 = c - a;var v1 = b - a;var v2 = pos - a;var dot00 = Vector3.Dot(v0, v0);var dot01 = Vector3.Dot(v0, v1);var dot02 = Vector3.Dot(v0, v2);var dot11 = Vector3.Dot(v1, v1);var dot12 = Vector3.Dot(v1, v2);var invDenom = 1 / (dot00 * dot11 - dot01 * dot01);var u = (dot11 * dot02 - dot01 * dot12) * invDenom;var v = (dot00 * dot12 - dot01 * dot02) * invDenom;// 如果u和v都在[0,1]的范围内,那么点P在三角形ABC内return (u >= 0) && (v >= 0) && (u + v < 1);
}

3.计算两条线段间距离最短的两个点,此方法不是最优方法,还需修改

/// <summary>
/// 计算两个线段的最近点
/// 此方法需要修改,现在实现的方法不是最好的方法,存在误差
/// </summary>
/// <param name="line1Point1"></param>
/// <param name="line1Point2"></param>
/// <param name="line2Point1"></param>
/// <param name="lin2Point2"></param>
/// <param name="value1"></param>
/// <param name="value2"></param>
public static float LineToLine(Vector3 line1Point1, Vector3 line1Point2, Vector3 line2Point1, Vector3 lin2Point2, out Vector3 value1, out Vector3 value2)
{List<Vector3> points = new List< Vector3>();value1 = Vector3.zero ; value2 = Vector3.zero ;//这边的方法需要修改,目前是将线段1按每距离0.1米加一个点(包括两个端点)float dis = Vector3.Distance(line1Point1, line1Point2);int count = (int)(dis * 10);Vector3 dir = (line1Point2 - line1Point1).normalized;points.Add(line1Point1);for (int i = 1; i <= count; i++){points.Add(dir * 0.1f * i + line1Point1);}points.Add(line1Point2);float minDis = float.MaxValue;//然后使用每个点计算到另一线段距离最短的点,最后比较得到距离最短的点foreach (var item in points){Vector3 p = PointToLineSegmentDistance(item, line2Point1, lin2Point2);float d = GetDistance(p, item);if(d < minDis){minDis = d;value1 = item;value2 = p;}}return minDis;
}

4.计算一条线段到一个三角面距离最短的两个点

/// <summary>
/// 计算一条线段到一个三角面距离最短的两个点
/// </summary>
/// <param name="linePoints"></param>
/// <param name="triPoints"></param>
/// <param name="value1"></param>
/// <param name="value2"></param>
public static void LineToTriangle(List<Vector3> linePoints, List<Vector3> triPoints, out Vector3 value1, out Vector3 value2)
{value1 = Vector3.zero;value2 = Vector3.zero;Vector3 pos = default;//判断线段与三角面是否相交,若相交,则距离最短的点为交点if (LineIntersectsTriangle(linePoints[0], linePoints[1], triPoints[0], triPoints[1], triPoints[2],out pos)){value1 = pos;value2 = pos;return;}//不相交的话,分别计算这条边与三角形三条边距离最短的点Vector3 p1 = default;Vector3 p2 = default;float dis1 = LineToLine(linePoints[0], linePoints[1], triPoints[0], triPoints[1], out p1, out p2);Vector3 p3 = default;Vector3 p4 = default;float dis2 = LineToLine(linePoints[0], linePoints[1], triPoints[0], triPoints[2], out p3, out p4);Vector3 p5 = default;Vector3 p6 = default;float dis3 = LineToLine(linePoints[0], linePoints[1], triPoints[2], triPoints[1], out p5, out p6);//分别计算线段的端点到三角形距离最短的点Vector3 p7 = GetPosInTriangle(triPoints[0], triPoints[1], triPoints[2], linePoints[0]);Vector3 p8 = GetPosInTriangle(triPoints[0], triPoints[1], triPoints[2], linePoints[1]);float dis4 = GetDistance(p7, linePoints[0]);float dis5 = GetDistance(p8, linePoints[1]);//比较得到最短距离的点float min = Mathf.Min(dis1, dis2, dis3, dis4, dis5);if(min == dis1){value1 = p1;value2 = p2;return;}else if(min == dis2){value1 = p3;value2 = p4;return;}else if(min == dis3){value1 = p5;value2 = p6;return;}else if(min == dis4){value1 = p7;value2 = linePoints[0];return;}else{value1 = p8;value2 = linePoints[1];return;}
}/// <summary>
/// 判断线段是否与一个三角面有交点,并得到这个交点
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="v0"></param>
/// <param name="v1"></param>
/// <param name="v2"></param>
/// <param name="pos"></param>
/// <returns></returns>
public static bool LineIntersectsTriangle(Vector3 a, Vector3 b, Vector3 v0, Vector3 v1, Vector3 v2, out Vector3 pos)
{// 计算三角形的法线Vector3 triangleNormal = Vector3.Cross(v1 - v0, v2 - v0).normalized;pos = default;// 计算线段的方向Vector3 lineDirection = b - a;// 计算线段与平面的交点float denominator = Vector3.Dot(triangleNormal, lineDirection);if (denominator != 0){// 线段与平面不平行,计算交点float t = Vector3.Dot(v0 - a, triangleNormal) / denominator;if (t >= 0 && t <= 1){// 交点在线段内部Vector3 intersectionPoint = a + t * lineDirection;// 检查交点是否在三角形内部if (PointInTriangle(intersectionPoint, v0, v1, v2)){pos = intersectionPoint;return true;}else{return false;}}else{return false;}}else{return false;}
}

5.计算两个三角形间距离最短的两个点

/// <summary>
/// 计算两个三角形间距离最短的两个点
/// </summary>
/// <param name="tri1"></param>
/// <param name="tri2"></param>
/// <param name="value1"></param>
/// <param name="value2"></param>
public static void GetPosInTriangles(List<Vector3> tri1, List<Vector3> tri2, out Vector3 value1, out Vector3 value2)
{//分别计算三角形1的三条边到三角形2的最短距离Vector3 p1 = default;Vector3 p2 = default;LineToTriangle(new List<Vector3>() { tri1[0], tri1[1] }, tri2, out p1, out p2);Vector3 p3 = default;Vector3 p4 = default;LineToTriangle(new List<Vector3>() { tri1[0], tri1[2] }, tri2, out p3, out p4);Vector3 p5 = default;Vector3 p6 = default;LineToTriangle(new List<Vector3>() { tri1[1], tri1[2] }, tri2, out p5, out p6);//Vector3 p11 = default;//Vector3 p21 = default;//LineToTriangle(new List<Vector3>() { tri2[0], tri2[1] }, tri1, out p11, out p21);//Vector3 p31 = default;//Vector3 p41 = default;//LineToTriangle(new List<Vector3>() { tri2[0], tri2[2] }, tri1, out p31, out p41);//Vector3 p51 = default;//Vector3 p61 = default;//LineToTriangle(new List<Vector3>() { tri2[1], tri2[2] }, tri1, out p51, out p61);float dis1 = GetDistance(p1, p2);float dis2 = GetDistance(p3, p4);float dis3 = GetDistance(p5, p6);//float dis4 = GetDistance(p11, p21);//float dis5 = GetDistance(p31, p41);//float dis6 = GetDistance(p51, p61);//比较得到面之间距离最短的点float min = Mathf.Min(dis1, dis2, dis3/*, dis4, dis5, dis6*/);if(min == dis1){value1 = p1;value2 = p2;return;}else if(min == dis2){value1 = p3;value2 = p4;return;}else/* if(min == dis3)*/{value1 = p5;value2 = p6;return;}//else if(min == dis4)//{//    value1 = p11;//    value2 = p21;//    return;//}//else if(min == dis5)//{//    value1 = p31;//    value2 = p41;//    return;//}//else//{//    value1 = p51;//    value2 = p61;//    return;//}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/4456.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

猫咪冻干究竟怎么选不踩雷?这几款生骨肉冻干一定适合你家喵

315中国之声的报道揭示了河北省邢台市南和区某宠粮代工厂的“行业秘密”&#xff0c;这无疑给广大宠物主人敲响了警钟。配料表上标注的鸡肉含量高达52%&#xff0c;新鲜鸡小胸占20%&#xff0c;然而所谓的鲜鸡肉实际上却是鸡肉粉。我们养宠物本是为了心灵上的慰藉&#xff0c;但…

栈和队列总结

文章目录 前言一、栈和队列的实现1.栈的具体实现2.循环顺序队列的具体实现 二、栈和队列总结总结 前言 T_T此专栏用于记录数据结构及算法的&#xff08;痛苦&#xff09;学习历程&#xff0c;便于日后复习&#xff08;这种事情不要啊&#xff09;。所用教材为《数据结构 C语言版…

揭秘Linux文件系统

前言 在上一篇文件描述符详解中谈论的都是打开的文件&#xff0c;但是在我们的系统中不仅有打开的文件还有许多未打开的文件&#xff0c;那么这些未打开的文件又该如何理解呢?阅读完本篇文章相信你会得到答案。 如果觉得文章内容对你有所帮助的话&#xff0c;可以给博主一键三…

langfuse使用零星记录

目录 前言 一、langfuse是什么&#xff1f; 二、使用零星记录 1.评估打分 2.score的问题与解决 总结 前言 langfuse使用过程的一些坑点&#xff0c;做一些记录&#xff0c;便于日后回顾查找&#xff0c;也为同样在学习的小伙伴们异同一些可能的帮助。 期望在学习使用一…

centos7.9离线安装rke2

使用rke2安装k8s,master节点有三台&#xff0c;agent节点一台&#xff0c;三台master通过etcd存储保证master节点的高可用&#xff0c;使用nginx对master进行负载均衡。 主机清单如下 ip主机名称用途192.168.16.72node72server节点192.168.16.73node73master节点192.168.16.7…

常用excel操作笔记

一、表达式 1. 查找excel中一列值出现在另外一列中 IF(SUMPRODUCT(--(ISNUMBER(SEARCH($A$1:$A$101,C2)))),1,0) 2.计算某个字符出现的次数 LEN(G2)-LEN(SUBSTITUTE(G2,">",))1 3.拼接字符串 C2&"|"&A2 4.根据当前日期生成19位id TEXT(TODAY…

MySQL语句,使用replace替换数据后,有小数时,使用round等方法无法取整

15.55这个数字 replace替换数据后乘以100&#xff0c;在Navicat中运行&#xff0c;是显示整数 但是在Python中调用SQL语句&#xff0c;使用replace替换数据并乘以100后&#xff0c;会显示有一位小数&#xff0c;并且使用round等方法无法取整 最终采用cast函数将replace后的数…

新装电脑Flutter环境部署坑汇总(持续更新)

1.本地安装&#xff0c;安装fvm的坑 本人电脑使用windows &#xff0c;安装fvm则一般使用choco安装&#xff0c;那么首先需要安装choco,打开powershell/或者cmd运行以下命令&#xff1a; Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager…

5.2 海思SS928开发 - kernle开发 - 构建脚本

5.2 kernle开发 - 构建脚本 SS928 kernel 提供了 makefile 用于 kernel 构建。想要得到最后的内核镜像&#xff0c;还要经过许多步骤&#xff0c;每次都手敲命令的话&#xff0c;会把我累死。自己实现一个构建脚本&#xff0c;支持以下常用功能即可&#xff1a; 构建内核镜像配…

图像置乱加密-Arnold加密算法

置乱加密是另一种较常用的加密方法&#xff0c;现也被许多文献选用&#xff0c;置乱加密可以是以像素为单位进行全局置乱&#xff0c;该方式打乱了图像像素值的位置&#xff0c;使其图像内容失去相关性&#xff0c;达到保护的目的。也可以是以块为单位进行置乱&#xff0c;该方…

Kafka报错ERROR Exiting Kafka due to fatal exception during startup

报错&#xff1a; ERROR Exiting Kafka due to fatal exception during startup. (kafka.Kafka$) kafka.common.InconsistentClusterIdException: The Cluster ID FSzSO50oTLCRhRnRylihcg doesnt match stored clusterId Some(0oSLohwtQZWbIi73YUMs8g) in meta.properties. Th…

某宝因SSL证书过期无法正常访问,证书过期问题频发企业如何破局?

近日&#xff0c;有网友发现&#xff0c;某宝网站无法正常访问&#xff0c;出现“此连接非私人连接”提示&#xff0c;而导致此类提示的罪魁祸首是因为SSL证书过期&#xff01;其实&#xff0c;近年来&#xff0c;因SSL证书过期导致的网站无法正常访问的事件频频发生&#xff0…

vue2—— mixin 超级详细!!!

mixin Mixin是面向对象程序设计语言中的类&#xff0c;提供了方法的实现。其他类可以访问mixin类的方法而不必成为其子类 Mixin类通常作为功能模块使用&#xff0c;在需要该功能时“混入”&#xff0c;有利于代码复用又避免了多继承的复杂 vue中的mixin 先来看一下官方定义 mi…

YOLO-yolov5构建数据集

1.收集数据集 创建一个dataset文件夹用来存放图片数据集。 我这里使用的图片数据集&#xff0c;是对一段视频进行抽帧得到的200张狗狗图片。 在dataset文件夹下新建images和labels文件夹&#xff0c;并将200张狗狗图片放入images中。 2.标注数据集 2.1安装标注工具labelimg…

Jenkins邮件发送失败问题解决

如下提示为 Extended E-mail Notification开启Debug模式下显示的错误信息&#xff0c; (Debug模式设置方法&#xff1a;Dashboard-> manage Jenkins->configure System)DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM XOAUTH2 DEB…

Projector投影器-Unity使用Projector投影器实现简单的阴影

在Unity中&#xff0c;可以使用Projector投影器来实现简单的阴影效果。Projector投影器是一种用于在场景中投射纹理的组件&#xff0c;可以用来模拟光照、阴影等效果。 要使用Projector投影器实现阴影效果&#xff0c;可以按照以下步骤进行操作&#xff1a; 创建一个空对象&am…

OpenCV——Bernsen局部阈值二值化方法

目录 一、Bernsen算法1、算法概述2、参考文献二、代码实现三、结果展示Bernsen局部阈值二值化方法由CSDN点云侠原创,爬虫自重。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、Bernsen算法 1、算法概述 Bernsen 算法是另一种流行的局部阈值二值化方…

网络相关知识总结

1、网口设置 网口设置IP&#xff0c;即操作/etc/sysconfig/network-scripts路径下的ifcfg-xx文件 主要参数详解&#xff1a; DEVICE:网口名 ONBOOT&#xff1a;表示启动系统时是否激活网卡&#xff0c;yes为激活&#xff0c;no不激活 HWADDR:mac值 DEFROUTE://默认路由设置…

Docker容器:docker基础

目录 一.docker前言 云计算服务模式 关于 docker 产品 虚拟化产品有哪些&#xff1f; ① 寄居架构 ② 源生架构 虚拟化技术概述 主流虚拟化产品对比 1. VMware系列 2. KVM/OpenStack 3. Xen 4. 其他半/全虚拟化产品 二. docker 的相关知识 1. docker 的概念 doc…

[linux网络编程]UDP协议和TCP协议的使用

目录 看以下内容前&#xff0c;你要先了解main函数带参数有什么用、 了解socket的相关函数接口 如果不了解socket的相关函数接口请先看我这篇文章 main函数带参数有什么用 UDP udp_server 1.生成socket文件描述符 2.填充sockaddr_in信息 3.bind 4.发&#xff08;收&…