Add text to sphere surface

1.3k Views Asked by At

I am trying to add some text to a sphere - labels on nodes of a graph.

So for example, in the graph below, I'd like each node labelled.

#include "colors.inc"

global_settings {
    assumed_gamma 1.0
    ambient_light Gray
}
light_source { <100,00,-150> color White }
camera {
  sky <0, 0, -1>
  look_at <0, 0, 0>
  location <20, -80, -160> 
}
plane { <0,0,-1>, 0
  pigment { color White }
}

 sphere {
< -50,-33,-50 > , 8
texture { pigment { color rgb 0.7 }}
}      
 sphere {
< 50,-50,-50 > , 8
texture { pigment { color rgb<1.0, 0.0, 0.0> }}
}     
cylinder {
< -50,-33,-50 >, < 50,-50,-50 > ,1
texture { pigment { color rgb 0.5 }}
}

I can add text to the plot generally but it is not on the spheres surface

text{ttf "crystal.ttf", "word", 0, 0 
             pigment {Black} 
             scale 10   
             translate < -50,-33,-50 > 
    }

From browsing web , I thought it may be possible to add the text as a texture to the sphere, but I have had no success - no text appears.

#macro my_node(Text) 

  #declare word=texture{
                  pigment{object{ 
                             text{ttf "crystal.ttf", Text, 0, 0  pigment {Black} scale 25} 
                             colour Clear }
                          }
                       }
sphere  {< 0, 0, 0>, 8
                texture { pigment { color rgb 0.7 }}
                texture{word}
            }
#end            

object {my_node("word")
            translate < -50,-33,-50 >
         }

My question: How can I add labels onto a sphere please. thanks

1

There are 1 best solutions below

0
On

So, I made some tests, and indeed, the "object" pigment pattern will work for you. As I've wrote in the comment what seems to be off is that you are drawing your "Word" pigment object in a place, and the sphere lies elsewhere, therefore there is no intersection, and the sphere is drawn only on the "outside" color.

I made this sample file - observe that I carefully specify both my texture object and my sphere to be at the origin (roughly within the <-1, -1, -1> <1, 1 , 1> two-unity-cube). The text object have translate and scale statments so that it is centered at <0,0,0> - POVRay as far as I know have no "text measurement" functions, so you have to center your text by "feeling" and "eye" - the only measurement you get is that character height is 1 unity maximum. If you use a monospaced font, you can get to know the exact width of each character - might make things easier.

Then, when creating the sphere, and applying the text as texture, I scale it up on the Z axis, to ensure the letters do cross the sphere surface - otherwise the text would lie "inside" the sphere.

As I mentioned on the comment, this creates "flat" text on a curved sphere, and there is no easy way to distort the text following the sphere.

So, this is what worked for me. (Note that it requires the "drodisans.ttf" file to be in the same folder)

#version 3.7
#include "colors.inc"


camera {
    location <0, 0, -8>
    look_at 0
}

#declare Label1 = object {
    text {
        ttf "droidsans.ttf", "Hello POV-Ray", 1, 0
        pigment {color Blue}
    }
    scale <0.3, 1, 1>
    translate <-1, -.35, -.5>
}

sphere {
    0, 1
    texture {
        pigment {object  {Label1 color Blue color Red} }
        finish {
            phong 1
            ambient 0.2
        }
        scale <.7, .5, 10>
    }
    translate <0, -.5, 0>
}


light_source {
    <0, 2, -4>
    color White   
}

Now, another way to do that, that would give you more control over the text, and even allow the text to actually "wrap around" the sphere, is to use an image as an image_map, from a separate file. That would require you to pre-render your labels as images, using another program (it could even be POVRay itself, or you could do that from a postscript snippet using Ghostscript). The "image_map" directive treats the image file as a Unity square that is projected on the <0, 0, 0> to <1, 1, 0> square, stretching infinitely on the z axis. But maybe, due to the 2 step rendering process needed here you should stick with the other approach, unless you have problem positioning your text there. (Centering has to be done "manually", as I've explained).

Note that either method will require you to "assemble your objects" at the origin, and translate and scale after that.

eImage rendered by the script above