> The following was supposedly scribed by > Massimiliano Mirra > on Saturday 20 December 2003 12:17 am: >>>Name of the entity type: square >>> Creation method: center and side >>> Parameters: x and y of center, length of side >> >> Same case again. There is no such thing as a square as far as storage is >> concerned. > >Is storage alone concerned? Data structure is my main concern because given a good data structure, programming is easy. Representation and drawing-level manipulation (see below) are also concerned, but they are agnostic to the fact that it is a special case of polygon. In my examples below, these things are driven solely by the data structure of the entity. >> The simplest definition is a set of four points. This will then >> also contain a set of N points. Whether it is a square or not rarely >> matters to any kind of manipulations/selections. > >What happens when one creates a square, rotates it, and later wants to >change its size by just modifying the length of its side? How are those >four points going to handle it if they don't know the rule by which >they're laid out? Will the square have to be created from scratch and >rotated again? Now you want the square to be modifiable as a *regular polygon*. But this is just a scaling operation with a basepoint. For all entities of this nature, the stage-1 of my @scalefunc will handle the requirements: "pts" => sub { my($pts, $factor) = @_; for(my $i = 0; $i < @$pts; $i++) { foreach my $c (0..2) { $pts->[$i][$c] *= $factor; } } }, # end subroutine $scalefunc[0]{pts} definition The fact that the entity contains a key "pts" triggers the calling of this function. Entity types with other properties which also require scaling are handled by the stage-2 function (like radius => sub {...}), again triggered by the *existence* of the key. Given a basepoint, I simply call complementary Move() operations on each side of the scaling. These functions work on *any* polygon, whether it is regular or not. The only operation that I can think of which would require the polygon to be specially treated as a regular polygon would be to change the number of sides while using the same (existing) length for each side. It seems reasonable at that point (changing from triangle to square) that you would just recreate the entity. Another possibility would be to define both a "pt" and a "pts" key for the regular polygon. This would serve to give it a "snap point" for the scaling operation and would allow you to apply a function which redefines the number of sides while maintaining the same center point. This redef_reg_pgon() function would of course have to check if the polygon is valid as a regular polygon and fail otherwise. The difference between having this check ask the entity if it is a square and having it simply compare the length of all of the sides seems obvious to me: for( i = -1; i < n; i++) { i2 = i+1; len[i] = dist(points[i], points[i2]); } these_are_equal(len) or croak("not a regular polygon"); compared to: switch(type) { case TRIANGLE ok(); break; case SQUARE ok(); break; case PENTAGON ok(); break; case HEXAGON ad infinitum Even if we handle this in a nicer way and bless() the polygon into the Equilateral::Triangle class, we are still creating a finite number of regular polygons. So, what if we just have a Polygon::Regular class and bless any N-sided polygon into it? This is a better solution, but not as simple as having a Polygon class and just using that. Simpler yet (IMO) is to ignore the entity's type entirely and just operate on it's guts. Sure, some entities will have properties (dimensions) which are specific to that entity type, but I imagine that a re-examination will show that conic sections have some properties in common in the same way that lines and polygons do. --Eric