2011-01-28 36 views
6

3D重心のようなものはありますか?私は完全に明確にしましょう。私はこのサイトとウェブ上で過去2日間の重心について読んで読んでいました。だから、Wikipediaを含むトピックに関する既存の記事を完全に認識しています。3D重心の計算方法を教えてください。

それでは、私が何をしようとしているのか説明しましょう。基本的には、エッジや頂点を選択したいが、面は選択したくない。次に、私は3D重心位置にオブジェクトを配置したいと思います。

私はしたくない何を教えてあげる:

  • より高詳細なメッシュを持っている任意の方向にすぎ引き上げる頂点の平均値を、。
  • バウンディングボックスの中心です。このシナリオでは既に何かが動作しています。

重心についての提案はありますが、頂点やエッジだけでは何も定義されていないため、これはどのように機能するのでしょうか?特にエッジループがある場合選択された。

キックのために、私はあなたを紹介します私は@Emile's codeリファレンスとして使用して、アップ働いたが、私はそれはそれが必要な方法を働いているとは思わないものもPyMEL

from pymel.core import ls, spaceLocator 
from pymel.core.datatypes import Vector 
from pymel.core.nodetypes import NurbsCurve 

def get_centroid(node): 
    if not isinstance(node, NurbsCurve): 
     raise TypeError("Requires NurbsCurve.") 
    centroid = Vector(0, 0, 0) 
    signed_area = 0.0 
    cvs = node.getCVs(space='world') 
    v0 = cvs[len(cvs) - 1] 
    for i, cv in enumerate(cvs[:-1]): 
     v1 = cv 
     a = v0.x * v1.y - v1.x * v0.y 
     signed_area += a 
     centroid += sum([v0, v1]) * a 
     v0 = v1 
    signed_area *= 0.5 
    centroid /= 6 * signed_area 
    return centroid 

texas = ls(selection=True)[0] 
centroid = get_centroid(texas) 
print(centroid) 
spaceLocator(position=centroid) 

答えて

8

と音量値がそれぞれvolumeの有限の音量に分割すると、理論的にはcentroid = SUM(pos*volume)/SUM(volume)になります。

これは、正確に複合部品の重心を見つけるために行われた計算です。

+0

私はこの回答を簡単にするつもりですが、後でそれをテストすることはできません。私はあなたの投稿を続けます。 – jedmao

2

私は疑問が好き。質量の中心は正しく聞こえますが、それでは、各頂点の質量はどのようになりますか?

なぜ頂点を含む各エッジの平均長さを使用しないのですか?これは密集したメッシュの領域を補うものでなければなりません。

+0

あなたが知っている、私はあなたがこれを投稿する前に同じことを考えていました。私は結果がどうなるのだろうか。その場合、数学は非常に単純なので、それは単に加重平均にすぎないからです。私は今眠る必要がありますが、明日これを調べます。 – jedmao

+0

このソリューションではまだ作業中です。私はあなたに最新の情報を提供しようとします。 – jedmao

+0

私は結果を見るのに興味があるでしょう。簡単なテストケースでは明らかに機能します。例えば。一方の端を定義する頂点が多く、他方の頂点が少ない頂点を持つ円柱。うまくいかない場合は、どのテストケースに問題がありますか? – Keith

3

3D重心だけでなく、n次元の重心があり、その式は、あなたが引用したWikipediaの記事の「積分式によって」で与えられます。

おそらくこの積分を設定する際に問題がありますか?あなたはあなたの形を定義していません。

[編集]私はあなたのコメントに応じてこの答えを強調します。あなたは、エッジと頂点に関して形状を記述しているので、それはpolyhedronと仮定します。ポリデッドをピラミッドに分割し、ピラミッドの重心を見つけると、図形の重心は重心の重心です(この最後の計算はja72の式を使用して行われます)。

私はあなたの形状が凸であると仮定します(中空の部分はありません---そうでない場合は凸の塊に分解してください)。内部の点をピックし、頂点にエッジを描画することでピラミッドに分割することができます(三角形分割)。あなたの形の各面がピラミッドの底です。ピラミッドの重心の数式があります(これを見ることができます。顔の重心から内点までの1/4です)。そして、あなたの形の重心は、重心の重心です---他の答えに示されているように、積分ではなく、有限の計算です。

これはHugh Bothwellの回答と同じアルゴリズムですが、私は1/4が1/3ではなく正しいと信じています。おそらく、この説明の検索用語を使用してどこかに潜んでいるコードを見つけることができます。

+0

ええ、まあ...恥ずかしげに、私は一体何がわからない。私は実際のコードを見ないと失われます。私は数式を理解していない。そしてあなたは正しい。私の形状は、頂点の集合を持っているだけでは必ずしも定義されていません。ドットを正しく接続する方法をどのように知っていますか? – jedmao

1

頂点からの顔情報を再作成する必要があります(本質的にDelauney三角形分割)。

頂点が凸包を定義している場合、オブジェクト内の任意の点Aを選択できます。あなたのオブジェクトを、頂点Aと各面をベースとするピラミッドプリズムの集合体として扱います。

各顔について、領域Faと2d重心Fcを見つけます。プリズムの質量は体積に比例します(= 1/3ベース*高さ(面に垂直なFc-Aの成分))。そして、すべてのプリズムで同じように比例定数を無視することができます。重心は(2/3 A + 1/3 Fc)、または基部の頂点から2d重心までの途中の3分の1です。

質量中心点の質量加重平均を実行すると、オブジェクト全体の3d重心を見つけることができます。

同じプロセスは、非凸形の船体または船体外のAの場合でも機能しますが、面計算が問題になることがあります。あなたはあなたの顔の譲歩に注意する必要があります。

+0

私は、これを得るために私が見つけた(そして単純化した)いくつかのDelauneyコードを活用しようとしてきましたが、私は100%正しく動作しているとは確信していません。残念ながら、私はこの問題にnumpyを頼ることはできません。このソリューションではまだ作業中です。私はあなたを更新しておきます。 – jedmao

関連する問題