[moved this thread from fltk.development]
>> On 12/06/11 06:50, Jens Grunert wrote:
>>> I want to draw comlex geometries and keep hitting this one in
>>> the documentation: "the functionality matches that found in the Adobe 
>>> PostScript".
>>> I searched already a lot on the net but could not find a concise, good and 
>>> easy
>>> to read explanation of the complex drawing functions (like tranform, scale, 
>>> translate etc.).
>>> 
>>> Does someone in the forum could point me to some good documentation 
>>> regarding
>>> the postscript-like functionality of the complex drawing functions?
> 
>> On Wed, Dec 7, 2011 at 2:40 AM, MacArthur, Ian (SELEX GALILEO, UK) 
>> <[email protected]> wrote:
>>     Jens,
>> 
>>     First off, you are posting in the wrong list (the dev list is for
>>     development *of* fltk, not *using* fltk) so you will more likely get a
>>     constructive answer over in fltk.general, which is also more active
>>     anyway...
>> 
>>     > I want to draw comlex geometries and keep hitting this one in
>>     > the documentation: "the functionality matches that found in
>>     > the Adobe PostScript". [..]
>> 
>>     What are you actuallly trying to draw? If you post over in fltk.general,
>>     outlining something of what you are trying to do, I'm sure you'll get
>>     somne answers.
>> 
>>     For what it is worth, I tend to favour GL for any complex drawing
>>     anyway, so that might be your best bet, create an Fl_Gl_Window for your
>>     drawing and use regular GL drawing (for which there are many examples on
>>     the web, of course!)

> On 12/07/11 05:59, E. Torres wrote:
> Wikipedia is a good point to start with those kind of questions
> http://en.wikipedia.org/wiki/Transformation_matrix

    In general I'd agree with Ian; openGL is probably the better choice
    for doing complex drawing.

    However, FLTK's own drawing functions (that don't involve opengl)
    do include a reasonable implementation of line drawing with scaling,
    transformation matrices, etc.

    For docs on the web, search for 'transformation matrix tutorial',
    or better yet, go to a bookstore and look for graphics programming books,
    such as for game programmers or 3D computer graphics. I'm sure many
    of the programmers here who work in 3D have the "Graphics Gems"
    series of books, which covers this.

    Also, there are surely some tutorials on PostScript that
    have a good description of the techniques.

    Off the top of my head regarding just scale/translate/rotate and
    matrix operations.. In general, if you've ever plotted a circle
    using sin() and cos(),  you know that to get it draw on your screen,
    you can't just plot the raw sin/cos values, or you'll end up with a dot
    instead of a circle, eg:

        for ( float f=0; f<6.28; f+=.1 ) {
            x = sin(f);
            y = cos(f);
            plot(x,y);                  // results in a tiny circle
        }

    ..because the sin()/cos() values range from just -1 to 1.

    So to get the circle to show up on the screen properly, you might
    multiply the values by some constant (50), and then add some constant (80)
    so that the circle is not clipped off the screen:

        for ( float f=0; f<6.28; f+=.1 ) {
            x = sin(f) * 50 + 80;
            y = cos(f) * 50 + 80;
            plot(x,y);                  // plots a 100 pixel diameter circle
        }

    Here you've basically got a scale of 50 and a translation of 80.
    Just by doing that, you've learned how to scale and translate
    an object.

    Since all "rotation" operations follow circular paths, by knowing
    how to plot a circle, you can plot shapes inside that circle, and
    apply offsets to the angle value to make that shape rotate.

    So to make a rotating square, you can take the four verticies
    of your square, and multiply them by sin() and cos(), and use
    the angle value to determine the rotational orientation of the
    vertices.

    And if you play with one of the scale values, you can "skew" or "flatten"
    the circle along an axis, such that the rotating square now travels along
    a "flattened" path, making it appear as if it's rotating along a 3D plane.

    If you adjust that scale along a sin() or cos() path, you can make the
    square appear to rotate in 3D. (There's more involved to simulate 
'perspective',
    but the above demonstrates a simple 'isometric' example)

    All this simple scale/translate stuff is interesting, but it can
    be compartmentalized into a 'transformation matrix', which is a math
    shortcut for representing all the above (scale,rotation,translation,skew)
    in a small 2D array of values that can then be treated as a discrete unit;
    a matrix.

    You can then create a 'hierarchy' of these that can be applied to one
    another, to make arrangements of objects that act as if they're connected
    to each other. Often this is called a matrix hierarchy, and can be used
    for grouping objects together, or drawing them relative to one another.

    When you assign a matrix to each object, when you go to draw them,
    the object's drawing code can all refer to fixed positions, and the
    matrix can be applied to all the drawing operations so as to move them
    relative to one another, so that they draw where they should be,
    and not all on top of one another.

    To apply one matrix to another is a "matrix multiply" operation, where one
    matrix is multiplied by the other. (The actual mechanics of how the 
individual
    values in the matrix are manipulated to do a 'matrix multiply' are very 
specific,
    won't go into those details here) This causes the rotations and translations
    to be applied such that they combine to form a new matrix that represents
    the combined position of the objects before it.

    So if one matrix has a translation on X of 10,  and the other has a
    translation on X of 5, the resulting matrix will have a translation
    of 15 on X. This results in a new drawing matrix that can be applied
    to the new object being drawn. Then repeat this operation for the next
    object in the chain to find its position.

    The same goes for rotations and scales.

    For instance, if you're trying to draw a clock with minute and second hands,
    and the clock is on a pendulum, and the pendulum is on a boat bobbing
    in the sea, you'd design all these objects to be drawn relative to 0,0
    at their centers.

    So if you were to draw all the objects without a matrix, they'd all
    draw all over each other, their center all being in the same 0,0 position.

    You would then assign a separate matrix each to each object;
    the boat, pendulum, clock, and individual clock hands. Then adjust
    the matrix of each so that their translations are relative to the
    object it's connected to. So if the pendulum is on the boat's deck
    at 10,10 relative to the boat's center, that would be the pendulum's
    matrix translations. And if the clock is 1 unit along Y from the pendulum's
    center, the clocks matrix would have 1 for the Y translation. etc.

    So now when you draw the objects, you start with the boat, and use
    its matrix as the 'current drawing matrix', so that when you draw
    the boat, the matrix is applied to each vertex, moving its actual
    drawing position.

    Then, before drawing the pendulum, you take the current drawing
    matrix (which is the boat's position), and multiply it by the
    pendulum's matrix.. the result is the pendulum's position relative
    to the boat's position. Make the result the new 'current drawing matrix',
    and then draw the pendulum. Repeat for the clock and hands.

    Doing this, any changes in one of the object's matrix affects
    that object's position, and the position of all objects connected to it,
    the "matrix hierarchy" defines which object is connected to which.

    Most people don't manipulate the matrix directly, they use functions
    like translate() and scale() to affect it, and these are usually
    provided by the API. However, sometimes it's useful to directly
    access or manipulate the values in the matrix.

    Most folks just think of the matrix as a 'magic array of numbers'
    that you use translate()/scale()/etc to manipulate, and conceptually
    imagine one of these matrices at the pivot point of each object in
    the hierarchy. A skeleton for instance would have a separate matrix
    for each joint, and the arrangement of matrices defines the hierarchy
    of the skeleton.

    Anyway, I know there's docs out there that cover all this, and
    bezier curves, and all the rest.

    Time to go to work..!

_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to