0

I'm working on a personal project to create a simple 3D rendering program. So far it can render simple solids such as cubes, cuboids, tetrahedrons, etc...

Simple Solids

The program works by providing a set of (CCW ordered) vertices which are then triangulated using a Delanuay algorithm. I'm not using any third party libraries and everything was been written in VB.NET from scratch... and I'm assuming the algorithms are properly implemented.

Here's the code that provides the vertices for a cube (yes, I'm aware that the actual length of the resulting solid will be 2 * length):

Public Shared Function Cube(length As Double) As List(Of Point3d)
    '   G-----F
    '  /|    /|
    ' B-----A |
    ' | H---|-E
    ' |/    |/ 
    ' C-----D

    Dim A As New Point3d(length, length, -length)
    Dim B As New Point3d(-length, length, -length)
    Dim C As New Point3d(-length, -length, -length)
    Dim D As New Point3d(length, -length, -length)
    Dim E As New Point3d(length, -length, length)
    Dim F As New Point3d(length, length, length)
    Dim G As New Point3d(-length, length, length)
    Dim H As New Point3d(-length, -length, length)

    Return New List(Of Point3d) From {A, B, C, D, E, F, G, H}
End Function

For the case of the sphere, I figured I could generate a set of vertices for a 180° arc on the XY plane and then rotate this arc along the X axis. Unfortunately, it appears that the Delaunay algorithm creates an invalid solid that doesn't meet Euler's formula for closed surfaces: V - E + F = 2

Simple Solids

Here's the code that is supposed to generate the vertices for the sphere:

Public Shared Function Sphere(radius As Double) As List(Of Point3d)
    Dim vertices As New List(Of Point3d)
    Dim arc As New List(Of Point3d)
    Dim p As New Point3d(0, 0, 0)
    Dim angleStep As Double = 45.0

    For ca As Double = 0.0 To 180.0 Step angleStep
        arc.Add(New Point3d(radius * Math.Cos((ca - 180.0) * Point3d.ToRad),
                               radius * Math.Sin((ca - 180.0) * Point3d.ToRad),
                               0))
    Next
    vertices.AddRange(arc)

    Dim v As Point3d
    For ax As Double = 0 To 360.0 Step angleStep
        For i As Integer = 0 To arc.Count - 1
            v = arc(i).RotateX(ax)

            Dim isDuplicate As Boolean = False
            For j As Integer = 0 To vertices.Count - 1
                If vertices(j).IsSimilar(v) Then
                    isDuplicate = True
                    Exit For
                End If
            Next
            If Not isDuplicate Then vertices.Add(v)
        Next
    Next

    Return vertices
End Function

Interestingly enough, if I set the angle step for each vertex to 90° the program, as expected, produces a valid octahedron. But reducing the angle step, in order to have a sphere with more faces, produces an invalid solid.

Simple Solids

So... the question is: what am I doing wrong?

UPDATE (2016/10/10): I've published the complete source code on GitHub: https://github.com/morphx666/3DEngine

Cœur
  • 37,241
  • 25
  • 195
  • 267
xfx
  • 1,329
  • 8
  • 18
  • The XZ plane has Y=0. Your arc has Z=0. (Also, your cube has an edge length of `Length * 2`.) – Andrew Morton Oct 09 '16 at 15:36
  • I'm sorry, that was a typo; I will correct the post. As for the length issue, yes, I'm aware of that... still, none of those issues would have any effect over the problem I'm having. – xfx Oct 09 '16 at 16:26
  • Could your `IsSimilar` function be faulty? Will the algorithm work if you don't remove duplicate vertices? Is your CCW ending up CW for some faces? - maybe going from -180 to 180 would cure that (although I doubt it). – Andrew Morton Oct 09 '16 at 16:29
  • Also, can you render the inside and outside of the faces, using different colours for each? Viewing an animation of the object rotating might show where something is going awry. – Andrew Morton Oct 09 '16 at 16:32
  • That's a pretty good idea. The rendering engine cannot do that at this moment, but I think it'll be well worth the effort. I'll post back when I've made the necessary modifications. – xfx Oct 09 '16 at 17:12
  • @AndrewMorton, I have published the source code on GitHub (see updated post) in case you want to take a look at it. – xfx Oct 10 '16 at 20:10
  • @xfx:Can you post the vertices of the sphere? I have implemented a delaunay triangulation (https://triangulation.codeplex.com/) and can try it. – Micromega Oct 11 '16 at 09:44
  • @Betterdev Here's a link to a text file containing the vertices: https://xfx.net/stackoverflow/sphere.txt – xfx Oct 11 '16 at 15:43
  • @xfx: TY, here is what I get:http://imgur.com/a/nURV8 with my code (http://pastebin.com/V5ByULKk). I needed to remove the negative z vertices and also move and scale it. It shows different results at different scale level? I hope it helps! – Micromega Oct 11 '16 at 16:32
  • @xfx:The last result seems to be stable it's not getting better. Unfortunatley there is a triangle missing on the left side? Is it right to remove the points with negative z value? I am guessing. – Micromega Oct 11 '16 at 16:53
  • @Betterdev, yes, that missing triangle seems to be part of the problem. Negative Z values are valid, although you could make them all positive by offsetting the Z values for all vertices by the same amount. In the program, negative Z values indicate points that are closer to the camera. – xfx Oct 11 '16 at 23:03
  • @xfx: I tried it with all points but it gives the same result. – Micromega Oct 12 '16 at 00:04
  • @xfx:IMO it's a problem with the order of the points. I tried to sort it ccw and it gives this:http://imgur.com/a/axPzL. Below there other order methods. It seems to me it's a valid dt, isn't it? – Micromega Oct 12 '16 at 15:26
  • @xfx: This one works:imgur.com/a/TSkAt (1st pic, 2nd pic is the other direction). Sorting CCW and removed the 0.0,0.0 point! – Micromega Oct 12 '16 at 16:06
  • @Betterdev, could you please provide me with the "properly ordered" list of points? – xfx Oct 12 '16 at 18:13
  • @xfx:http://pastebin.com/nrm9WfzY – Micromega Oct 12 '16 at 18:44
  • @Betterdev, thank you. I'll try to work with that information. – xfx Oct 12 '16 at 18:51
  • @xfx:No problem. I am bit confused but in my pastebin the ordering is CW and the 1st pic is from top to bottom and the 2nd pic is from bottom to top. You could try my package at triangulation.codeplex.com and change the order of the hilbert scan in 4 different orientation! – Micromega Oct 13 '16 at 07:21
  • @Betterdev: Well, after trying a bunch of things to try and get the vertices order correct, I figured... why not create the [sphere from a spiral](https://xfx.net/stackoverflow/sphere2.png)? That would/should allow me to have better control over the order of the vertices. Unfortunately, this produces a solid with even more faces, holes and all sorts of artifacts. I'm about to give up... – xfx Oct 13 '16 at 21:53
  • @xfx:Could you provide the points? Maybe it's your delaunay triangulation? – Micromega Oct 14 '16 at 08:24
  • @Betterdev, [Here they are](https://xfx.net/stackoverflow/sphere2.txt). These are the points that generate [this sphere](https://xfx.net/stackoverflow/sphere2.png). – xfx Oct 18 '16 at 02:26
  • @xfx: TY. I am not sure why you can't sort the sphere correctly. Just for fun I tried your sphere but results are as expected. Could you delete points that are not visible (from the point-of-view)? I also think triangulation isn't something done real-time :). Sorry, to disappoint you, here is the pic:http://imgur.com/a/h4ADe. – Micromega Oct 18 '16 at 11:47
  • @xfx:Here is the new order of the points clockwise:http://pastebin.com/4MbVjUqn! – Micromega Oct 18 '16 at 12:02
  • @xfx:Interesting results:http://imgur.com/a/nLaZe – Micromega Oct 20 '16 at 10:37
  • @Betterdev, well that looks nice!!! I went to check your source code at codeplex but it isn't displaying; did you remove it? – xfx Oct 20 '16 at 20:37
  • @xfx:No, it's seems a codeplex problem. Try Download it with git. Btw. the last result was sorting just the x-value!!! It seems there is an error in the hilbet sort! – Micromega Oct 20 '16 at 21:18
  • @xfx:codeplex is working. Maybe Hilbert sort needs some sort of transformation:https://github.com/themadcreator/delaunay/blob/master/src/org/delaunay/algorithm/ScaledHilbertIndex.java? – Micromega Oct 24 '16 at 12:19
  • @Betterdev, [I think I may have corrected the sorting issue](https://xfx.net/stackoverflow/sspehere_01.png). Unfortunately, there's seems to be some other issue with the code - most likely with the Delaunay's triangulation algorithm. – xfx Oct 24 '16 at 17:01
  • @xfx:Nice, I tried >themadcreator with my code but it didn't worked for me. – Micromega Oct 24 '16 at 17:29
  • @xfx: BTW. I solved the issue with the hilbert sort! – Micromega Feb 17 '17 at 16:29
  • Did you? Is your fix available at you repository? – xfx Feb 17 '17 at 16:57
  • @xfx:yes, I am github now. It was simply another optimization not working together. The other optimization was to triangulate from left to right means sorting x variable and prune smaller x value in the triangulation. This doesn't work with a hilbert sort. – Micromega Jul 10 '17 at 19:33
  • @Betterdev, thanks. I'll check the code and see if I can fix mine then... – xfx Jul 13 '17 at 01:02

1 Answers1

0

Hard to tell anything without knowing the implementation of the Delaunay triangulation. However, just from the title, I suspect a robustness problem. * The case of points on a sphere is VERY degenerate. * I guess that you are using floating point arithmetics, aren't you? See for instance https://hal.archives-ouvertes.fr/inria-00560388/ for the way that the CGAL library (www.cgal.org) handles such degeneracies. And you can read http://www.cgal.org/exact.html about arithmetic issues.

  • I'm preparing the code to post it on GitHub. But, I believe @AndrewMorton is right in assuming that some faces are facing backwards. – xfx Oct 10 '16 at 19:35