geometry4Sharp Ray-Mesh求交 判断点是否在几何体内部

C# 7.3

geometry4Sharp 1.0.0

该C#代码实现了一个STL模型点位置检测器,使用geometry3Sharp库处理3D网格数据。核心功能包括:

  1. 加载STL文件并验证模型封闭性;

  2. 采用改进的射线投射算法(包含5次随机方向测试)判断点是否在模型内部;

  3. 提供单点和批量检测功能。

算法先进行快速边界框排除,再通过计算射线与三角形交点数确定位置,增强了结果的可靠性。适用于需要判断三维空间中点与STL模型位置关系的应用场景。

cs 复制代码
using g4;
using System;
using System.Collections.Generic;

public class STLPointChecker
{
  private DMesh3 mesh;
  private AxisAlignedBox3d bounds;

  public STLPointChecker(string stlFilePath)
  {
    DMesh3Builder builder = new DMesh3Builder();
    StandardMeshReader reader = new StandardMeshReader() { MeshBuilder = builder };
    IOReadResult result = reader.Read(stlFilePath, ReadOptions.Defaults);
    if (result.code == IOCode.Ok)
      mesh = builder.Meshes[0];

    if (mesh == null)
      return;

    if (!mesh.IsClosed())
      throw new Exception("STL模型不是封闭的,无法判断内外");

    bounds = mesh.CachedBounds;
  }

  // 射线法判断点是否在内部(基础可靠版)
  public bool IsPointInside(Vector3d testPoint)
  {
    if (mesh == null)
    {
      Console.WriteLine("Mesh is null");
      return false;
    }

    // 快速边界框排除
    if (!bounds.Contains(testPoint))
      return false;

    // 创建射线(沿X轴正方向)
    Ray3d ray = new Ray3d(testPoint, Vector3d.AxisX);
    int intersectionCount = 0;
    var rand = new Random();

    // 为确保稳定性,可发射多条随机方向的射线取多数结果
    for (int i = 0; i < 5; i++)
    {
      if (i > 0) // 第一次用X轴,后续用随机方向
      {
        Vector3d randomDir = new Vector3d(
            rand.NextDouble() * 2.0 - 1.0,
            rand.NextDouble() * 2.0 - 1.0,
            rand.NextDouble() * 2.0 - 1.0
        ).Normalized;
        ray = new Ray3d(testPoint, randomDir);
      }

      int count = CountRayIntersections(ray);
      if (count % 2 == 1) // 奇数个交点在内部
        intersectionCount++;
    }

    // 5条射线中3条以上认为在内部则判定为内部
    return intersectionCount >= 3;
  }

  private int CountRayIntersections(Ray3d ray)
  {
    int count = 0;

    // 遍历所有三角形
    foreach (int tid in mesh.TriangleIndices())
    {
      // 使用 geometry3Sharp 内置的高效求交方法
      IntrRay3Triangle3 intersection = new IntrRay3Triangle3(ray,
          new Triangle3d(
              mesh.GetVertex(mesh.GetTriangle(tid).a),
              mesh.GetVertex(mesh.GetTriangle(tid).b),
              mesh.GetVertex(mesh.GetTriangle(tid).c)
          )
      );

      if (intersection.Find() && intersection.IsSimpleIntersection)
      {
        if (intersection.RayParameter > 0) // 确保交点在射线正方向
          count++;
      }
    }

    return count;
  }

  // 批量检查多个点
  public Dictionary<Vector3d, bool> CheckPoints(List<Vector3d> points)
  {
    var results = new Dictionary<Vector3d, bool>();
    foreach (var point in points)
    {
      results[point] = IsPointInside(point);
    }
    return results;
  }
}

// 使用示例
//var checker = new STLPointChecker(@"E:\Data\PathPlanning\convex_hull.stl");

//// 检查单个点
//Vector3d testPoint = new Vector3d(10.0, 5.0, 2.0);
//bool inside = checker.IsPointInside(testPoint);
//Console.WriteLine($"点 ({testPoint.x}, {testPoint.y}, {testPoint.z}) 在内部: {inside}");

//// 批量检查
//var points = new List<Vector3d>
//            {
//                new Vector3d(0, 0, 0),
//                new Vector3d(50, 50, 50),
//                new Vector3d(-10, -10, -10),
//                new Vector3d(2104.38, 633.567, 775.12)
//            };

//var results = checker.CheckPoints(points);
//foreach (var kvp in results)
//{
//  Console.WriteLine($"点 {kvp.Key}: {(kvp.Value ? "内部" : "外部")}");
//}
相关推荐
恋猫de小郭1 小时前
Kotlin Toolchain 0.13,JetBrains 推荐 KMP 都切换到到全新工具链
android·前端·flutter
我是人✓1 小时前
Java面向对象核心特性深度解析
java·前端·算法
晓得迷路了1 小时前
栗子前端技术周刊第 149 期 - Vite+ 1.0、Preact 11、Next.js 16.4...
前端·javascript·react.js
IT_陈寒1 小时前
为什么我的Vue组件总是莫名其妙更新?
前端·人工智能·后端
狂师1 小时前
2026年APP自动化测试工具大全,12款主流工具一次看懂
前端·开源·测试
for_ever_love__1 小时前
LangChain Text-to-SQL:让不会写 SQL 的人查数据库
数据库·sql·langchain·大模型·agent·rag·问答
前端一小卒1 小时前
搜索 API 额度用完返回空数组,Agent 就开始一本正经地胡说
前端·javascript·node.js
Pniubi2 小时前
基于openclaw开发skill与自研agent中的skill开发区别
服务器·agent·skill·openclaw·龙虾
乘风gg2 小时前
Spec Kit vs OpenSpec vs Superpowers:三大 AI Coding 框架深度对比
前端·ai编程·claude
梦想不只是梦与想2 小时前
SQLAlchemy:查询与操作 (三)
数据库·python·sqlalchemy