You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何生成可构成四面体的随机顶点,修复现有随机生成器异常问题

随机四面体生成器问题修复方案

现有代码核心缺陷

  • 点生成逻辑无合理性约束:p3、p4的生成上限设为p1+p2无几何意义,也没有校验四个点是否共面、共线,容易生成无效点位
  • 边长约束未生效:定义的min_len、max_len参数未实际用到,生成的四面体边长无法符合要求
  • 函数变量作用域错误:surface_normal_form函数中使用的center是外层函数的局部变量,未作为入参传入,运行时会报错

修复步骤

  1. 重写点位生成逻辑:
    • 按顺序生成四个点,每生成一个新点就校验和已有所有点的距离是否在[min_len, max_len]区间内
    • 四个点全部生成后校验混合积绝对值(判断是否共面),阈值可设为1e-6避免浮点误差,如果不符合要求就重新生成
  2. 修正surface_normal_form函数的入参,把center作为参数传入
  3. 保留原有体素化生成逻辑不变

修正后代码示例

import numpy as np
import itertools

def rand_tetrahedron_generator(bounds, min_len, max_len):
    """
    bounds: List - 每个维度的最大长度
    min_len: int - 四面体边长最小值
    max_len: int - 四面体边长最大值
    """
    assert len(bounds) == 3
    assert min_len <= max_len
    max_len = min(max_len, bounds[0], bounds[1], bounds[2])
    bounds = np.array(bounds)
    
    # 有效四面体生成循环
    while True:
        # 生成第一个点
        p1 = np.random.randint(low=0, high=bounds, size=3)
        # 生成第二个点,满足和p1的距离约束
        valid_p2 = False
        for _ in range(100):
            p2 = np.random.randint(low=0, high=bounds, size=3)
            dist = np.linalg.norm(p2-p1)
            if min_len <= dist <= max_len:
                valid_p2 = True
                break
        if not valid_p2:
            continue
        
        # 生成第三个点,满足和p1、p2的距离约束,且三点不共线
        valid_p3 = False
        for _ in range(100):
            p3 = np.random.randint(low=0, high=bounds, size=3)
            d1 = np.linalg.norm(p3-p1)
            d2 = np.linalg.norm(p3-p2)
            if not (min_len <= d1 <= max_len and min_len <= d2 <= max_len):
                continue
            # 检查是否共线:叉积不为0
            if np.linalg.norm(np.cross(p2-p1, p3-p1)) > 1e-6:
                valid_p3 = True
                break
        if not valid_p3:
            continue
        
        # 生成第四个点,满足和前三个点的距离约束,且四点不共面
        valid_p4 = False
        for _ in range(100):
            p4 = np.random.randint(low=0, high=bounds, size=3)
            d1 = np.linalg.norm(p4-p1)
            d2 = np.linalg.norm(p4-p2)
            d3 = np.linalg.norm(p4-p3)
            if not (min_len <= d1 <= max_len and min_len <= d2 <= max_len and min_len <= d3 <= max_len):
                continue
            # 检查是否共面:混合积不为0
            v1 = p2 - p1
            v2 = p3 - p1
            v3 = p4 - p1
            scalar_triple = np.dot(v3, np.cross(v1, v2))
            if abs(scalar_triple) > 1e-6:
                valid_p4 = True
                break
        if valid_p4:
            break
    
    points = np.array([p1,p2,p3,p4])
    center = np.mean(points, axis=0)
    x, y, z = (np.indices((60, 60, 60))-np.array([20,25,25]).reshape(-1,1,1,1))/8
    mx = midpoints(x)
    my = midpoints(y)
    mz = midpoints(z)
    conditions = []
    for a,b,c in itertools.combinations(points, 3):
        a_p, n = surface_normal_form(a,b,c, center)
        conditions.append((mx-a_p[0])*n[0]+(my-a_p[1])*n[1]+(mz-a_p[2])*n[2] <= 0)
    simplex = conditions[0] & conditions[1] & conditions[2] & conditions[3]
    return simplex
    
def surface_normal_form(a,b,c, center):
    v = b-a
    w = c-b
    n = np.cross(v,w)
    # 法向量朝外
    if (center-a)@n > 0:
         n *= -1
    return a, n

def midpoints(x):
    sl = ()
    for i in range(x.ndim):
        x = (x[sl + np.index_exp[:-1]] + x[sl + np.index_exp[1:]]) / 2.0
        sl += np.index_exp[:]
    return x

效果示例

四面体绘制示例图

内容的提问来源于stack exchange,提问作者zx01p

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 07:51:02