2011-01-28 16 views
6

¿Existe incluso algo así como un centroide 3D? Permítanme ser perfectamente claro: he estado leyendo y leyendo acerca de los centroides durante los últimos 2 días tanto en este sitio como en la web, así que estoy perfectamente al tanto de las publicaciones existentes sobre el tema, incluido el Wikipedia.¿Cómo calculo un centroide 3D?

Dicho esto, déjame explicarte lo que estoy tratando de hacer. Básicamente, quiero tomar una selección de bordes y/o vértices, pero NO caras. Entonces, quiero colocar un objeto en la posición del centroide 3D.

te voy a decir lo que no quiero:

  • Los vértices promedio, que tire demasiado lejos en cualquier dirección que tiene una malla más alto-detallada.
  • El centro del cuadro delimitador, porque ya tengo algo que funciona para este escenario.

Estoy abierto a sugerencias sobre el centro de masa, pero no veo cómo esto funcionaría, porque los vértices o los bordes por sí solos no definen ningún tipo de masa, especialmente cuando solo tengo un bucle de borde seleccionado.

Para patadas, te voy a mostrar algunos PyMEL que trabajé hacia arriba, usando @Emile's code como referencia, pero no creo que esté funcionando como debería:

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) 

Respuesta

8

En teoría centroid = SUM(pos*volume)/SUM(volume) cuando divide la pieza en volúmenes finitos, cada uno con una ubicación pos y un valor de volumen volume.

Este es precisamente el cálculo realizado para encontrar el centro de gravedad de una pieza compuesta.

+0

Voy a aceptar esta respuesta por simplicidad, pero no podré probarla hasta más adelante. Te mantendré informado. – jedmao

2

me gusta la pregunta. El centro de masa suena bien, pero la pregunta es: ¿qué masa para cada vértice?

¿Por qué no utilizar la longitud promedio de cada borde que incluye el vértice? Esto debería compensar muy bien las áreas con una malla densa.

+0

Ya sabes, estaba pensando lo mismo minutos antes de publicar esto. Me pregunto cuál sería el resultado. Porque la matemática sería extremadamente simple en ese caso porque sería solo un promedio ponderado. Necesito dormir ahora, pero lo investigaré mañana. – jedmao

+0

Aún trabajando en esta solución. Trataré de mantenerte actualizado. – jedmao

+0

Me interesará ver el resultado. Claramente funcionará para algunos casos de prueba simples. P.ej. Un cilindro con muchos vértices que definen un extremo y menos en el otro. Si no funciona, ¿qué casos de prueba son un problema? – Keith

3

No hay solo un centroide 3D, hay un centroide n-dimensional, y la fórmula para ello se da en la sección "Por fórmula integral" del artículo de Wikipedia que cita.

¿Tal vez tenga problemas para configurar esta integral? No has definido tu forma.

[Editar] Voy a reforzar esta respuesta en respuesta a su comentario. Como ha descrito su forma en términos de bordes y vértices, supongo que es polyhedron. Puede dividir un poliedro en pirámides, encontrar los centroides de las pirámides y luego el centroide de su forma es el centroide de los centroides (este último cálculo se realiza con la fórmula de ja72).

Supongo que su forma es convexa (sin partes huecas --- si este no es el caso, divídalo en trozos convexos). Puede dividirlo en pirámides (triangularlo) seleccionando un punto en el interior y dibujando bordes en los vértices. Entonces, cada cara de tu forma es la base de una pirámide. Hay fórmulas para el centroide de una pirámide (puede buscar esto, está a 1/4 del camino desde el centroide de la cara hasta su punto interior). Entonces, como se dijo, el centroide de su forma es el centroide de los centroides, el cálculo finito de ja72, no una integral, como se da en la otra respuesta.

Este es el mismo algoritmo que en la respuesta de Hugh Bothwell, sin embargo, creo que 1/4 es correcto en lugar de 1/3. Tal vez pueda encontrar algún código para que aceche en alguna parte usando los términos de búsqueda en esta descripción.

+0

Sí, bueno ... vergonzosamente, ni siquiera sé qué es una integral. Me pierdo cuando no veo el código real. No entiendo las fórmulas. Y tienes razón Mi forma no está necesariamente definida cuando solo tengo una colección de vértices. ¿Cómo sabría cómo conectar los puntos correctamente? – jedmao

1

Tendrá que volver a crear la información de la cara de los vértices (esencialmente una triangulación de Delauney).

Si sus vértices definen un casco convexo, puede elegir cualquier punto arbitrario A dentro del objeto. Trate su objeto como una colección de prismas piramidales que tienen el vértice A y cada cara como base.

Para cada cara, encuentre el área Fa y el centroide 2d Fc; entonces la masa del prisma es proporcional al volumen (== 1/3 base * altura (componente de Fc-A perpendicular a la cara)) y puede ignorar la constante de proporcionalidad siempre que haga lo mismo para todos los prismas; el centro de masa es (2/3 A + 1/3 Fc), o un tercio del camino desde el ápice hasta el 2do centroide de la base.

Puede hacer un promedio ponderado de masa de los puntos del centro de masa para encontrar el centroide 3d del objeto como un todo.

El mismo proceso debería funcionar para cascos no convexos, o incluso para A fuera del casco, pero el cálculo facial puede ser un problema; Tendrás que tener cuidado con la destreza de tus caras.

+0

He intentado aprovechar algún código de Delauney que encontré (y simplifiqué) para que funcione, pero no estoy 100% seguro de que esté funcionando correctamente. Desafortunadamente, no puedo confiar en numpy para este. Todavía estoy trabajando en esta solución. Te mantendré informado. – jedmao

Cuestiones relacionadas