POV-Ray : Newsgroups : povray.advanced-users : Manipulator arm design Server Time
1 Nov 2024 03:16:26 EDT (-0400)
  Manipulator arm design (Message 1 to 7 of 7)  
From: David Wallace
Subject: Manipulator arm design
Date: 14 Jul 2003 20:57:27
Message: <3f135177@news.povray.org>
I am trying to find a simple way to set up a manipulator arm consisting of
multiple connected parts.  Let's start with a simple piece definition:

#declare maSection = union {
    box { <-2, 0, -1>, <-1, 9, 1> }
    cylinder { x*-2, x*-1, 1 }
    box { < 1, 0, -1>, < 2, 9, 1> }
    cylinder { x*2, x*1, 1 }
    box { <-1, 1, -1>, <1, 10, 1> }
    cylinder { <-1, 10, 0>, <1, 10, 0>, 1 }
    texture { pigment { rgb <0.45, 0.49, 0.60> } }
}

The idea is have an array of rotation angles,

#declare maRotArray = array [5] { 23, 29, -10, 15, 30 }

so that each joint has its own angle.

A brute force approach might look like this:

#macro ManipArm(ob, sep, Joints)
 #local ps = 0;
 #local nJoint = dimension_size(Joints,1);
 union { #while (ps<nJoint)
  object { ob
   #local rt = 0;
   #while (rt<ps)
    rotate x*Joints[rt]
    translate y*10
    #local rt = rt + 1;
   #end
  }
 #end }
#end

The combined object would look like this:

#declare Arm = object { ManipArm(maSection, 10, maRotArray) }

Note that 5 joints means 6 pieces.  I want to know if this is the best way
to carry it out before proceeding to build such a system with more complex
parts.  Feel free to add array validation or other error checking if you
want.


Post a reply to this message

From: Mike Williams
Subject: Re: Manipulator arm design
Date: 15 Jul 2003 01:32:57
Message: <5PWy9HA3E5E$Ewzs@econym.demon.co.uk>
Wasn't it David Wallace who wrote:
>I am trying to find a simple way to set up a manipulator arm consisting of
>multiple connected parts.  Let's start with a simple piece definition:

I'd suggest having your macro work down the arm in the opposite
direction, from the hand to the elbow, counting ps down from Joints-1 to
zero. I find it easier to get the links in the correct position that
way.

It looks a bit odd having all the links the same size. You might want to
make "ob" into a macro that produces links of different sizes and pass
the size parameters as an array into ManipArm() when then passes the
relevant parameters for the particular link into ob(). In this scene
I've simply used an array of sizes to perform a scaling in the y
direction, but it should give you the general idea.


global_settings { assumed_gamma 1.0 }
camera { location  <10,20,-50> look_at <20, 15, 0>}
light_source {<-1000,1000,-1000> colour rgb 1}
plane {y,0 pigment {rgb 0.8}}

// ----------------------------------------

// Subsection
#declare maSection = union {
    box { <-2, 0, -1>, <-1, 9, 1> }
    cylinder { x*-2, x*-1, 1 }
    box { < 1, 0, -1>, < 2, 9, 1> }
    cylinder { x*2, x*1, 1 }
    box { <-1, 1, -1>, <1, 10, 1> }
    cylinder { <-1, 10, 0>, <1, 10, 0>, 1 }
    texture { pigment { rgb <0.45, 0.49, 0.60> } }
}

//Joint array
#declare maRotArray = array [5] { 23, 29, -10, 15, 30 }
// Joint lengths
#declare maSizeArray = array [6] {10,9,7,5,4,3}


//Connection macro
#macro ManipArm(ob, Lengths, Joints)
 #local ps = dimension_size(Joints,1) - 1;
 #local Arm = union{ob scale <1,Lengths[ps+1]/10,1>}
 #while (ps>=0)
   #local Arm = union {
     object {Arm 
       rotate x*Joints[ps]
       translate y*Lengths[ps]
     }
     object {ob scale <1,Lengths[ps]/10,1>}
   }
   #local ps = ps-1;
 #end
 object {Arm}
#end

//Invocation
object {ManipArm(maSection, maSizeArray, maRotArray) 
  rotate y*90
}


Post a reply to this message

From: David Wallace
Subject: Re: Manipulator arm design
Date: 15 Jul 2003 03:07:20
Message: <3f13a828@news.povray.org>
The connection fingers at each end would scale with the object using your
approach, and I want constant finger lengths.  To accomplish this a macro is
required:

#macro maSection(len) union {
    box { <-2, 0, -1>, <-1, len-1, 1> }
    cylinder { x*-2, x*-1, 1 }
    box { < 1, 0, -1>, < 2, 1en-1, 1> }
    cylinder { x*2, x*1, 1 }
    box { <-1, 1, -1>, <1, len, 1> }
    cylinder { <-1, len, 0>, <1, len, 0>, 1 }
    texture { pigment { rgb <0.45, 0.49, 0.60> } }
} #end

I also wanted very badly to avoid nesting the objects the way your macro
does.  POV-Ray will eventually complain if you have a lot pieces set up this
way.  What I wanted to do was set up an individual transform for each piece
that would allow them to be placed in a group without the nesting:

// Joint array
#declare maRotArray = array [5] { 23, 29, -10, 15, 30 }
// Joint lengths
#declare maSizeArray = array [6] {10,9,7,5,4,3}
// Transform array
#declare maTrnArray = array [5]

//Connection macro
#macro ManipArm(ob, Lengths, Joints, Moves)
 #local aSiz = dimension_size(Joints,1);
 #local ps = 0;
  #while (ps<aSiz)
  #local rt = ps;
  #declare Moves[ps] = transform {
   #while (rt>=0)
    rotate x*Joints[rt]
    translate y*Lengths[rt]
    #local rt = rt - 1;
   #end
  }
  #local ps = ps + 1;
 #end

 union {
  object { maSection(Lengths[ps]) }
  #while (ps<aSiz)
   #local ps = ps + 1;
   object { maSection(Lengths[ps]) transform { Moves[ps-1] } }
  #end
 }
#end

//Invocation
object {ManipArm(maSection, maSizeArray, maRotArray, maTrnArray)
  rotate y*90
}

You do have a point about working backward from the hand to the shoulder,
though.


Post a reply to this message

From: Mike Williams
Subject: Re: Manipulator arm design
Date: 15 Jul 2003 11:15:36
Message: <VXc5bBAZpBF$EwfC@econym.demon.co.uk>
Oops, I missed a "#local ps=ps-1;" in my previous post, so the top unit
was being inserted twice.

global_settings { assumed_gamma 1.0 }
camera { location  <10,20,-60> look_at <20, 15, 0>}
light_source {<-1000,1000,-1000> colour rgb 1}
plane {y,0 pigment {rgb 0.8}}

// ----------------------------------------

// Subsection
#declare maSection = union {
    box { <-2, 0, -1>, <-1, 9, 1> }
    cylinder { x*-2, x*-1, 1 }
    box { < 1, 0, -1>, < 2, 9, 1> }
    cylinder { x*2, x*1, 1 }
    box { <-1, 1, -1>, <1, 10, 1> }
    cylinder { <-1, 10, 0>, <1, 10, 0>, 1 }
    texture { pigment { rgb <0.45, 0.49, 0.60> } }
}

//Joint array
#declare maRotArray = array [5] { 23, 29, -10, 15, 30 }

//Connection macro
#macro ManipArm(ob, sep, Joints)
 #local ps = dimension_size(Joints,1) - 1;
 #local Arm = union{ob}
 #local ps=ps-1;        // This line added
 #while (ps>=0)
   #local Arm = union {
     object {Arm 
       rotate x*Joints[ps]
       translate y*sep
     }
     object {ob}
   }
   #local ps = ps-1;
 #end
 object {Arm}
#end

//Invocation
object {ManipArm(maSection, 10, maRotArray) 
  rotate y*90
}


Post a reply to this message

From: David Wallace
Subject: Re: Manipulator arm design
Date: 17 Jul 2003 23:38:12
Message: <3f176ba4@news.povray.org>
Here is an advanced example of what I'm after:

// Arm

#declare atabHgt = 0.035;
#declare atabHgtB = atabHgt+0.015;
#declare atabThk = 0.005;
#declare atabRadL = 0.055;
#declare atabRadH = 0.075;
#declare atabRadC = atabRadL-atabThk;

#declare ataRadO = atabRadC-atabThk;
#declare ataRadI = ataRadO-atabThk;

#declare ataBase = union {
 difference {
  cone { 0, atabRadH, y*atabHgt, atabRadL }
  cylinder { y*atabThk, y*atabHgtB, atabRadC }
 }
 cylinder { y*atabThk, y*atabHgtB, atabThk*2 }
 sphere { y*atabHgtB, ataRadI }
}

#macro atasLow(ht) difference {
 #local fg = ataRadI+atabThk;
 #local lp = (ataRadI+ataRadO)*0.5;
 union {
  cylinder { -y*fg, y*ht, ataRadO }
  torus { lp, atabThk translate -y*fg }
 }
 box { <-1, -1.1, -1>, <1, -.0, 1> scale <atabRadH, fg, atabThk*.5> }
 cylinder { 0, -y*fg*1.1, ataRadI }
} #end

#macro atasHighB(ht, nf)
 #local fw = ataRadO*2/nf;
 #local fh = ataRadI/fw;
 #local rc = fw*0.5*(nf-2);
 #local hc = ht+0.5*ataRadI;
 #local knob = union {
  cylinder { -x*rc, x*rc, fw }
  sphere { -x*rc, fw }
  sphere { x*rc, fw }
 }
 union {
  difference {
   box { <-1, 0, -1>, 1 }
   cylinder { -y, y*.4, 1 scale <1, 1, 0.3> translate -z }
   cylinder { -y, y*.4, 1 scale <1, 1, 0.3> translate z }
   sphere { 0, 1 scale <1, .4, .3> translate <0, .4,-1> }
   sphere { 0, 1 scale <1, .4, .3> translate <0, .4, 1> }
   scale <rc, hc, fw>
  }
  cylinder { 0, y*hc, fw translate x*rc }
  cylinder { 0, y*hc, fw translate -x*rc }
  object { knob }
  object { knob scale < 1, fh, 1> translate y*hc }
  scale < 1, 1, nf*.5>
 }
#end

#macro atasHighI(ht, nf) difference {
 #local fw = ataRadO/nf;
 atasHighB(ht, nf)
 #local ps = -1.5-nf*.5;
 #local nm = 0;
 #while (nm<nf)
  box {
   <-1.0, 0,-1.1>, < 1.0, 2.1, 1.1> scale <fw, ataRadI, ataRadO>
   translate <ps*fw, ht, 0>
  }
  #set ps = ps + 4;
  #set nm = nm + 2;
 #end
} #end

#macro atasHighO(ht, nf) difference {
 #local fw = ataRadO/nf;
 atasHighB(ht, nf)
 #local ps = 0.5-nf*.5;
 #local nm = 1;
 #while (nm<nf)
  box {
   <-1.0, 0,-1.1>, < 1.0, 2.1, 1.1> scale <fw, ataRadI, ataRadO>
   translate <ps*fw, ht, 0>
  }
  #set ps = ps + 4;
  #set nm = nm + 2;
 #end
} #end

#declare atasL = 0.16;
#declare atasH = 2*ataRadI+atasL;

#declare ataSectB = union {
 object { atasLow(atasL*.5) }
 object { atasHighO(atasL*.5,5) translate y*atasL*.5 }
 translate y*ataRadI
}

#declare ataSectM = union {
 object { atasHighI(atasL*.5,5) rotate x*180 }
 object { atasHighO(atasL*.5,5) }
 translate y*atasH*.5
}

#declare ataSectH = union {
 object { atasHighI(atasL*.5,5) rotate x*180 }
 object { atasHighI(atasL*.5,9) }
 translate y*atasH*.5
}

#declare ataObjs = array[6] { ataBase, ataSectB, ataSectM, ataSectM,
ataSectM, ataSectH }
#declare ataLens = array[6] { atabHgtB, atasH, atasH, atasH, atasH, atasH }
#declare ataAngles = array[5] { <-40, 20, 35>, x*26, x*30 , x*28, x*33 }
#declare ataMoves = array[5]

#macro ManipArm(Objects, Lengths, Joints, Moves)
 #local aSiz = dimension_size(Joints,1);
 #debug concat(str(aSiz,0,0), " objects.\n")
 #local ps = 0;
 #while (ps<aSiz)
  #local rt = ps;
  #declare Moves[ps] = transform {
   #while (rt>=0)
    rotate Joints[rt]
    translate y*Lengths[rt]
    #local rt = rt - 1;
   #end
  }
  #local ps = ps + 1;
 #end
 union {
  #set ps = 0;
  object { Objects[ps] }
  #while (ps<aSiz)
   #local ps = ps + 1;
   object { Objects[ps] transform { Moves[ps-1] } }
  #end
 }
#end

#declare atArm = object {
 ManipArm(ataObjs, ataLens, ataAngles, ataMoves)
}

Well, what do you think?


Post a reply to this message

From: Mike Williams
Subject: Re: Manipulator arm design
Date: 18 Jul 2003 02:28:41
Message: <L+GBwEAwL5F$Ewe4@econym.demon.co.uk>
Wasn't it David Wallace who wrote:
>Well, what do you think?

I think:

global_settings { assumed_gamma 1.0 }
camera { location  <10,20,-60> look_at <20, 20, 0>}
light_source {<-1000,1000,-1000> colour rgb 1}
plane {y,0 pigment {rgb 0.8}}
box {<-4,0,-4>,<4,3,4> pigment {rgb <0.45, 0.49, 0.60>}}

// ----------------------------------------

// Hand unit
#declare Hand = union {
  cylinder {<0,0,-1><0,0,1>,1}
  cylinder {<0,0,-1.1><0,0,1.1>,0.5 pigment {rgb 1}}
  difference {box {<-3,0,-0.7>,<0,3,0.7> rotate -z*45}  
    plane {x,0}
    scale <0.5,1,1>
    rotate -z*10
  } 
  difference {box {<-3,0,-0.7>,<0,3,0.7> rotate -z*45}  
    plane {-x,0}
    scale <0.5,1,1>
    rotate z*10
  } 
  pigment {rgb 0.7}
}

// Subsection
#macro maSection (Length)
union {
    box { <-2, 0, -1>, <-1, Length-1, 1> }
    cylinder { x*-2, x*-1, 1 }
    box { < 1, 0, -1>, < 2, Length-1, 1> }
    cylinder { x*2, x*1, 1 }
    box { <-1, 1, -1>, <1, Length, 1> }
    cylinder { <-1, Length, 0>, <1, Length, 0>, 1 }
    cylinder { <-2.2, 0, 0>,<2.2,0,0>, 0.5 pigment {rgb 1}}
    texture { pigment { rgb <0.45, 0.49, 0.60> } }
}
#end

#declare Unit1 = union {
  box {<-1.5,1,-1.5>,<1.5,2,1.5>}
  box {<-2,0,-1>,<-1,1,1>}
  box {<1,0,-1>,<2,1,1>}
  cylinder {<-2,0,0><-1,0,0>,1}
  cylinder {<2,0,0><1,0,0>,1}
  cylinder {<-2.2,0,0><2.2,0,0>,0.5 pigment {rgb 1}}
}

#declare Unit2 = union {
  box {<-1.5,1,-1.5>,<1.5,2,1.5>}
  box {<-1,0,-1>,<1,1,1>}
  cylinder {<-1,0,0><1,0,0>,1}
}


#macro Section (Length,Shaft,Start,End)
union {
  #switch (Shaft)
    #case (1)
      box {<-1.5,2,-1.5><1.5,Length-2,1.5>}
    #break
    #case (2)
      cylinder {<0,2,0>,<0,Length-2,0>,1.2 pigment {rgb 1}}
    #break
    #case (3)
      cylinder {<0.5,2,0>,<0.5,Length-2,0>,1 pigment {rgb 1}}
      cylinder {<-0.5,2,0>,<-0.5,Length-2,0>,1 pigment {rgb 1}}
    #break
    #case (4)
      cylinder {<0,2,0.5>,<0,Length-2,0.5>,1 pigment {rgb 1}}
      cylinder {<0,2,-0.5>,<0,Length-2,-0.5>,1 pigment {rgb 1}}
    #break
  #end
  #switch (Start)
    #case (1)
      object {Unit1}
    #break
    #case (2)
      object {Unit2}
    #break
  #end
  #switch (End)
    #case (1)
      object {Unit1 scale <1,-1,1> translate y*Length}
    #break
    #case (2)
      object {Unit2 scale <1,-1,1> translate y*Length}
    #break
  #end
  texture { pigment { rgb <0.45, 0.49, 0.60> } }
}
#end


// Array for 6 subunits
// Each subunit has: [0] Length
//                   [1] Angle
//                   [3] Shaft type
//                   [4] Start type
//                   [5] End type
// The final section is different. The hand has:
//                   [0] scale
//                   [1] Angle
//                   [2] Rotation
#declare maInfo = array [6][5] {
 // Len Ang Shf Str End
    {10,-10, 1,  1,  2},
    {15, 45, 2,  1,  2},
    {8,  29, 4,  1,  1},
    {8, -10, 2,  2,  1},
    {7,  15, 3,  2,  1},
 // Siz Ang Rot
    {1.5, 0,45,  0,  0}  // Hand section
 }       


//Connection macro
#macro ManipArm(Info)
 #local ps = dimension_size(Info,1) - 1;
 #local Arm = object {Hand 
     scale Info[ps][0] 
     rotate y*Info[ps][2] 
     rotate x*Info[ps][1]
 }
 #local ps=ps-1;
 #while (ps>=0)
   #local Arm = union {
     object {Arm 
       translate y*Info[ps][0]
     }
     object {Section(Info[ps][0], Info[ps][2], Info[ps][3],
Info[ps][4],)}
     rotate x*Info[ps][1]
   }
   #local ps = ps-1;
 #end
 object {Arm}
#end

//Invocation
object {ManipArm(maInfo) 
  rotate y*140
}


Post a reply to this message

From: David Wallace
Subject: Re: Manipulator arm design
Date: 18 Jul 2003 07:52:04
Message: <3f17df64@news.povray.org>
"Mike Williams" <mik### [at] econymdemoncouk> wrote in message
news:L+GBwEAwL5F$Ewe4@econym.demon.co.uk...
> Wasn't it David Wallace who wrote:
> >Well, what do you think?
>
> I think:
>
It works, but I think the hand has been partly screwed out of its socket.
Now for one of my arm applications: a table with three arms on it... with
hands.

// Table texture

#declare IsTest=0;
#declare colArm = texture {
 pigment { rgb <0.43, 0.46, 0.55> }
 #if (!IsTest)
  MetFinish(2)
  normal { average
   normal_map {
    [1.00 wrinkles 0.2 scale .03]
    [1.00 dents 0.3 scale .1]
   }
  }
 #end
}

// Arm Table

#declare atabHgt = 0.035;
#declare atabHgtB = atabHgt+0.015;
#declare atabThk = 0.005;
#declare atabRadL = 0.055;
#declare atabRadH = 0.075;
#declare atabRadC = atabRadL-atabThk;

#declare ataRadO = atabRadC-atabThk;
#declare ataRadI = ataRadO-atabThk;

#declare ataBase = union {
 difference {
  cone { 0, atabRadH, y*atabHgt, atabRadL }
  cylinder { y*atabThk, y*atabHgtB, atabRadC }
 }
 cylinder { y*atabThk, y*atabHgtB, atabThk*2 }
 sphere { y*atabHgtB, ataRadI }
}

#macro atasLow(ht) difference {
 #local fg = ataRadI+atabThk;
 #local lp = (ataRadI+ataRadO)*0.5;
 union {
  cylinder { -y*fg, y*ht, ataRadO }
  torus { lp, atabThk translate -y*fg }
 }
 box { <-1, -1.1, -1>, <1, -.0, 1> scale <atabRadH, fg, atabThk*.5> }
 cylinder { 0, -y*fg*1.1, ataRadI }
} #end

#macro atasHighB(ht, nf)
 #local fw = ataRadO*2/nf;
 #local fh = ataRadI/fw;
 #local rc = fw*0.5*(nf-2);
 #local hc = ht+ataRadI;
 #local ch = 0.30;
 #local th = 0.10;
 #local knob = union {
  cylinder { -x*rc, x*rc, fw }
  sphere { -x*rc, fw }
  sphere { x*rc, fw }
 }
 union {
  difference {
   box { <-1, 0, -1>, 1 }
   cylinder { -y, y*ch, 1 scale <1, 1, th> translate -z }
   cylinder { -y, y*ch, 1 scale <1, 1, th> translate z }
   sphere { 0, 1 scale <1, ch, th> translate <0, ch,-1> }
   sphere { 0, 1 scale <1, ch, th> translate <0, ch, 1> }
   scale <rc, hc, fw>
  }
  cylinder { 0, y*hc, fw translate x*rc }
  cylinder { 0, y*hc, fw translate -x*rc }
  object { knob }
  object { knob scale < 1, fh, 1> translate y*hc }
  scale < 1, 1, nf*.5>
 }
#end

#macro atasHighI(ht, nf) difference {
 #local fw = ataRadO/nf;
 atasHighB(ht, nf)
 #local ps = 1-nf;
 #while (ps<nf)
  box {
   <-1.0, 0,-1.1>, < 1.0, 2.1, 1.1> scale <fw, ataRadI, ataRadO>
   translate <ps*fw, ht, 0>
  }
  #set ps = ps + 4;
 #end
} #end

#macro atasHighO(ht, nf) difference {
 #local fw = ataRadO/nf;
 atasHighB(ht, nf)
 #local ps = 3-nf;
 #while (ps<nf)
  box {
   <-1.0, 0,-1.1>, < 1.0, 2.1, 1.1> scale <fw, ataRadI, ataRadO>
   translate <ps*fw, ht, 0>
  }
  #set ps = ps + 4;
 #end
} #end

#declare atasL = 0.16;
#declare atasH = 2*ataRadI+atasL;

#declare ataSectB = union {
 object { atasLow(atasL*.5) }
 object { atasHighO(atasL*.5,5) translate y*atasL*.5 }
 translate y*ataRadI
}

#declare ataSectM = union {
 object { atasHighI(atasL*.5,5) rotate x*180 }
 object { atasHighO(atasL*.5,5) }
 translate y*atasH*.5
}

#declare ataSectH = union {
 object { atasHighI(atasL*.5,5) rotate x*180 }
 object { atasHighO(atasL*.5,9) }
 translate y*atasH*.5
}

#macro ataHand(bend, len)
 #local cl = ataRadO/9;
 #local cr = ataRadI*0.3;
 #local lds = cr*2+len;
 #local bdy = cos(radians(bend*.5));
 #local bdx = sin(radians(bend*.5));
 #local lnd = <-cr*2*bdx, (lds+len)*bdy, 0>;
 #local hSect = union {
  torus { cr*2, cl rotate z*90 }
  cylinder { y*cr*2, y*lds, cl rotate x*bend }
  sphere { y*lds, cl rotate x*bend }
  cylinder { y*0, y*len, cl rotate x*-bend translate y*lds rotate x*bend }
  sphere { y*len, cl rotate x*-bend translate y*lds rotate x*bend }
  rotate -x*bend*.5
 }
 #local vSect = cylinder {
  -x*cl*6, x*cl*2, cl
  translate y*len rotate -x*bend
  translate y*lds rotate x*bend*0.5
 }
 union {
  difference {
   cylinder { -x*cl*7, x*cl*3, cr*2 }
   cylinder { -x*cl*5, x*cl*1, cr*3 }
   cylinder { -x*cl*8, x*cl*4, cr }
  }
  object { hSect translate -x*cl*6 }
  object { hSect translate  x*cl*2 }
  object { vSect }
 }
#end

#declare ataHandL = object { ataHand(75, 0.05) }
#declare ataHandR = object { ataHand(75, 0.05) rotate y*180 }

#declare ataObjs = array[8] { ataBase, ataSectB, ataSectM, ataSectM,
ataSectM, ataSectH, ataHandL, ataHandR }
#declare ataLens = array[8] { atabHgtB, atasH, atasH, atasH, atasH, atasH,
0, 0 }
#declare atArmAng = array[1][3]
#declare atArmAng[0][0] = array[7] { <-40, 20,-35>, x*26, x*30 , x*28, x*33,
x* 5,-x*10 }
#declare atArmAng[0][1] = array[7] { < 10, 70,  5>, x* 6, x* 4 , x* 8, x*13,
x*10,-x*20 }
#declare atArmAng[0][2] = array[7] { <- 3,-90,-15>, x*10, x* 8 , x*14, x*11,
x*15,-x*30 }
#declare ataMoves = array[7]

#macro ManipArm(Objects, Lengths, Joints, Moves)
 #local aSiz = dimension_size(Joints,1);
 #debug concat(str(aSiz,0,0), " objects.\n")
 #local ps = 0;
 #while (ps<aSiz)
  #local rt = ps;
  #declare Moves[ps] = transform {
   #while (rt>=0)
    rotate Joints[rt]
    translate y*Lengths[rt]
    #local rt = rt - 1;
   #end
  }
  #local ps = ps + 1;
 #end
 union {
  #set ps = 0;
  object { Objects[ps] }
  #while (ps<aSiz)
   #local ps = ps + 1;
   object { Objects[ps] transform { Moves[ps-1] } }
  #end
 }
#end

#macro atArm(obn, arn) object { ManipArm(ataObjs, ataLens,
atArmAng[obn][arn], ataMoves) } #end

#declare atlgTop = otswRad+otsgWid;

#declare atgArm = union {
 cylinder { 0, y*otswRad, otsgRadT translate z*otsgWid }
 cylinder { 0, y*otswRad, otsgRadT translate -z*otsgWid }
 //cylinder { z*otsgWid,-z*otsgWid, otsgRadT translate y*(otswRad+otsgWid) }
 object {
  SectorY( torus { otsgWid, otsgRadT }, 180 )
  rotate <0, 90, 90>
  translate y*otswRad
 }
 sphere { y*atlgTop, otswRadC }
}

#declare atlGuard = union {
 ObjRound ( atgArm, z*90, z*-45, 5 )
 sphere { z*otsgWid, otswRadC }
 sphere { -z*otsgWid, otswRadC }
 cylinder { z*otsgWid,-z*otsgWid, otswRadC }
 object {
  SectorY( torus { atlgTop, otsgRadT }, 180 )
  rotate -x*90
 }
}

#declare atlHgt = 1.0;
#declare atlHgtW = 0.02;
#declare atlInset = 0.3;
#declare atlWid = 0.05;
#declare atlThk = 0.05;
#declare atlShift = otswRad+otswRadT;
#declare atlbShift = atlShift+otswRad+otsgWid+atlHgtW;

#declare atlBow = difference {
 #local r1 = <atlInset-atlThk, atlHgt*0.5, atlWid+atlThk>;
 #local r2 = r1+<atlThk, atlThk,-atlThk>;
 cylinder { -z, z, 1 scale r2 }
 cylinder { -z, z, 1 scale r1 }
 plane { y, -atlHgt*0.5 }
 plane { y, -atlHgt*0.5 rotate x*180 }
 plane { -x, 0 }
 translate x*atlThk*1.25
}

#declare atlBody = union {
 object { atlBow }
 box { -.5, .5 scale <atlThk*2.5, atlHgt*0.1, atlWid*2> translate
y*atlHgt*.55 }
 box { -.5, .5 scale <atlThk*2.5, atlHgt*0.1, atlWid*2>
translate -y*atlHgt*.55 }
 translate y*atlHgt*0.6
}

#declare atRad = 0.40;

#declare atLeg = union {
 object { atlBody translate y*atlbShift }
 object { otsWheel translate y*atlShift }
 object { atlGuard translate y*atlShift }
 cylinder { -y*atlHgtW, y*atlHgtW, otsgRadT translate y*atlbShift }
 translate x*atRad
}

#declare attThk = 0.01;
#declare attAlt = atlbShift+atlHgt*1.2+attThk;
#declare attRad = atRad*1.2;

#declare atTop = union {
 cylinder { 0, -y*attThk, attRad-attThk }
 torus { attRad-attThk, attThk }
 torus { attRad*.5-attThk, attThk*2 scale <1, 2, 1> translate y*attThk*3 }
 translate y*attAlt
}

#declare ataPos = attRad*0.7;

#macro ArmTable(obn) union {
 ObjRound( atLeg, y*0, y*120, 3 )
 torus { atRad, atlThk*.6 translate y*(atlbShift+atlHgt*.05) }
 torus { atRad-atlInset+atlThk*1.75, atlThk*.6 translate
y*(atlbShift+atlHgt*0.60) }
 torus { atRad, atlThk*.6 translate y*(atlbShift+atlHgt*1.15) }
 object { atTop }
 object { atArm( obn, 0 ) translate <ataPos, attAlt, 0> rotate y* 60 }
 object { atArm( obn, 1 ) translate <ataPos, attAlt, 0> rotate y*-60 }
 object { atArm( obn, 2 ) translate <ataPos, attAlt, 0> rotate y*180 }
 texture { colArm }
} #end

light_source { <10,  50, -15>, 2.0
 fade_distance 23
 fade_power 1.3
}
light_source { <.3, -1.1,  1>, rgb <0, 0, 1> }
camera { location <-1.7,  2.0,-1.60> look_at <-0.0, 1.3, 0.0> }
object { ArmTable(0) }

My textures employ a custom version of metals.inc that I adapted to use
macros and metallic reflection.


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.