unity C# 计算3D空间任意多边形面积,距离,角度测量工具
2022/6/23 1:20:04
本文主要是介绍unity C# 计算3D空间任意多边形面积,距离,角度测量工具,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
效果图
代码:
using UnityEngine; using System.Collections.Generic; using System; /// <summary> /// 划线面积,距离,角度 /// </summary> public class UnderlinedMeasureTool : MonoBehaviour { /// <summary> /// 相机 /// </summary> public Camera _camera; public int size = 30;//文字大小 //圆点的预制体 public GameObject aim; public LineRenderer lineRender; bool sb = false; //GL 绘制的顶点数组 顺序是 0->1 2->3 4->5 取法 0 1 3 5 7 9 //参考UI界面 private List<Vector3> lv;//划线的点 private List<Vector3> lv1;//存坐标的点 public List<GameObject> aims; public int type = 3; void Start() { lv = new List<Vector3>(); lv1 = new List<Vector3>(); aims = new List<GameObject>(); } void Update() { if (Input.GetMouseButtonDown(0))//绘制多边形 { Ray ray = _camera.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit, Mathf.Infinity)) { //创建圆点 GameObject go = Instantiate(aim, new Vector3(hit.point.x, hit.point.y, hit.point.z), Quaternion.Euler(90, 0, 0)) as GameObject; aims.Add(go); lv1.Add(hit.point); if (type == 1) { if (lv.Count >= 2) { ClearLines(); GameObject go1 = Instantiate(aim, new Vector3(hit.point.x, hit.point.y, hit.point.z), Quaternion.Euler(90, 0, 0)) as GameObject; aims.Add(go1); lv1.Add(hit.point); lv.Add(hit.point); } else { lv.Add(hit.point); } } else if (type == 2) { if (lv.Count >= 3) { ClearLines(); GameObject go1 = Instantiate(aim, new Vector3(hit.point.x, hit.point.y, hit.point.z), Quaternion.Euler(90, 0, 0)) as GameObject; aims.Add(go1); lv1.Add(hit.point); lv.Add(hit.point); } else if (lv.Count >= 2) { if (sb) { lv.RemoveAt(lv.Count - 1); lv.RemoveAt(lv.Count - 1); } lv.Add(hit.point); sb = true; } else { lv.Add(hit.point); } } else if (type == 3) { if (lv.Count >= 2) { //存入点就是反复存入来自动连线,0--1 1--2 2--3.。。。。类似这格式存储点 if (sb) { lv.RemoveAt(lv.Count - 1); lv.RemoveAt(lv.Count - 1); } lv.Add(lv[lv.Count - 1]); lv.Add(hit.point); lv.Add(lv[0]); lv.Add(hit.point); sb = true; } else { lv.Add(hit.point); } } } //print(lv.Count); lineRender.positionCount = lv.Count; lineRender.SetPositions(lv.ToArray()); } } void OnGUI() { GUIStyle text = new GUIStyle(); text.fontSize = size; // 利用gui 为了实时动态更新画线数据 if (lv.Count >= 2) { //除了第一个点和最后个点,其它点都是存了两遍 for (int i = 0; i < lv.Count - 1; i = i + 2) { Vector3 s = new Vector3((lv[i].x + lv[i + 1].x) / 2, (lv[i].y + lv[i + 1].y) / 2, (lv[i].z + lv[i + 1].z) / 2); Vector3 a = _camera.WorldToScreenPoint(s); //注意屏幕坐标系与GUI的ui坐标系y轴相反,ToString(".000")保留小数点后3位数,几个零几位数 //显示线段的长度 GUI.Label(new Rect(a.x- size, Screen.height - a.y, 50, 20), "<color=red>" + Vector3.Distance(lv[i], lv[i + 1]).ToString(".000") + "</color>" + "<color=blue>" + "m" + "</color>",text); } } //显示面积 if (lv1.Count > 2 && type == 3) { Vector3 a = _camera.WorldToScreenPoint(lv1[0]); GUI.Label(new Rect(a.x - 0, Screen.height - a.y, 50, 20), "<color=yellow>" + Compute_3D_polygon_area(lv1).ToString(".00") + "</color>" + "<color=blue>" + "㎡" + "</color>", text); } //显示角度 if (lv1.Count == 3 && type == 2) { Vector3 a = _camera.WorldToScreenPoint(lv1[1]); GUI.Label(new Rect(a.x, Screen.height - a.y, 50, 20), "<color=yellow>" + Angle(lv1[1], lv1[0], lv1[lv1.Count - 1]).ToString(".000") + "</color>" + "<color=blue>" + "℃" + "</color>", text); } } // 清除重新测量 public void ClearLines() { if (lv == null) return; sb = false; for (int i = 0; i < aims.Count; i++) { Destroy(aims[i]); } lv.Clear(); lv1.Clear(); aims.Clear(); lineRender.positionCount = 0; } //计算任意多边形的面积,顶点按照顺时针或者逆时针方向排列,不需要考虑y轴的坐标. 2D public double ComputePolygonArea(List<Vector3> points) { int point_num = points.Count; if (point_num < 3) return 0.0; float s = points[0].y * (points[point_num - 1].x - points[1].x); for (int i = 1; i < point_num; ++i) s += points[i].y * (points[i - 1].x - points[(i + 1) % point_num].x); return Mathf.Abs(s / 2.0f); } public double Compute_3D_polygon_area(List<Vector3> points) { //points为任意多边形的点集合 注意输入时要按环的流动输入,不能乱序输入 //此方法是3D空间的,相较于2D更具有普适性 if (points.Count < 3) return 0.0; var P1X = points[0][0]; var P1Y = points[0][1]; var P1Z = points[0][2]; var P2X = points[1][0]; var P2Y = points[1][1]; var P2Z = points[1][2]; var P3X = points[2][0]; var P3Y = points[2][1]; var P3Z = points[2][2]; var a = Mathf.Pow(((P2Y - P1Y) * (P3Z - P1Z) - (P3Y - P1Y) * (P2Z - P1Z)), 2) + Mathf.Pow(((P3X - P1X) * (P2Z - P1Z) - (P2X - P1X) * (P3Z - P1Z)), 2) + Mathf.Pow(((P2X - P1X) * (P3Y - P1Y) - (P3X - P1X) * (P2Y - P1Y)), 2); var cosnx = ((P2Y - P1Y) * (P3Z - P1Z) - (P3Y - P1Y) * (P2Z - P1Z)) / (Mathf.Pow(a, 0.5f)); var cosny = ((P3X - P1X) * (P2Z - P1Z) - (P2X - P1X) * (P3Z - P1Z)) / (Mathf.Pow(a, 0.5f)); var cosnz = ((P2X - P1X) * (P3Y - P1Y) - (P3X - P1X) * (P2Y - P1Y)) / (Mathf.Pow(a, 0.5f)); var s = cosnz * ((points[points.Count - 1][0]) * (P1Y) - (P1X) * (points[points.Count - 1][1])) + cosnx * ((points[points.Count - 1][1]) * (P1Z) - (P1Y) * (points[points.Count - 1][2])) + cosny * ((points[points.Count - 1][2]) * (P1X) - (P1Z) * (points[points.Count - 1][0])); for (int i = 0; i < points.Count-1; i++) { var p1 = points[i]; var p2 = points[i + 1]; var ss = cosnz * ((p1[0]) * (p2[1]) - (p2[0]) * (p1[1])) + cosnx * ((p1[1]) * (p2[2]) - (p2[1]) * (p1[2])) + cosny * ((p1[2]) * (p2[0]) - (p2[2]) * (p1[0])); s += ss; } return Mathf.Abs(s / 2.0f); } //计算夹角 public double Angle(Vector3 cen, Vector3 first, Vector3 second) { double M_PI = 3.1415926535897931; double ma_x = first.x - cen.x; double ma_y = first.y - cen.y; double ma_z = first.z - cen.z; double mb_x = second.x - cen.x; double mb_y = second.y - cen.y; double mb_z = second.z - cen.z; double v1 = (ma_x * mb_x) + (ma_y * mb_y) + (ma_z * mb_z); double ma_val = Math.Sqrt(ma_x * ma_x + ma_y * ma_y + ma_z * ma_z); double mb_val = Math.Sqrt(mb_x * mb_x + mb_y * mb_y + mb_z * mb_z); double cosM = v1 / (ma_val * mb_val); double angleAMB = Math.Acos(cosM) * 180 / M_PI; return angleAMB; } }
原文链接:https://blog.csdn.net/qq_22972867/article/details/120452678
这篇关于unity C# 计算3D空间任意多边形面积,距离,角度测量工具的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2024-12-06使用Microsoft.Extensions.AI在.NET中生成嵌入向量
- 2024-11-18微软研究:RAG系统的四个层次提升理解与回答能力
- 2024-11-15C#中怎么从PEM格式的证书中提取公钥?-icode9专业技术文章分享
- 2024-11-14云架构设计——如何用diagrams.net绘制专业的AWS架构图?
- 2024-05-08首个适配Visual Studio平台的国产智能编程助手CodeGeeX正式上线!C#程序员必备效率神器!
- 2024-03-30C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
- 2024-03-29c# datetime tryparse
- 2024-02-21list find index c#
- 2024-01-24convert toint32 c#