Click here to Skip to main content
15,888,286 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello,

Thank you for any help in advance. :)

I have been working on a 3D program for a while now that doesn't use DirectX or any other alternative (As a technical challenge), Uses GDI+ in .NET framework. So far its fully working with basic lighting, walk around navigation e.t.c.

In the program so far when you make a manual selection of triangles in any 3D world it will illuminate them yellow. I would now like to extrude that face/triangle collection a given integer amount on a button click. (Similar to programs like blender or 3DS Max)

I have tried googling but my results are just clouded with ice-cream extruding machines :D :p

I suppose what i'm asking is pointers in the right direction or some help with the math behind it. I'm probably missing something quite simple.


In the program
Triangle structure is a just a collection of 3 location vectors. (With a whole load of methods for normal and magnitude and such like)
Posted
Comments
Sergey Alexandrovich Kryukov 30-Mar-11 13:57pm    
Why using DirectX, not using WPF?
--SA
Thomas.D Williams 30-Mar-11 14:08pm    
This is purely a standard windows forms project, so its a no. No use of anything that would give me a 3D advantage :p (Still a student) I do believe you helped me a while back when I queried about mouse keys or something and it came down to something simple like form key preview.
Steve Wellens 30-Mar-11 15:11pm    
Seems like you could extrude three points so you would have three lines.
Then, put a surface between each two lines (a rectangle, four points, two per line).
Thomas.D Williams 30-Mar-11 15:19pm    
I did think of something similar. The only problem I can think of is how would the new points know what direction to extrude in.
E.g. if this was a 2D triangle the xy plane then the extruded points would be just increased in the z-axis. What if the triangle had been tilted in that 3rd dimension. It wouldn't be clear the new coordinates of even the vertex of a triangle.
Thank you for your suggestion. I'll see if I can work on it and possibly get the components of the triangle normal to increase each vector component with
Thomas.D Williams 30-Mar-11 15:27pm    
I'm also thinking of possibly making an article here on the CP for people who want to achieve a similar pointless challenge even though there are plenty of reliable systems like directx.
Going all the way from taking simple 3d point and plotting them on the screen
All the way to navigating a 3D world with the use of your keyboard and mouse.

1 solution

If you are just asking how to compute the extruded points of a triangle then the principle is as follows:

- all your triangles (ABC) must be oriented.
- compute a normal vector for the triangle. If the triangles are properly oriented, all normals will point towards the exterior. If they all point to interior, then just change ABC order into ACB for all your triangles.
- normalize this vector (not necessary but always a good idea)
- point A' (extruded of A) will be A + normal, and same for B' and C'

The normal of a triangle can be obtained using cross product. Something like this:

C#
//define a vector (will be used also for points)
struct Vector3
{
    public double X { get; set; }
    public double Y { get; set; }
    public double Z { get; set; }

    //default constructor
    public Vector3() {}
    //constructs a vector from 2 points
    public Vector3(Vector3 A, Vector3 B)
    {
        X = B.X - A.X;
        Y = B.Y - A.Y;
        Z = B.Z - A.Z;
    }

    //normalizes this vector
    public void Normalize()
    {
        float d = Math.Sqrt(X * X + Y * Y + Z * Z);
        if (d == 0)
            return;
        X /= d;
        Y /= d;
        Z /= d;
    }

    // returns the cross product between vectors u and v
    static public Vector3 CrossProduct(Vector3 u, Vector3 v)
    {
        Vector3 w = new Vector3();
        w.X = u.Y * v.Z - u.Z * v.Y;
        w.Y = u.Z * v.X - u.X * v.Z;
        w.Z = u.X * v.Y - u.Y * v.X;
        return w;
    }
}

//defines a face
struct Face
{
    public Vector3 A { get; set; }
    public Vector3 B { get; set; }
    public Vector3 C { get; set; }

    // returns a normalized normal vector
    // use this vector for your extrusion
    public Vector3 GetNormal()
    {
        Vector3 AB = new Vector3(A, B);
        Vector3 AC = new Vector3(A, C);
        Vector3 n = Vector3.CrossProduct(AB, AC);
        n.Normalize();
        return n;
    }
}
 
Share this answer
 
Comments
BobJanova 31-Mar-11 8:29am    
Yep, this is the answer. Since the OP probably already has his own vector class with cross product I will mention it in maths, not code ;).

The normal of a triangle (or in fact any planar convex polygon) can be found with:
norm[(v2-v1)×(v0-v1)]
... where v is the list of vertices of the planar polygon. (In a triangle, v = [A, B, C ] in Oliver's solution here.)

It may be better to store the triangles as a surface, including the surface normal (and possibly other surface level properties like colour, reflectivity etc) as well as the vertices so you don't have to calculate it each time.

And then yes, to extrude 'vertically' (away from the surface) you simply add a multiple of the normal to each point.
Olivier Levrey 31-Mar-11 8:32am    
I agree. I just wrote this to explain the "theory" ;)
Thanks for the vote.
Thomas.D Williams 31-Mar-11 9:16am    
Thank you for the mathematical explanation.
It actually made sense. Just finished covering them in maths in my education (Obviously not at this depth). Luckily my triangle class has methods for normal vector(Pre-calculated so doesn't have to be calculated). Colouring is handled by the lights in a "real time" sense.
Thomas.D Williams 31-Mar-11 9:18am    
Also would I not have to make the triangle normal a unit vector before multiplying it by a factor from an integer?
Olivier Levrey 31-Mar-11 9:21am    
Exactly. This is why I wrote the Vector3.Normalize method and called it in Face.GetNormal.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900