Code archives/3D Graphics - Maths/Gradient Of a Triangle
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
I have written this for use with a function that splits a mesh into a number of surfaces, for various levels of gradient. This is useful if you want to add a cliff texture to the steep triangles of a mesh etc. The 'Instant cliffs' function is here: http://blitzbasic.com/codearcs/codearcs.php?code=1094 I'm sure you could think of plenty of other uses for finding a triangle's gradient though. . . :O) | |||||
Function TriGradient#(surface%, triangle%) Local v0%,v1%,v2% Local v0x#, v0y#, v0z# Local v1x#, v1y#, v1z# Local v2x#, v2y#, v2z# Local tx#, ty#, tz# Local m1#, m2#, c1#, c2# Local ax#, ay#, az# Local theta#, argument#, modulus# Local i% ;Special case 1: Is the whole triangle parallel to xz-plane? v0x = VertexX(surface, TriangleVertex(surface, triangle, 0)) v0y = VertexY(surface, TriangleVertex(surface, triangle, 0)) v0z = VertexZ(surface, TriangleVertex(surface, triangle, 0)) v1x = VertexX(surface, TriangleVertex(surface, triangle, 1)) v1y = VertexY(surface, TriangleVertex(surface, triangle, 1)) v1z = VertexZ(surface, TriangleVertex(surface, triangle, 1)) v2x = VertexX(surface, TriangleVertex(surface, triangle, 2)) v2y = VertexY(surface, TriangleVertex(surface, triangle, 2)) v2z = VertexZ(surface, TriangleVertex(surface, triangle, 2)) If v0y = v1y And v1y = v2y Then ;Yes, so gradient is 0 Return 0 End If ;Step 1: ;Sort out vertices in order of height (y-axis), v0=bottom, v1=middle, v2=top For i=0 To 2 v% = TriangleVertex(surface, triangle, i) If v0=0 Then v0 = v If v2=0 Then v2 = v If VertexY(surface,v) > VertexY(surface,v2) Then v2 = v If VertexY(surface,v) < VertexY(surface,v0) Then v0 = v Next For i=0 To 2 v% = TriangleVertex(surface, triangle, i) If v0<>v And v2<>v Then v1 = v Next v0x = VertexX(surface, v0) v0y = VertexY(surface, v0) v0z = VertexZ(surface, v0) v1x = VertexX(surface, v1) v1y = VertexY(surface, v1) v1z = VertexZ(surface, v1) v2x = VertexX(surface, v2) v2y = VertexY(surface, v2) v2z = VertexZ(surface, v2) ;Step 2: Translate lowest point To 0,0,0 tx = v0x ty = v0y tz = v0z v0x = v0x - tx v0y = v0y - ty v0z = v0z - tz v1x = v1x - tx v1y = v1y - ty v1z = v1z - tz v2x = v2x - tx v2y = v2y - ty v2z = v2z - tz ;Special case 2: Is the line (v1,v2) is parallel to xz-plane? If v1y = v2y Then ;Yes, so invert the triangle in the y-axis v0y = v1y v1y = 0 v2y = 0 ;Lowest point is now v2, highest is v0, so swap them: tx# = v2x ty# = v2y tz# = v2z v2x = v0x v2y = v0y v2z = v0z v0x = tx v0y = ty v0z = tz ;Re-do translation: v0x = v0x - tx v0y = v0y - ty v0z = v0z - tz v1x = v1x - tx v1y = v1y - ty v1z = v1z - tz v2x = v2x - tx v2y = v2y - ty v2z = v2z - tz End If ;Step 3: Find Point a, such that y(a) = 0 and y is on the line (v2, v1) ;Line Equations: ;y=m1x+c1 ;y=m2z+c2 m1 = (v2y-v1y) / (v2x-v1x) m2 = (v2y-v1y) / (v2z-v1z) c1 = v1y - m1 * v1x c2 = v1y - m1 * v1z ay = 0 ax = -c1/m1 az = -c2/m2 ;Special case 3: is v1 at y=0 If v1y = 0 Then ;Yes, therefore a = v1 ax = v1x ay = v1y az = v1z End If ;Step 4. Rotate all points v0,v1,v2, a about y-axis so that point a is at x=0 theta# = -ATan2(az, ax) ;Angle to rotate ;NOTE: Actually only v2's z-component will be used, so let's be lazy and only calculate v2z. ;;Rotate v0 ;argument# = ATan2(v0z, v0x) ;modulus# = Sqr(v0x^2 + v0z^2) ;v0x = modulus * Cos(theta+argument) ;v0z = modulus * Sin(theta+argument) ;;Rotate v1 ;argument# = ATan2(v1z, v1x) ;modulus# = Sqr(v1x^2 + v1z^2) ;v1x = modulus * Cos(theta+argument) ;v1z = modulus * Sin(theta+argument) ;;Rotate v2 argument# = ATan2(v2z, v2x) modulus# = Sqr(v2x^2 + v2z^2) ;v2x = modulus * Cos(theta+argument) v2z = modulus * Sin(theta+argument) ;;Rotate a ;argument# = ATan2(az, ax) ;modulus# = Sqr(ax^2 + az^2) ;ax = modulus * Cos(theta+argument) ;az = modulus * Sin(theta+argument) ;Step 5. Calculate the gradient, and return the value. Return Abs(v2y / v2z) End Function Function Test#(v0x#, v0y#, v0z#, v1x#, v1y#, v1z#, v2x#, v2y#, v2z#) m% = CreateMesh() s% = CreateSurface(m) AddVertex s, v0x, v0y, v0z AddVertex s, v1x, v1y, v1z AddVertex s, v2x, v2y, v2z AddTriangle s, 0,1,2 Return TriGradient(s, 0) End Function Graphics3D 800, 600, 0, 2 Print Test(0,0,0, 10,1,0, 20,0,0) WaitKey End |
Comments
None.
Code Archives Forum