如何在3D球体上绘制球面三角形?

3 投票
2 回答
3552 浏览
提问于 2025-04-16 00:47

假设你知道一个球面三角形的三个顶点。那你该如何在3D球体上画出它的边呢?

我需要一些Python代码,用于Blender这个3D建模软件。

我已经在Blender里做好了球体。

谢谢,祝你在Blender上玩得开心。

备注 1:

我在球面上有三个点/顶点(p1, p2, p3),这是一个球面三角形,但我需要在3D球体上画出边。

那么,应该用什么公式来确定三角形每对点之间的所有顶点呢?从p1到p2、从p2到p3,以及从p3到p1这三条边。

我知道这和球面上的大圆(Great circle)有关,但我找不到合适的公式来进行球坐标的计算!

谢谢。


大圆

如果能看到用大圆的解决方案,并直接在球坐标中展示,那会很有趣!

不过在欧几里得空间中做也是很有意思的。

谢谢。


好的,我用这个想法在两个点之间画线段。

但没有按照之前提到的方法去做。

我用了另一种方法——贝塞尔线插值。

我用贝塞尔线来参数化这条线,然后进行了细分,并计算了之前提到的每个细分贝塞尔点的比例和角度,效果很好且非常精确。

但我还是想看看用之前的方法是怎么做的,只是不确定如何进行迭代循环?

你是怎么把Python代码放到这里的?直接用Ctrl-V粘贴吗?

谢谢,祝你在2.5版本中玩得开心。


我确实在使用Blender的论坛,但并不能保证每次都能得到清晰的答案!

这就是我在这里试试的原因——碰碰运气。

我做了第一条边,似乎有效,现在得做一个循环来获取第一条边的多个段,然后再做其他边。

2- 另一个话题,我在这里开了一个关于贝塞尔三角形补丁的帖子。我知道这不是一个有用的工具,但只是想展示一下怎么做。

你见过用Python脚本做这些三角形补丁吗?我在Blender的论坛上问过这个问题,但没有得到答案。还有在IRC的Python频道,现在似乎也没什么人,可能大家都忙着完成2.5 Beta版本,应该在一两周内发布。

嘿,非常感谢你参与这个数学讨论,如果我有问题明天再来。

祝你数学愉快,2.5版本也玩得开心。

2 个回答

0

一个简单又便宜的方法是先画出三角形,然后把三角形的面分割成你想要的细节程度。接着,把所有的顶点调整到你想要的半径大小。

4

创建正弦网格

下面是用Python代码在Blender中创建正弦波网格的方法:

import math
import Blender
from Blender import NMesh

x = -1 * math.pi

mesh = NMesh.GetRaw()
vNew = NMesh.Vert( x, math.sin( x ), 0 )
mesh.verts.append( vNew )

while x < math.pi:
 x += 0.1
 vOld = vNew
 vNew = NMesh.Vert( x, math.sin( x ), 0 )
 mesh.verts.append( vNew )
 mesh.addEdge( vOld, vNew )

NMesh.PutRaw( mesh, "SineWave", 1 )
Blender.Redraw()

代码的详细解释可以在这里找到:http://davidjarvis.ca/blender/tutorial-04.shtml

绘制边缘的算法

画一段线和画三段线是一样的,所以我们可以把问题重新表述为:

给定两个端点,如何在球面上画一个弧?

换句话说,就是在球面上画出以下两个点之间的弧:

  • P1 = (x1, y1, z1)
  • P2 = (x2, y2, z2)

解决这个问题的方法是沿着弧 P1P2 画出很多中间点,步骤如下:

  1. 计算球的半径:
    R = sqrt( x12 + y12 + z12 )
    
  2. 计算 P1 和 P2 之间线段的中点 (m):
    Pm = (xm, ym, zm)
    xm = (x1 + x2) / 2
    ym = (y1 + y2) / 2
    zm = (z1 + z2) / 2
  3. 计算 P1 和 P2 之间线段到中点的长度:
    Lm = sqrt( xm2, ym2, zm2 )
  4. 计算球的半径与中点长度的比值:
    k = R / Lm
  5. 计算沿弧的中点:
    Am = k * Pm = (k * xm, k * ym, k * zm)

对于 P1 到 P2,创建两条边:

  • P1 到 Am
  • Am 到 P2

这两条边会穿过球体。为了解决这个问题,需要计算 P1Am 和 AmP2 之间的中点。中点越多,线段就越能贴合球面的形状。

由于Blender在计算上非常精确,最终得到的弧可能会被球体(渐近地)隐藏起来。一旦创建了三角形网格,可以将其稍微移离球体几单位(比如0.01)。

使用样条曲线

另一种解决方案是根据以下内容创建一个样条曲线

  • 球的半径(如上所述计算)
  • P1
  • Am
  • P2

生成的样条曲线必须移动到球体的前面。

Blender艺术家论坛

Blender专家也会有很好的想法来解决这个问题,可以试着问问他们。

另见

http://www.mathnews.uwaterloo.ca/Issues/mn11106/DotProduct.php

http://cr4.globalspec.com/thread/27311/Urgent-Midpoint-of-Arc-formula

撰写回答