# Can robot.rb be written a ruby way?

**URL:** <https://www.ruby-forum.com/t/can-robot-rb-be-written-a-ruby-way/53343>\
**Category:** Ruby\
**Created:** [February 1, 2006, 11:58pm UTC](https://www.ruby-forum.com/t/can-robot-rb-be-written-a-ruby-way/53343 "2006-02-01T23:58:48Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![anne001](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/34f0e0/32.png) [@anne001](https://www.ruby-forum.com/u/anne001)\
**Post date:** [February 1, 2006, 11:58pm UTC](https://www.ruby-forum.com/t/can-robot-rb-be-written-a-ruby-way/53343/1 "2006-02-01T23:58:48Z")

</div>

This site gives the c code from robot.c in its  
robot-framework-1.3.tar.gz file  
[http://yallara.cs.rmit.edu.au/~aholkner/Interactive3D/](http://yallara.cs.rmit.edu.au/~aholkner/Interactive3D/)

and this site gives a ruby code for the same program in robot.rb in its  
folder sample in version 0.32g  
[http://www2.giganet.net/~yoshi/](http://www2.giganet.net/~yoshi/)

The c program is structured as follows:  
void init(void)  
void display(void)  
void reshape (int w, int h)  
void keyboard (unsigned char key, int x, int y)  
int main(int argc, char\*\* argv)  
{ …  
/\* Tell GLUT to create and display the window, with the given title  
\*/  
glutCreateWindow(“Robot Arm Demo”);

/\* Call our own init function to set up the background color and  
shading  
\* model. \*/  
init ();

/\* Tell GLUT where each of our functions are. We are passing in the  
name  
\* of each function, which it will then call as required. \*/  
glutDisplayFunc(display);  
glutReshapeFunc(reshape);  
glutKeyboardFunc(keyboard);

/\* All initialisation is finished, tell GLUT to run the application  
forever  
\* (or until we tell it to quit) \*/  
glutMainLoop();  
…}

and the ruby program is set up as  
def init  
display = Proc.new {  
reshape = Proc.new {|w, h|  
keyboard = Proc.new {|key, x, y|  
…  
GLUT.CreateWindow($0);  
init();  
GLUT.DisplayFunc(display);  
GLUT.ReshapeFunc(reshape);  
GLUT.KeyboardFunc(keyboard);  
GLUT.MainLoop();  
…  
I was surprised to find that robot.rb is a litteral translation of  
robot.c. No objects talking to each other here!

On the other hand, GLUT has a function ReshapeFunc which requires a  
function, and so reshape is going to be a function, etc, so there may  
not be a lot of room for ruby like programming.

Is it the case here, that because it is calling opengl and GLUT code,  
the structure is going to have to be “C” like, and not “Object OOP”  
like? Or is there a way of writing robot.rb a more ruby like way?

---

<div class="post-metadata">

**Author:** ![anne001](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/34f0e0/32.png) [@anne001](https://www.ruby-forum.com/u/anne001)\
**Post date:** [February 2, 2006, 12:32am UTC](https://www.ruby-forum.com/t/can-robot-rb-be-written-a-ruby-way/53343/2 "2006-02-02T00:32:37Z")

</div>

Actually, maybe it is display which I would like to see more ruby like

display = Proc.new {  
GL.Clear(GL::COLOR\_BUFFER\_BIT);  
GL.PushMatrix();  
GL.Translate(-1.0, 0.0, 0.0);  
GL.Rotate($shoulder, 0.0, 0.0, 1.0);  
GL.Translate(1.0, 0.0, 0.0);  
GL.PushMatrix();  
GL.Scale(2.0, 0.4, 1.0);  
GLUT.WireCube (1.0);  
GL.PopMatrix();

GL.Translate(1.0, 0.0, 0.0);  
GL.Rotate($elbow, 0.0, 0.0, 1.0);  
GL.Translate(1.0, 0.0, 0.0);  
GL.PushMatrix();  
GL.Scale(2.0, 0.4, 1.0);  
GLUT.WireCube(1.0);  
GL.PopMatrix();

GL.PopMatrix();  
GLUT.SwapBuffers();  
}  
In this simple example, the arms are represented by a scaled cube.  
so the basic drawing takes two lines  
GL.Scale(2.0, 0.4, 1.0);  
GLUT.WireCube(1.0);

But the figures I have seen on the internet have a long list of parts,  
for ex

> **[Solved: Draw Robot using opengl , C | Experts Exchange](https://www.experts-exchange.com/questions/21391512/Draw-Robot-using-opengl-C.html)**
>
> Find answers to Draw Robot using opengl , C from the expert community at Experts Exchange

Typically, data like info in ruby would be stored in an object? So I  
should create an object for each body part, with in this case a method  
made of those two lines?

The other problem with this program is that it draws the upper arm, and  
then draws the fore arm at the end of the upper arm. So whatever  
rotation the arm went through the forearm will stay attached to the  
arm. But with a whole body, this way of drawing does not generalise. It  
seems to me that ruby’s object oriented hierarchies would be perfect  
for this.

So in the object Arm, I should create a forearmobject, and in  
forearmobject, I should create a hand object. The method draw arm  
object would draw the arm, and proceed to call the draw forearm method,  
which would draw the forearm, and call the draw hand method.

This program seems to redraw the whole figure from scratch, even if  
only the forearm was changed. I wonder if the computation could be  
saved so only the part changed is redrawn, but it does not sound like  
it, because push and pop suggests a giant laundry list which it would  
not be easy to access in organised pieces.

If this is the case, I just need to figure out who is at the top of the  
hierarchy, probably the hip, and build the thing.

are those thoughts on the right track for a ruby way version of  
robot.rb?

---

<div class="post-metadata">

**Author:** ![anne001](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/34f0e0/32.png) [@anne001](https://www.ruby-forum.com/u/anne001)\
**Post date:** [February 2, 2006, 1:26pm UTC](https://www.ruby-forum.com/t/can-robot-rb-be-written-a-ruby-way/53343/3 "2006-02-02T13:26:14Z")

</div>

On 2/1/06, anne001 [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Typically, data like info in ruby would be stored in an object? So I  
> should create an object for each body part, with in this case a method  
> made of those two lines?
> 
> The other problem with this program is that it draws the upper arm, and  
> then draws the fore arm at the end of the upper arm. So whatever  
> rotation the arm went through the forearm will stay attached to the  
> arm. But with a whole body, this way of drawing does not generalise. It  
> seems to me that ruby’s object oriented hierarchies would be perfect  
> for this.

The usual way is to have a scenegraph, which is a tree that describes  
the scene you’re drawing. You then attach models and transformations  
and material information to the nodes in the graph. When you draw it,  
the  
renderer (for example) traverses the graph depth-first, calling the  
state  
setting functions and drawing functions. Other way would be to collect  
the scene objects into a list and collapse their transforms into world  
coordinates and then draw the list.

This way you can e.g. create a room object for the scene root, attach  
some box objects to it, and put some books in the boxes. Now when  
you move a box, all the books in it move too.

Here’s some pseudocode:  
room = Room.new  
boxes = (1…3).each{  
box = Box.new(:position =\> random\_position)  
box.attach StackOfBooks.new  
box  
}  
room.attach(\*boxes)  
renderer.draw(room)

# hmm, one box too many

room.detach(boxes.last)  
renderer.draw(room)

The renderer#draw could be something like:

def draw(scene)  
clear\_frame  
setup\_default\_state  
setup\_camera  
setup\_lights  
draw\_object(scene)  
swap\_buffers  
end

def draw\_object  
stack\_state{  
transform(obj)  
set\_material(obj)  
draw\_geometry(obj)  
obj.children.each{|c| draw\_object(c) }  
}  
end

> This program seems to redraw the whole figure from scratch, even if  
> only the forearm was changed. I wonder if the computation could be  
> saved so only the part changed is redrawn, but it does not sound like  
> it, because push and pop suggests a giant laundry list which it would  
> not be easy to access in organised pieces.

With OpenGL, it’s going to be a lot slower to figure out what parts of  
the  
frame have changed and need updating, than just clearing the frame and  
drawing everything again. There are some situations where this doesn’t  
apply (like if there’s a huge background scene in the horizon; it can be  
just drawn to a texture once and the texture then used as an impostor),  
but generally it’s not something to worry about.

HTH,  
Ilmari
