calculating normals or: i can't find my own typo

Blitz3D Forums/Blitz3D Programming/calculating normals or: i can't find my own typo

koekjesbaby(Posted 2004) [#1]
i try to find the normals from a set of connected nodes with this code:
Graphics3D(640,480,16,2)
SetBuffer(BackBuffer())
 
Function createLine(x1#,y1#,z1#, x2#,y2#,z2#, mesh=0)
	If mesh = 0 Then 
		mesh=CreateMesh()
		EntityFX(mesh,16)
		surf=CreateSurface(mesh)	
		verts = 0	
	Else
		surf = GetSurface(mesh,1)
		verts = CountVertices(surf)
	End If

	AddVertex surf,x1#,y1#,z1#,0,0
	AddVertex surf,x2#,y2#,z2#,1,1
	
	AddTriangle surf,verts,verts+1,verts
	
	Return mesh
End Function

Type node
	Field x#,y#,z#
	Field links.node[5]
	Field nLinks
End Type
Function node.node(x#,y#,z#)
    n.node = New node
    n\x# = x#
    n\y# = y#
    n\z# = z#

    Return n
End Function

n0.node = node(0,0,0)
n1.node = node(1,0,0)
n2.node = node(0,1,0)
n3.node = node(0,0,1)
n4.node = node(1,1,0)
n5.node = node(0,1,1)
n6.node = node(1,0,1)
n7.node = node(1,1,1)

n0\links[0] = n1
n0\links[1] = n2
n0\links[2] = n3
n0\nLinks = 3

n1\links[0] = n0
n1\links[1] = n4
n1\links[2] = n6
n1\nLinks = 3

n2\links[0] = n0
n2\links[1] = n5
n2\links[2] = n4
n2\nLinks = 3

n3\links[0] = n5
n3\links[1] = n6
n3\links[2] = n0
n3\nLinks = 3

n4\links[0] = n1
n4\links[1] = n7
n4\links[2] = n2
n4\nLinks = 3

n5\links[0] = n7
n5\links[1] = n3
n5\links[2] = n2
n5\nLinks = 3

n6\links[0] = n7
n6\links[1] = n1
n6\links[2] = n3
n6\nLinks = 3

n7\links[0] = n5
n7\links[1] = n6
n7\links[2] = n4
n7\nLinks = 3



For n.node = Each node
    nx# = 0
    ny# = 0
    nz# = 0
    
    v0x# = n\x#
    v0y# = n\y#
    v0z# = n\z#
    DebugLog "new normal at: ("+ v0x +","+ v0y +","+ v0z +")"
    
    For i = 0 To (n\nLinks-1)
        If i = n\nLinks-1
            v1x# = n\links[0]\x#
            v1y# = n\links[0]\y#
            v1z# = n\links[0]\z#

            v2x# = n\links[i]\x#
            v2y# = n\links[i]\y#
            v2z# = n\links[i]\z#
        Else
            v1x# = n\links[i+1]\x#
            v1y# = n\links[i+1]\y#
            v1z# = n\links[i+1]\z#

            v2x# = n\links[i]\x#
            v2y# = n\links[i]\y#
            v2z# = n\links[i]\z#
        EndIf

        px# = v1x#-v0x#
        py# = v1y#-v0y#
        pz# = v1z#-v0z#

        qx# = v2x#-v0x#
        qy# = v2y#-v0y#
        qz# = v2z#-v0z#
        
        ;---
        connection =  createLine(v0x#,v0y#,v0z#, v1x#,v1y#,v1z#)
        connection =  createLine(v0x#,v0y#,v0z#, v2x#,v2y#,v2z#,connection)

        EntityColor(connection, 0,0,0)
        ;---
        
        ; cross product
        tx# = (py#*qz# - pz#*qy#)
        ty# = (pz#*qx# - px#*qz#)
        tz# = (px#*qy# - py#*qx#)
        
        nx# = nx# + tx#
        ny# = ny# + ty#
        nz# = nz# + tz#

    Next
    l# = Sqr(nx#*nx# + ny#*ny# + nz#*nz#)
    nx# = nx#/l#
    ny# = ny#/l#
    nz# = nz#/l#

    DebugLog "    normal -> " +nx# + ", " + ny# + ", " +nz#
    normal =  createLine(n\x#,n\y#,n\z#, n\x#+nx#,n\y#+ny#,n\z#+nz#)
    EntityColor(normal, 255,0,0)
Next

campiv = CreatePivot()
camera=CreateCamera(campiv)
MoveEntity(camera, 0,0,-3)
PositionEntity(campiv, 0.5,0.5,0.5)

CameraClsColor(camera, 255,255,255)
l=CreateLight()
WireFrame(1)

While Not KeyHit(1)
    
    
    RotateEntity(campiv, -MouseY(), MouseX(), 0)    
	RenderWorld()
	Flip()
Wend

the red lines are the normals i calculate, but they are (obviously) wrong. i've been staring at this too long to be able to concentrate on this anymore. does anyone know what i am doing wrong?

thanks!


DrakeX(Posted 2004) [#2]
your math is right, but it's just the order of the links that determines the normal of each node. just like triangles ;)

switch links 1 and 2 of nodes n1, n2, and n7 and you'll see the normals are all facing out.