How to Project a Terrain onto a Sphere?

Started by
12 comments, last by quddusaliquddus 14 years, 10 months ago
Hi all :D, I am trying to create a Sphere with Fractal Terrain. I have the code for creating a terrain using the Diamond Square Algorithm. I also have the code for creating a 3D Sphere. All this is in WPF using Visual Basic .NET I would like to know how I could project the Terrain onto a Sphere. I am at a complete loss as how to do this. Any help is appreciated. Thanks Q :) PS Diamond Square Algorithm Result: 1547jtf.jpg Sphere Result: qovd49.jpg
Advertisement
Well, its actually pretty simple :)

You have <insert an algorithm of your choice here> that creates your terrain height data. From that you can construct vertices as if the terrain raises height values on a flat plane. So each height value is just a difference of the original (flat) vertex height and the height from your terrain algorithm output.

For a sphere its the same. Just take the unmodified vertex position on the sphere's surface and translate this vertex along the direction vector from the sphere's center to this particular vertex position by the amout of the height output from your terrain algorithm for this location.

Of course there are more advanced techniques such as building six flat terrain patches as faces of a single cube. Then you can apply a transformation for each vertex that transforms it from flat cube face space to sphere space.
------------------------------------I always enjoy being rated up by you ...
I'm assuming you want the result to be something like a planet; a sphere with terrain.

The easiest way I've found is to use 3d noise, and wherever the vertex lies relative to the origin of the sphere, displace it outwards whatever the noise is at that point. There is no projection needed. Unless you were subdividing the planet into 6 quadtrees, then you would need to project them from a cube to a sphere (not difficult). Even then, the noise would still simply be a function of any given point on the sphere.

Here is a great method of projecting a cube (6 quadtrees) to a sphere.
Hi. Thanks for the help guys (and the link). Would you guys go over my implementation and see where Im going wrong? If so- I will post it on the forum.

I have managed to create peaks on the sphere modifying points belonging to six triangles. Then I simply tried to extend the height of the sphere using the data from the Diamond Square Algorithm (without success).

So - is anyone up for looking @ the code?
I would take a quick look if you'd like.
Thanks.

[The Diamond Square Algorithm]

            'Assign Square Corner Indexes            SqrSize = Points.Count - 1            SqrCorners(0) = 0            SqrCorners(1) = Sqrt(SqrSize) - 1            '### Diamond Step            'Assign Centre Index            Centre = SqrSize / 2            'Create Centre Point3D            Dim CentrePoint As New Point3D            'Assign to Centre Point3D            CentrePoint.X = Points(Centre).X            CentrePoint.Y = (Points(SqrCorners(0)).Y + Points(SqrCorners(1)).Y + Points(SqrCorners(2)).Y + Points(SqrCorners(3)).Y + (Rnd.Next(0, RandomRange) / 1000)) / 4            CentrePoint.Z = Points(Centre).Z            'Assign Centre Point3D to Points Collection            Points(Centre) = CentrePoint            Points(DiamCorners(1)) = CentrePoint            Points(DiamCorners(2)) = CentrePoint            Points(DiamCorners(3)) = CentrePoint            '### Call DiamondSquareAlgorithm for each quarter with reduced random range            'Split into Four Squares            'Bottom Left            Dim Square1 As New Point3DCollection((SqrSize / 2) - 5)            'Bottom Right            Dim Square2 As New Point3DCollection((SqrSize / 2) - 5)            'Top Left            Dim Square3 As New Point3DCollection((SqrSize / 2) - 5)            'Top Right            Dim Square4 As New Point3DCollection((Sq            Next            'Populate Square 2            'Bottom Right Square            For i = 0 To (SqrSide / 2) - 1                For j = 0 To (SqrSide / 2) - 1                    Square2.Add(Points((i * SqrSide) + j + (SqrSide / 2)))                Next            Next            'Populate Square 3            'Top Left Square            For i = 0 To (SqrSide / 2) - 1                For j = 0 To (SqrSide / 2) - 1                    Square3.Add(Points(((i + SqrSide / 2) * SqrSide) + j))                Next            Next            'Populate Square 4            'Top Right Square             For i = 0 To (SqrSide / 2) - 1                For j = 0 To (SqrSide / 2) - 1                    Square4.Add(Points(((i + SqrSide / 2) * SqrSide) + j + (SqrSide / 2)))are with new quarters using loop            'Populate Square 1            'Bottom Left Square            Dim Index As Integer = 0            For i = 0 To (SqrSide / 2) - 1                For j = 0 To (SqrSide / 2) - 1                    Points((i * SqrSide) + j) = Square1(Index)                    Index = Index + 1                Next            Next            'Populate Square 2            'Bottom Right Square            'Top Left Square            Index = 0            For i = 0 To (SqrSide / 2) - 1                For j = 0 To (SqrSide / 2) - 1                    Points(((i + SqrSide / 2) * SqrSide) + j) = Square3(Index)                    Index = Index + 1                Next            Next            'Populate Square 4            'Top Right Square             Next            '### Return current whole square        End If    End Function


[Edited by - quddusaliquddus on June 24, 2009 9:09:57 AM]
The above-code is in two parts: Diamond Square Algorithms and Sphere-Creation.

Edit:

I seperated them into two posts. I will try to add vb tags.
Maybe try placing the code in source tags to make it easier to read? Although I'm not sure if it can highlight VB.

Also, is there a specific problem with the code you posted?
[The Sphere-Creation Code]

        Dim Ext As Double = InputBox("Ext: ", "Extension", "1")        'For Adding Peaks to Sphere        'Dim P3DHeightList As Point3DCollection = DiamondSquareAlgorithm(Point3DList, 100)        'Dim s1, s2, s3, s4, s5, s6 As Integer        'For j = 1 To ((n / 2))        '    For i = 0 To n + 1 Step 2        '        'Dim s1 As Integer        '        'Assign Values        '        HorizSegment = i        '        VertiSegment = j        '        'Calculate Point        '        Square = ((VertiSegment - 1) * n * 6) + 6 * HorizSegment + 1        '        s1 = Square        '        Point3DList(s1) = getPeak(Point3DList(s1), r, Ext)        '        '===        '        'Dim s2 As Integer        '        'Assign Values        '        HorizSegment = i + 1        '        VertiSegment = j        '        'Calculate Point        '        Square = ((VertiSegment - 1) * n * 6) + 6 * HorizSegment - 3        '        s2 = Square        '        Point3DList(s2) = getPeak(Point3DList(s2), r, Ext)        '        '===        '        'Dim s3 As Integer        '        'Assign Values        '        HorizSegment = i + 2        '        VertiSegment = j        '        'Calculate Point        '        Square = ((VertiSegment - 1) * n * 6) + 6 * HorizSegment - 1        '        s3 = Square        '        Point3DList(s3) = getPeak(Point3DList(s3), r, Ext) 5                    SphereMesh.Positions.Add(Point3DList(P + Q))                    triangleMesh.TriangleIndices.Add(P + Q)                Next                P = P + 6            Next        Next        'Add to Viewport        Dim triangleModel As New GeometryModel3D(SphereMesh, material)        Dim model As New ModelVisual3D()        model.Content = triangleModel        model.SetValue(NameProperty, "Earth")        Me.V.Children.Add(model)        Dim stopTime As DateTime = DateTime.Now        Console.WriteLine(stopTime)        Dim duration As TimeSpan = stopTime - startTime        'MessageBox.Show(duration.ToString)


[Edited by - quddusaliquddus on June 24, 2009 9:19:15 AM]
Thanks again.

One specific problem seems to be that in the Sphere-creation code - when I call the getpeak function - if I pass the Y value of P3DHeightList as the 'Ext' parameter - it doesnt give the desired effect i.e. it should extend that particular peak outwards by that given amount. This doenst happen.

So theres something going wrong.

This topic is closed to new replies.

Advertisement