POV-Ray - YAMAHA Upright Piano

last edited: 9/5/11

As I play piano myself, I always wanted a classy real upright piano in my room instead of my M-AUDIO Keystation 88es. I can't afford one, neither do I have the place to fit it, so why not create one virtually. I used the following picture as a visual reference, and the only mesurements that I had was that the piano was overall 121 x 153 x 61cm: I had to figure everything else by eying.

For every part, I had to create a rounded box that looked approximately like the picture. For parts that are not boxes, for example the black keys, I had to round things manually, i.e. render a cylinder for each edge, joining them together with smaller boxes, etc. Designing the keyboard layout itself turned out to be a challenge: I learned during this project that white and black keys do not all share the same width and the alignment is not regular. Thankfully, this site oriented me well.


Reference key mesurements in mm

One of the most challenging part to design with rounded edges were the two lateral feet of the piano, in particular the upper part of them. I had never rounded the edges of a concave shape before, and the result I ended up with was pretty interesting. I'll try to explain how I did it, and illustrate it with some renders. So I started up with a box, from which I subtracted a horizontal cylinder (image 1). Then I added this result to another same box, but from which a bigger cylinder is removed (image 2). This made two grooves appear at each side of the box. After that, I added two tori, one filling each grove, from which i subtracted what I didn't need (image 3). Finally, I add a rounded box in the front face, which overlaps the curve of the tori on the bottom, so that the front face is rounded as well (image 4).

I use similar operations for the grooves in front of the keys, around the lock hole, but with stretched spheres. The keyboard lid (officially called "Fall board") is simply composed of rounded boxes, with golden "TENCHI" letters (the font mimicking the original "YAMAHA" logo is Impact). The multiple small hinges on top of the piano and under the lid are done with a small macro to render a multitude of little cylinders (the attentive reader will notice that the mechanism that I rendered for the lid is actually wrong, I placed the hinges in the wrong spot, will correct that sometime).

This project is not yet finished. What's left ? The little piece of wood on the lid that holds music sheets for you, the pedals, and the stool. I'll code them when I come back to POV-Ray someday :3 For the time being, here are the renders of what's done already (Each render took approximately 20min, except the last which took 1h):

Source code (file available here)

global_settings
{ 
    max_trace_level 15
    assumed_gamma 1.0
}
 
#include "shapes.inc" 
#include "textures.inc"


#declare rotation_clapet = 30;
 
#declare enable_dof = 1;         

            
#declare Camera_0 = // angle
camera
{
    perspective angle 17 //16
    location  <-40.0 , 21 , 55>
    right     x*image_width/image_height
    look_at   <15.3/2 , 11.1 / 2 , 3.1 / 2>
    #if (enable_dof = 1)                                                
        focal_point <15.3/2, 11.1/2+2, 5.4> blur_samples 75 aperture 0.6
    #end
}  
#declare Camera_1 = // front
camera
{
    perspective angle 24
    location  <15.3/2, 30 , 55>
    right     x*image_width/image_height
    look_at   <15.3/2, 6, 3.1 / 2>
    #if (enable_dof = 1)
        focal_point <15.3/2, 11.1/2+2, 5.4> blur_samples 40 aperture 0.6
    #end
}     
#declare Camera_2 = // side
camera
{
    perspective angle 24
    location  <55, 10, 3.1>
    right     x*image_width/image_height
    look_at   <15.3/2 , 4, 3.1 / 2>
    #if (enable_dof = 1)
        focal_point <15.3/2, 11.1/2+2, 5.4> blur_samples 40 aperture 0.6 
    #end
}                        
#declare Camera_3 = // keyboard
camera
{
    perspective angle 45
    location  <15.3/2, 15, 25>
    right     x*image_width/image_height
    look_at   <15.3/2, 7, 4.5>
    #if (enable_dof = 1)
        focal_point <15.3/2, 11.1/2+2, 5.4> blur_samples 40 aperture 0.6 
    #end
}          
#declare os = 1.77;
#declare Camera_4 = // keys close-up
camera
{
    perspective angle 120
    location  <15.3/2+4-os, 8.1, 5.7>
    right     x*image_width/image_height
    look_at   <15.3/2-(2+os), 2, -4.4>
    #if (enable_dof = 1)
        focal_point <15.3/2+1.8,  11.1/2+2.3, 5.0> blur_samples 100 aperture 0.07 
    #end
}                        
camera { Camera_0 }    
     
     
     
light_source{< 3000,3000,-3000> color rgb 0.2 }         
// Close up light:
/*light_source{<16/2-os,17,3> color rgb 1 
  //looks_like { sphere { 0*x, 0.5 pigment { rgb 1 } } }
} */  
light_source{<16,6,10> color rgb 1 
  //looks_like { sphere { 0*x, 0.5 pigment { rgb 1 } } }
}    
light_source{<-5,8,1> color rgb 1 
  //looks_like { sphere { 0*x, 0.5 pigment { rgb 1 } } }
}    
 light_source{<17,8.5,15> color rgb 0.1 
  //looks_like { sphere { 0*x, 0.5 pigment { rgb 1 } } }
} 

difference
{ 
plane{
    y, -0.05
    texture
    {
        pigment { checker color rgb<1,1,1>*1.2 color rgb<0.25,0.15,0.1>*0 scale 15.3/2 }
        finish { phong 0.1}
    }
}
box { <-15.3*3,-50,-50>,<15.3*4,50,1000> inverse } 
}
#declare side_holder =
union
{
    object
    {                                  
        Round_Box(<0,0,0>,<0.4,1,2>, 0.03, off)
        rotate x*30  
        translate <0.1,(3/4)*(11.9)-0.9,2.5> 
    }
    Round_Box(<0.1,(3/4)*(11.9)-0.9,2>,<0.5, (3/4)*(11.9)-2.4,6-0.27>, 0.03, off)    
    Round_Box(<0.1,(3/4)*(11.9)-1.17,2>,<0.5, (3/4)*(11.9)-2.33,6>, 0.03, off)     
    Round_Box(<0.1,(3/4)*(11.9)-2,5>,<0.5, (3/4)*(11.9)-2.4,5.9>, 0.03, off)     
    Round_Cylinder(<0.1,(3/4)*(11.9)-1.2,5.7>,<0.5,(3/4)*(11.9)-1.2,5.7>, 0.3,0.03, off)
    Round_Cylinder(<0.1,(3/4)*(11.9)-2.3,5.9>,<0.5,(3/4)*(11.9)-2.3,5.9>, 0.1,0.03, off)
}
#declare foot =
object
{
    Round_Box(<0.12,0,5.5>,<0.48,(3/4)*(11.9)-2.1,5>, 0.05, off)  
}

/*#declare foot_up2 =
union
{
    union
    {
        difference
        {
            box {  <0.12+0.035,(3/4)*(11.9)-2.86,5.5+0.2>, <0.48-0.035,(3/4)*(11.9)-2.1,5.3> }                            
            cylinder { <0.12-0.035,(3/4)*(11.9)-2.9+0.04,5.5+0.2-0.035>, <0.48+0.035,(3/4)*(11.9)-2.9+0.04,5.5+0.2-0.035>, 0.2-0.03 } 
        } 
        difference
        {
            box {  <0.12,(3/4)*(11.9)-2.86,5.5+0.2>, <0.48,(3/4)*(11.9)-2.1,5.3> }                            
            cylinder { <0.119,(3/4)*(11.9)-2.9+0.04,5.5+0.2-0.035>, <0.481,(3/4)*(11.9)-2.9+0.04,5.5+0.2-0.035>, 0.2 } 
        } 
        difference
        {              
            union
            {                                                                        
                torus { 0.2, 0.03 rotate z*90 translate <0.12+0.035,(3/4)*(11.9)-2.9+0.04,5.5+0.2-0.035> }         
                torus { 0.2, 0.03 rotate z*90 translate <0.48-0.035,(3/4)*(11.9)-2.9+0.04,5.5+0.2-0.035> } 
            }
            box {  <0.479,(3/4)*(11.9)-2.86,5.5+0.2>, <0.121,(3/4)*(11.9)-2.1,5> inverse }   
            
        }  
        Round_Box(<0.12, (3/4)*(11.9)-2.686,5.5+0.23>, <0.48,(3/4)*(11.9)-2.1,5.3>, 0.03, off) 
    }
} */
#declare foot_up =
union {
    difference
    {
        box {  <0.12+0.035,(3/4)*(11.9)-2.86,5.5+0.2>, <0.48-0.035,(3/4)*(11.9)-2.1,5.3> }   
        cylinder { <0.12-0.035,(3/4)*(11.9)-2.9+0.04,5.5+0.2-0.035>, <0.48+0.035,(3/4)*(11.9)-2.9+0.04,5.5+0.2-0.035>, 0.2-0.03 } 
    }    
    difference
    {
        box {  <0.12,(3/4)*(11.9)-2.86,5.5+0.2>, <0.48,(3/4)*(11.9)-2.1,5.3>}                            
        cylinder { <0.119,(3/4)*(11.9)-2.9+0.04,5.5+0.2-0.035>, <0.481,(3/4)*(11.9)-2.9+0.04,5.5+0.2-0.035>, 0.2} 
    }
    difference
    {              
        union
        {                                                                        
            torus { 0.2, 0.03 rotate z*90 translate <0.12+0.035,(3/4)*(11.9)-2.9+0.04,5.5+0.2-0.035> }         
            torus { 0.2, 0.03 rotate z*90 translate <0.48-0.035,(3/4)*(11.9)-2.9+0.04,5.5+0.2-0.035> } 
        }                                                                                 
       box {  <0.479,(3/4)*(11.9)-2.86,5.5+0.199>, <0.121,(3/4)*(11.9)-2.1,5> inverse }   
        
    }  
    object { Round_Box(<0.12, (3/4)*(11.9)-2.695,5.5+0.23>, <0.48,(3/4)*(11.9)-2.1,5.3>, 0.03, off) } 
}
union
{     
    // Top opening                                                                
    object
    {
        Round_Box(<0,0,0>, <15.3+0.4, 0.2, (3.1/2) + 0.2>, 0.05, off) 
        translate <-0.2, 11.9, -0.2>
    }
    object
    {
        Round_Box(<0,0,0>, <15.3+0.4, 0.2, (3.1/2) + 0.2>, 0.05, off) 
        translate <-0.2, 11.9, (3.1)/2>
    }
    // Main box   f                                
    Round_Box(<0,0,0>, <15.3,11.9,2.97>, 0.05, off)
    // side beams  
    Round_Box(<0.1,0,0>, <0.4,11.9,3.1>, 0.065, off)  
    Round_Box(<14.9,0,0>, <15.2,11.9,3.1>, 0.065, off)
    // center plane
    Round_Box(<0.3,0,0>, <14.9,11.9,3.12>, 0.05, off)
    // horizontal beam
    Round_Box(<0.04,(3/4)*(11.9),2>, <15.3-0.04, (3/4)*(11.9)-0.2,3.165>, 0.05, off) 
    // side keyboard holders
    side_holder
    object { side_holder translate <-0.2+15.3-0.4,0,0> }
    // keyboard holder
    difference
    {
        Round_Box(<0.3, (3/4)*(11.9)-2.23 ,2>,<15.3-0.3, (3/4)*(11.9)-1.8,5.94>, 0.03, off)  
        cylinder { <0.3, (3/4)*(11.9)-1.8 ,6.075>,<15.3-0.3, (3/4)*(11.9)-1.8,6.075>, 0.2 }
    }
    difference
    {
        Round_Box(<0.3, (3/4)*(11.9)-1.8 ,2>,<15.3-0.3, (3/4)*(11.9)-1.35,5.94>, 0.03, off)
        difference
        {
            cylinder { <0.3, (3/4)*(11.9)-1.35 ,6.075>,<15.3-0.3, (3/4)*(11.9)-1.35,6.075>, 0.2 }
            difference
            {
                box { <(15.3)/2-1.5, 0, -10>, <(15.3)/2+1.5, 20, 10> }                                
                sphere { <0,0,0>, 0.2 scale x*3 translate <(15.3)/2-1.5, (3/4)*(11.9)-1.35, 6.075> }
                sphere { <0,0,0>, 0.2 scale x*3 translate <(15.3)/2+1.5, (3/4)*(11.9)-1.35, 6.075> } 
            }
        }                                                                               
        cylinder { <0,0,0>, <0,0,-5>, 0.075 translate <15.3 / 2, (3/4)*(11.9)-1.53, 10> }
        object { Round_Box(<-0.03,0,5>, <0.03,0.17,-5>, 0.04, off) translate <15.3 / 2, (3/4)*(11.9)-1.67, 10> }
    }
    // boxes around the keyboard
    Round_Box(<0.3, (3/4)*(11.9)-1.35 ,2>,<0.92, (3/4)*(11.9)-1.11 ,5.64>, 0.03, off) 
    Round_Box(<15.3, (3/4)*(11.9)-1.35 ,2>,<15.3-1.22, (3/4)*(11.9)-1.11 ,5.64>, 0.03, off) 
    Round_Box(<14.3, (3/4)*(11.9)-1.35 ,2>,<0.5, (3/4)*(11.9)-0.7 ,4.195>, 0.03, off)
    // feet
    foot   
    object { foot translate<15.3-0.54,0,0> }  
    foot_up
    object { foot_up scale <0,0,-1> translate <0,0,2*(5.5+0.23)-0.955> }
    object { foot_up translate <15.3-0.54,0,0> }
    object { foot_up scale <0,0,-1> translate <15.3-0.54,0,2*(5.5+0.23)-0.955> }
    Round_Box(<0.1, 0, 2>, <0.5, 0.8, 6>, 0.03, off)
    object { Round_Box(<0.1, 0, 2>, <0.5, 0.8, 6>, 0.03, off) translate <-0.2+15.3-0.4,0,0> }
    // rotating panel
    object
    {   
        union
        {
            Round_Box(<0.0, 0 ,0>,<15.3-1, 0.2, 1.7>, 0.03, off)
            Round_Box(<0,0.1,1.7>, <15.3-1, -0.5, 1.5>, 0.03, off) 
        }
        rotate x*(-90-rotation_clapet)
        translate <0.5, (3/4)*(11.9)-0.58, 4.195>
    } 
    
    pigment { rgb 0.01 } 
    finish
    {

        specular 0.01   
        phong 0.1
        phong_size 15
        reflection { 0.004 }
        conserve_energy
    }
}    

// Brass parts 

union
{    
    Round_Box(<0.5,(3/4)*(11.9)-0.7,4>, <15.3-0.5, (3/4)*(11.9)-0.699, 4.195>, 0.001, off)
    object
    {
         Round_Box(<0,0,0>, <14.3, 0.001, 0.195>, 0.001, off)
         rotate x*-rotation_clapet
         translate<0.5,(3/4)*(11.9)-0.697, 4>
    } 
    difference
    {           
        union
        {
            cylinder { <0,0,0>, <0,0,-5>, 0.075 translate <15.3 / 2, (3/4)*(11.9)-1.53, 10> }
            object { Round_Box(<-0.03,0,5>, <0.03,0.17,-5>, 0.04, off) translate <15.3 / 2, (3/4)*(11.9)-1.67, 10> }
        }
        box { <10, 10, 5.935>, <-10, -10, 30> }
        cylinder { <0,0,0>, <0,0,-5>, 0.045 translate <15.3 / 2, (3/4)*(11.9)-1.53, 10> }
        object { Round_Box(<-0.005,0,5>, <0.005,0.15,-5>, 0.015, off) translate <15.3 / 2, (3/4)*(11.9)-1.65, 10> }
    }   
    object
    {
    
        text
        {
            ttf "impact.ttf" "T  E  N  C  H  I" 0.001, 0
            translate <0,0,0.27>
            scale 0.35
            rotate y*180
            rotate x*-rotation_clapet
            translate <0,0.2,0> }
        
        translate <(15.3/2)+0.95, (3/4)*(11.9)-0.58, 4.195>
    }                   
    #declare i = 51;
    #while (i > 0)
        cylinder { <0.3*i,12.1, 3.1 / 2>, <-0.28+0.3*i,12.1, 3.1 / 2>, 0.04 }
        #declare i = i - 1;
    #end                      
    #declare i = 47;
    #while (i > 0)
        cylinder { <0.3*i,(3/4)*(11.9)-0.693, 4.09>, <-0.28+0.3*i,(3/4)*(11.9)-0.693, 4.09>, 0.04 translate <0.56,0,0> }

        #declare i = i - 1;
    #end
    texture
    {                           
        pigment { rgb <217/255,142/255,28/255> }
        finish
        {            
            diffuse 1.2
            ambient 0.2 
            reflection { 0.6 }
        }
    }
} 

union
{           
    //sphere { <15.3/2+3.8,  11.1/2+2.3, 5.0>, 0.03 }    
    
    pigment { rgb <1,0,0> }
    finish
    {
        diffuse 0.3
        ambient 0.5
        specular 0.01   
        phong 0.1
        reflection { 0.1 metallic }
        conserve_energy
    }
}
#declare w_note_tex =
texture
{      
    pigment { rgb 1 }
    finish
    {
        diffuse 0.3
        ambient 0.5
        specular 0.01   
        phong 0.1
        reflection { 0.1 metallic }
        conserve_energy
    }
} 

#declare b_note_tex =  
texture
{         
    pigment { rgb 0.01 }
    //pigment { rgb <1,0,0> }
    finish
    {
        diffuse 0.1
        ambient 0.2
        specular 0.01   
        phong 0.1
        phong_size 15
        reflection { 0.004 }
        conserve_energy
    }
}
                    
#declare w_note_24 = 
difference
{   
    Round_Box(<0,0,0>,<-0.23,0.3,-1.3>,0.02, off)
    Round_Box(<0,-1,1>,<-0.23,0.26,-0.03>,0.02, off)
    translate <-0.005,0,0> 
    texture { w_note_tex }
}
#declare w_note_23 = 
difference
{           
    Round_Box(<0,0,0>,<-0.22,0.3,-1.3>,0.02, off)
    Round_Box(<0,-1,1>,<-0.22,0.26,-0.03>,0.02, off)  
    translate <-0.005,0,0> 
    texture { w_note_tex }
}

#declare bl_note =
union
{                                                                                         
    object { Round_Cylinder(<0.02,0.3 + 0.1, -0.14>, <0.02,0.3 + 0.1, -0.8>, 0.02, 0.02, off) }
    object { Round_Cylinder(<0.12,0.3 + 0.1, -0.14>, <0.12,0.3 + 0.1, -0.8>, 0.02, 0.02, off) }           
    box { <0.02, 0.3+0.1, -0.14>, <0.12,0.3+0.12,-0.8> }
    
    cylinder { <0.02,0.3 + 0.1, -0.15>, <0.02,0.3, 0>, 0.02 } 
    cylinder { <0.12,0.3 + 0.1, -0.15>, <0.12,0.3, 0>, 0.02 }      
    box { <0,0,0>, <0.10, 0.02, 0.180277563773199464> rotate x*33.69 translate <0.02, 0.4, -0.15> }
    
    object { Round_Cylinder(<0.00,0.3 + 0.1, -0.15>, <0.14,0.3 + 0.1, -0.15>, 0.02,0.02,off) }
    object { Round_Cylinder(<0.00,0.3 + 0.1, -0.8>, <0.14,0.3 + 0.1, -0.8>, 0.02,0.02,off) } 
     
     
    object { Round_Cylinder(<0.02,0.32, 0>, <0.02,0, 0>, 0.02, 0.02, off) }
    object { Round_Cylinder(<0.12,0.32, 0>, <0.12,0, 0>, 0.02, 0.02, off) } 
    object { Round_Box     (<0.00,0.32, 0>, <0.14,0, 0>, 0.02, off) }
    
    intersection
    {
        object { Round_Box(<0.14, 0, 0>, <0.0, 0.4, -0.82>, 0.02, off) }
        plane { y,0 rotate x*33.69 translate <0.02, 0.4, -0.15> } 
    }
    texture { b_note_tex }
}
     
#declare hollow_note =
object
{
    Round_Box(<0.01,-1,0.05>, <-0.15,1,-1.35>, 0.05, off)
    texture { w_note_tex }    
}     
     
#declare c_note =
difference
{
     object { w_note_23 }
     object
     {
        hollow_note
        translate <-0.14,0,-0.5>
     }   
}
 
#declare d_note =
difference
{
     object { w_note_24 }
     object
     {
        hollow_note
        translate <-0.14+0.23,0,-0.5>
     }  
     object
     {
        hollow_note
        translate <-0.14*3+0.23,0,-0.5>
     }  
} 

#declare e_note =
difference
{
     object { w_note_23 }
     object
     {
        hollow_note
        translate <-0.14*3+0.23+0.24,0,-0.5>
     }    
} 

#declare f_note =
difference
{
     object { w_note_24 }
     object
     {
        hollow_note
        translate <-0.14*5-0.13+0.23*2+0.24,0,-0.5>
     }    
}  

#declare g_note =
difference
{
     object { w_note_23 }
     object
     {
        hollow_note
        translate <-0.14*5-0.13+0.23*2+0.24*2,0,-0.5>
     } 
     object
     {
        hollow_note
        translate <-0.14*6-0.13*2+0.23*2+0.24*2,0,-0.5>
     }     
} 

#declare a_note =
difference
{
     object { w_note_23 }
     object
     {
        hollow_note
        translate <-0.14*6-0.13*2+0.23*3+0.24*2,0,-0.5>
     } 
     object
     {
        hollow_note
        translate <-0.14*7-0.13*3+0.23*3+0.24*2,0,-0.5>
     }     
}
#declare a_note_first =
difference
{
     object { w_note_23 }
     object
     {
        hollow_note
        translate <-0.14*7-0.13*3+0.23*3+0.24*2,0,-0.5>
     }     
}
 
#declare b_note =
difference
{
     object { w_note_24 } 
     object
     {
        hollow_note
        translate <-0.14*7-0.13*3+0.23*4+0.24*2,0,-0.5>
     }     
}

#declare c_to_b =                           
union
{
    object { c_note }                                                                     
    object { d_note translate <-0.23, 0, 0> }  
    object { e_note translate <-0.23-0.24, 0, 0> }
    object { f_note translate <-0.23*2-0.24, 0, 0> } 
    object { g_note translate <-0.23*2-0.24*2, 0, 0> }
    object { a_note translate <-0.23*3-0.24*2, 0, 0> }
    object { b_note translate <-0.23*4-0.24*2, 0, 0> } 
    
    object { bl_note translate <-0.14*2, 0, -0.5> }
    object { bl_note translate <-0.14*4, 0, -0.5> }
    object { bl_note translate <-0.14*6-0.13, 0, -0.5> }
    object { bl_note translate <-0.14*7-0.13*2, 0, -0.5> }
    object { bl_note translate <-0.14*8-0.13*3, 0, -0.5> }
}         
 
object
{
    union
    {                                                                    
        object { a_note_first }          
        object { bl_note translate <-0.14*2-0.05, 0, -0.5> }
        object { b_note translate <-0.23,0,0> }
        #declare i = 0;
        #while (i < 7)
            object { c_to_b translate <-0.23-0.24 - i*1.64,0,0> } 
            #declare i = i + 1;
        #end 
        object { w_note_24 translate <-0.23-0.24-i*1.64,0,0> }
    }
    scale <1.08,0,1.06>  
    translate <15.3 -1.22, (3/4)*(11.9)-1.42, 5.6>
}

 

Comments (0)

No comments yet!

Post a comment

 
image
art, music, projects © 2006-11 Tenchi