Une méthode pour calculer le centre de masse à partir d’un fichier .stl (stéréolithographie)?

J’essaie de calculer les coordonnées du centre de masse (x, y, z) d’un object défini dans un fichier STL (stéréolithographie, à ne pas confondre avec la bibliothèque de modèles standard). Le fichier STL contient un object fermé (ou des objects) défini (s) par une limite constituée de sortingangles. Les sortingangles eux-mêmes ne sont pas nécessairement dans n’importe quel ordre, le fichier est simplement constitué des coordonnées 3 sumts de chaque sortingangle flottant dans un espace 3D plus un vecteur normal au sortingangle (la normale ne doit pas être prise en compte car elle n’est pas toujours réalisée correctement). Il n’y a rien qui relie chaque sortingangle les uns aux autres, il est supposé que l’object est fermé.

Une approche simple consisterait à diviser un volume (dans ce cas une boîte) en millions d’éléments et à déterminer si chaque élément se trouve ou non à l’intérieur de l’object défini dans le fichier STL, puis à résumer les moments et à calculer le centre de gravité. Cela fonctionnerait mais c’est loin d’être élégant et extrêmement lent.

Une autre méthode consisterait à convertir la représentation des limites en un certain nombre de solides de tétraèdre tassés. Forme que je pourrais calculer le centre de masse de chaque tétraèdre, son volume et le moment résultant et ainsi calculer le centre de masse global à partir de la sum de tous les tétraèdres. Le problème avec ceci est que je ne sais pas comment convertir une représentation de surface de sortingangles en une représentation de volume de tétraèdres (je suppose que c’est une tâche relativement non sortingviale).

Quelqu’un a-t-il des méthodes ou peut-il imaginer des méthodes que je pourrais essayer? Ou peut-être même des documents de référence qui parlent de cela?

Pour plus d’informations sur les fichiers STL (seules les 2 premières sections sont importantes, tout le rest est inutile): http://en.wikipedia.org/wiki/STL_%28file_format%29

    Après beaucoup de reflection et d’expérimentation, j’ai la réponse!

    Premièrement, nous ajoutons un 4ème point à chaque sortingangle pour les transformer en tétraèdres avec un centre de volume. Nous calculons les volumes et les centres des masses et les multiplions les uns par les autres pour obtenir nos moments. Nous additionnons les moments et divisons par le volume total pour obtenir notre centroïde global.

    Nous calculons les volumes en utilisant la méthode déterminée indiquée ici (équation 32): http://mathworld.wolfram.com/Tetrahedron.html

    Les centroïdes de chacun des tétraèdres sont simplement la moyenne des 4 points.

    Le truc ici est qu’en raison de la manière dont le fichier STL est créé, les sortingangles ont une normale qui pointe vers l’extérieur de la surface de la pièce, en suivant la règle de droite des 3 sumts utilisés pour créer le sortingangle. nous pouvons utiliser cela à notre avantage en nous permettant d’avoir une convention cohérente permettant de déterminer si un volume du tétraèdre doit être ajouté ou soustrait de notre partie nette (ceci est dû au fait que le sharepoint référence que nous avons choisi ne se trouve pas nécessairement dans la partie et la partie globale n’est pas nécessairement convexe, c’est cependant un object fermé).

    En utilisant la méthode Determiner pour calculer le volume, les trois premiers points de coordonnées représenteront les trois points de notre sortingangle. Le quasortingème point serait notre origine commune. Si la normale créée par le sortingangle (suivant la règle de la main droite allant du point 1, 2, 3) pointe vers notre sharepoint référence commun, ce volume sera calculé comme ne faisant pas partie de notre volume global solide ou négatif (en pointant vers, Je veux dire que le vecteur créé par la normale du sortingangle pointe de manière lâche vers le même côté qu’un plan normal créé par le vecteur à partir du sharepoint référence situé au centroïde du tétraèdre). Si le vecteur est éloigné du sharepoint référence, il s’agit alors d’un volume positif ou à l’intérieur de la pièce. S’il est normal, le volume passe à zéro car le sortingangle est dans le même plan que le sharepoint référence.

    Nous n’avons pas à nous soucier de garder une trace de tout cela, car si nous sums cohérents avec nos entrées (comme dans les sortingangles suivent la règle de la main droite avec la face normale vers l’extérieur de la partie), la détermination nous donnera le bon signe.

    Quoi qu’il en soit, voici le code (c’est encore plus simple que l’explication).

    class data // 3 vertices of each sortingangle { public: float x1,y1,z1; float x2,y2,z2; float x3,y3,z3; }; int main () { int numTriangles; // pull in the STL file and determine number of sortingangles data * sortingangles = new sortingangles [numTriangles]; // fill the sortingangles array with the data in the STL file double totalVolume = 0, currentVolume; double xCenter = 0, yCenter = 0, zCenter = 0; for (int i = 0; i < numTriangles; i++) { totalVolume += currentVolume = (triangles[i].x1*triangles[i].y2*triangles[i].z3 - triangles[i].x1*triangles[i].y3*triangles[i].z2 - triangles[i].x2*triangles[i].y1*triangles[i].z3 + triangles[i].x2*triangles[i].y3*triangles[i].z1 + triangles[i].x3*triangles[i].y1*triangles[i].z2 - triangles[i].x3*triangles[i].y2*triangles[i].z1) / 6; xCenter += ((triangles[i].x1 + triangles[i].x2 + triangles[i].x3) / 4) * currentVolume; yCenter += ((triangles[i].y1 + triangles[i].y2 + triangles[i].y3) / 4) * currentVolume; zCenter += ((triangles[i].z1 + triangles[i].z2 + triangles[i].z3) / 4) * currentVolume; } cout << endl << "Total Volume = " << totalVolume << endl; cout << endl << "X center = " << xCenter/totalVolume << endl; cout << endl << "Y center = " << yCenter/totalVolume << endl; cout << endl << "Z center = " << zCenter/totalVolume << endl; } 

    Extrêmement rapide pour le calcul des centres de masse pour les fichiers STL.

    EDIT: Cherchez “algorithme de nombre d’enroulement” ou “algorithme de nombre de croisement” – ce que j’essaie de décrire ci-dessous est un algorithme de nombre de croisement à 3 jours.

    J’ai l’impression que quelque chose comme ça va marcher, mais je n’ai pas la capacité de le tester, pour le moment:

    Construisez la structure 3D remplie à partir des sortingangles du fichier STL de manière itérative. Commencez par choisir un point unique à utiliser comme base pour la structure 3D. Ensuite, commencez votre structure en créant une pyramide sortingangular, dont la base est définie par le premier sortingangle du fichier STL et définissez le sumt de votre choix. Chacun de ces composants de votre volume construit de manière itérative contiendrait également une “parité d’intersection” – initialisez-le à 0.

    Pour chaque sortingangle suivant dans le fichier STL, créez une pyramide similaire et vérifiez si elle intersecte la structure 3D que vous avez construite jusqu’à présent. Si tel est le cas, calculez l’intersection et segmentez la structure existante et la nouvelle pyramide de manière à ce que deux composants ne se chevauchent pas. Conservez la “parité d’intersection” de la partie la plus externe du nouveau polyèdre 0, mais basculez-la sur toutes les parties intérieures de l’intersection. Si elle était 0, définissez-la sur 1, si elle était égale à 1, définissez-la sur 0.

    À la fin, vous aurez le polyèdre fermé défini par toutes les parties de votre structure ayant une parité d’intersection égale à 0. Calculez les moments de tous ces polyèdres et faites la moyenne de ceux-ci pour obtenir votre centre de masse. Je pense que la complexité serait quelque chose comme O (n ^ 2).