Thank you very much for your answers, they are good starting points for me.
What I want to do is something very simple, in the past I wrote a program to display millions of rectangles, each is an widget, being selectable and completely filled with an fl_rect, with a tooltip with its name and selectable rectangle colors (a viewer for semiconductor placements). I'm quite happy now with this simple and straightforward implementation since on powerful machines it's fast enough. On this topic I did exchange information with people from the forum. Now the interesting news: there are also many components with rectilinear shapes (like L-shape, T-shape and many more). The easiest way - for me - would be the possibility of widgets not only x,y,w,h but with a polygonal boundary. This would be a cool feature :-). The second easiest way is to draw a polygon within the standard widget - therefore were my questions below, but there is the drawback that the widget itself is actually bigger than the physical object which creates all sorts of problems many with select and tool tips which could show wrong object name(s). I'm a bit stuck at the moment and thinking of the best way to implement the polygonal objects. Regards, Jens > [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

