I have currently thought of two possible ways to do this, depending on what you want to
produce. One method produces a texture map which can be wrapped around a sphere with no distortion.
The other method produces a 3D model of the planet using polygons.
Choosing a Plane
Any method requires that you randomly choose planes to cut the sphere in half. How do you
do this? To define a plane, you need to know the normal vector to the plane, and the location
of one point on the plane.
All planes must pass through the center of the sphere, which makes things easier. Now all you
have to do is randomly select normal vectors. You will obviously want to produce an even
distribution of vectors, so you should choose vectors which lie inside the sphere.
procedure to randomly select plane normals
VECTOR: n
loop
n = VECTOR( random(-1,1), random(-1,1), random(-1,1) )
magnitude = mag(n)
until magnitude(n) < 1
3D Polygon Method
This method produces the best results, but can take up quite a lot of memory. The planets
above each contained 10000 polygons.
First, generate a sphere. You can either write your own program to do this, or use a 3D
modeling program. The more vertices the better. Also, it is best to have a sphere with an even
distribution of vertices across it's surface. For example, 3D Studio can generate two kinds of
sphere which it calls Lsphere and Gsphere. Lsphere is a longitude/latitude sphere and contains
a higher concentration vertices at the poles than at the equator. The Gsphere is much better,
with a very even distribution. At some point I will get round to writing a document on
generating spheres.
OK, so now you have a sphere. The method is simple from now on.
loop
n = random vector ; see method above
loop through each vertex of the sphere
d = dotproduct( n , this vertex) ; is this vertex infront of
; or behind the plane?
if d > 0 then ; if infront then
move this vertex out a little bit
else ; if behind then
move this vertex in a little bit
end if
end loop
end loop
Here you can use the fast dot product without square roots. Also, for speed and accuracy
it's a good idea to keep an extra number (initialised to 1000 or something) with each vertex.
When you move each vertex in or out a little bit, just add or subtract 1 from this number
instead of moving the location of the vertex. This is obviously much faster. Then, when you have
done lots of iterations, you can use these numbers to move the vertices.
Map Method
I shall explain the map method later when I have figured out a better way of doing it.
Update:
It was pointed out to me, by Toby Haynes, that the above problem, causing the land on one
side of the planet to look the same as the sea on the other side, can be overcome. Rather than
splitting the sphere through the middle, you can slice it absolutely anywhere you like. This
produces better looking continents which don't appear to be symmetrical at all.
The modification to the existing code is very small. Now, when you generate a random plane
normal, you treat it as both the normal to the plane, and the distance of the plane from the
centre of the sphere.
All that needs to change is how we decide if a point is behind or infront of the plane.
The plane is specified by the vector n. This is both the normal vector to the plane,
and the plane's distance from the centre of the sphere. On the diagram are two points. The green
one is infront of the plane, and the red one is behind. You will see that the dot product of
v1 (the vector from the end of n to the green point) is greater than 1. The dot
product of v2 and n is less than 1.
loop
n = random vector ; see method above
m = randomly either -1 or 1
loop through each vertex of the sphere
p = coordinates of this vertex
v = p - n
d = dotproduct(n , v) ; is this vertex infront of
; or behind the plane?
if d > 0 then ; if infront then
move this vertex by m
else ; if behind then
move this vertex by -m
end if
end loop
end loop
You will have noticed the introduction of a new variable m. This is here for a good
reason. All the points on the sphere, behind the plane are are moved out a little bit, and
those infront are moved in a little. Whenever a plane is generated, the centre of the sphere
is behind the plane (unless the plane passes exactly through the middle). This means that most
points are behind the plane. This in turn means that most points will be moved out a little bit.
The result is the planet becomes composed entirely of land.
To overcome this, we can randomly choose whether it is points that are behind or infront
of the plane than are moved outwards (and vice versa). The variable m indicates this.
A value of -1 means "in a little bit", 1 means "out a little bit".
Here is an axample of the new method. You can see that there are no similarities between
the two views of the planet.