How to Project a Terrain onto a Sphere?
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:
Sphere Result:
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.
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'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.
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 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?
Thanks.
[The Diamond Square Algorithm]
[Edited by - quddusaliquddus on June 24, 2009 9:09:57 AM]
[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.
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?
Also, is there a specific problem with the code you posted?
[The Sphere-Creation Code]
[Edited by - quddusaliquddus on June 24, 2009 9:19:15 AM]
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.
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
Popular Topics
Advertisement