2

i get tired to calculate the volume of 3D object (Cube, Cylinder ...) can any one help

with this problem ? the question is , how to calculate the volume of object from his

coordinates based on triangles. my class don't do well the job , any one help me to

emproove the class ?

thanks

public class Algorithm
{
    private  Mesh _mesh { get; set; }

    public Algorithm(Mesh mesh)
    {
        _mesh = mesh;
    }

    private double SignedVolumeOfTriangle(Vector3 p1, Vector3 p2, Vector3 p3)
    {
        var v321 = p3.X * p2.Y * p1.Z;
        var v231 = p2.X * p3.Y * p1.Z;
        var v312 = p3.X * p1.Y * p2.Z;
        var v132 = p1.X * p3.Y * p2.Z;
        var v213 = p2.X * p1.Y * p3.Z;
        var v123 = p1.X * p2.Y * p3.Z;
        return (1.0 / 6.0) * (-v321 + v231 + v312 - v132 - v213 + v123);
    }

    public double VolumeOfMesh()
    {
        double volume = 0.0;

        Vector3[] vertices = _mesh.Vertices;
        int[] triangles = _mesh.Triangles;

        for (int i = 0; i < _mesh.Triangles.Length; i += 3)
        {
            Vector3 p1 = vertices[triangles[i + 0]];
            Vector3 p2 = vertices[triangles[i + 1]];
            Vector3 p3 = vertices[triangles[i + 2]];

            volume += SignedVolumeOfTriangle(p1, p2, p3);
        }

        return Math.Abs(volume);
    }
}



public  class Mesh
{
    public Mesh(Vector3[] _vertices,int[] _triangles)
    {
        Vertices = _vertices;
        Triangles = _triangles;
    }

    public Vector3[] Vertices { get; set; }

    public int[] Triangles { get; set; }
}


public class Vector3
{
    public Vector3()
    {

    }

    public Vector3(double x,double y,double z)
    {
        X = x;
        Y = y;
        Z = z;
    }

    public double X { get; set; }

    public double Y { get; set; }

    public double Z { get; set; }
}



private void button1_Click(object sender, EventArgs e)
{
        Vector3[] vers = new Vector3[8] {
                                    new Vector3 {X = 5,Y = 5,Z =5},
                                    new Vector3 {X = 15,Y = 5,Z =5},
                                    new Vector3 {X = 15,Y = 15,Z =5},
                                    new Vector3 {X = 5,Y = 15,Z =5},
                                    new Vector3 {X = 5,Y = 5,Z =15},
                                    new Vector3 {X = 15,Y = 5,Z =15},
                                    new Vector3 {X = 15,Y = 15,Z =15},
                                    new Vector3 {X = 5,Y = 15,Z =15},
        };

        int[] trs = new int[36] { 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 
                                  1, 6, 2, 1, 5, 6, 0, 4, 7, 0, 7, 3,
                                  0, 1, 5, 0, 5, 4, 3, 2, 6,3, 6, 7 };


        Mesh mesh = new Mesh(vers, trs);
        Algorithm algo = new Algorithm(mesh);
        var vol = algo.VolumeOfMesh();

        MessageBox.Show(vol.ToString());
}

The result of my test is vol = 666,666 but it should be 1000.

Emond
  • 50,210
  • 11
  • 84
  • 115
Ali
  • 23
  • 1
  • 4

1 Answers1

3

The line

double v132 = (p3.X - basePoint.X) * (p3.Y - basePoint.Y) * (p2.Z - basePoint.Z);

Is not correct according to How to calculate the volume of a 3D mesh object the surface of which is made up triangles it should be (notice the p1.X instead of p3.X):

var v132 = p1.X*p3.Y*p2.Z;

EDIT

Although you marked this answer as correct I tested the code and found more errors.

The triangles are not all facing outward (or inward) by adjusting the triangle indices like this:

0, 1, 2,
0, 2, 3,
4, 6, 5,
4, 7, 6,// adjusted
1, 6, 2,
1, 5, 6,
0, 7, 4,// adjusted
0, 3, 7,// adjusted
0, 5, 1,// adjusted
0, 4, 5,// adjusted
3, 2, 6,
3, 6, 7

all normals face outward. the calculation then returns -1000 the minus depending on the base offset.

Community
  • 1
  • 1
Emond
  • 50,210
  • 11
  • 84
  • 115
  • Of course you need to subtract the basePoint. The answer you linked to is using the origin as the basePoint, and that's why the subtraction isn't there. But it mentions this fact. – R. Martinho Fernandes Apr 17 '11 at 18:16
  • hi i just replace the return (1.0f / 6.0f) * (-v321 + v231 + v312 - v132 - v213 + v123);by return (-v321 + v231 + v312 - v132 - v213 + v123); – Ali Apr 17 '11 at 18:17
  • @Ali: could you explain your comment? I do not understand. – Emond Apr 17 '11 at 18:18
  • i just remove the (1.0f / 6.0f) – Ali Apr 17 '11 at 18:23
  • Then why did you remove the 1.0/6.0 ? Did you apply the change I proposed? – Emond Apr 17 '11 at 18:44
  • @Ali, how can we help if you do not tell us what you have done and all you say is: it doesn't work? Please add to your question examples of what went wrong. Test your code with very simple models such as cubes and pyramids. – Emond Apr 17 '11 at 19:04
  • i just tested with a 10*10*10 cube coordinates and the result is 666,666 – Ali Apr 17 '11 at 19:24
  • Please add your tests to your question so others can see them. Could you also post the coordinates and the basePoint of the mesh? – Emond Apr 17 '11 at 19:31
  • As Martinho Fernandes stated you do need to subtract the basePoint and in your code you firt showed you did but now that is missing. – Emond Apr 18 '11 at 04:40