Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number

Re^2: Bear is driving?

by teamster_jr (Curate)
on Apr 03, 2006 at 09:39 UTC ( #540887=note: print w/replies, xml ) Need Help??

in reply to Re: Bear is driving?
in thread Bear is driving?

here is a completely cleaned up version, showing what is actually run:

  • Set up the canvas:
    use GD; $i = new GD::Image( 153, 153, ); $i->colorAllocate( 200, 200, 200 );
  • The functions:
    (by predefining them you don't need to use ())
    • l() is the actual drawing function - it takes and x and y coordinate, then an array of differences to make a polygon, finally the last argument is the colour it wants to be:
      sub l { $p = new GD::Polygon; $x=shift; $y=shift; $p->addPt( ( $x += shift ), ( $y += shift ) ) while $#_; $i->filledPolygon( $p, shift ); }
    • d() calls l() to draw the top (in grey) and right hand (in very dark) sides (this is required to be separate for reasons that will become clear later)
      It takes the starting x and y coordinates, and then has hardcoded the differences to get to other points to make these faces.
      sub d { l @_, 0, 0, 20, -10, 20, 10, -20, 10, $i->colorAllocate( 153, 15 +3, 153, ); l @_, 20, 10, 20, -10, 0, 20, -20, 10, $i->colorAllocate( 20, 0, + 0 ); }
    • a() calls d() then makes the final (front) face in a fairly nasty bluey colour. (the colours were chosen to maximise the string reuse (which will also be explained later).
      sub a { d @_; l @_, 0, 0, 0, 20, 20, 10, 0, -20, $i->colorAllocate( 20, 153, 153 +, ); }
  • and now the list of calls:
    a("73","73"); a("43","88"); a("13","103"); a("13","73"); a("13","43"); a("13","13"); a("43","28"); a("73","43"); a("103","58");
    These basically draw boxes in an order so they stack properly.
    This is added so that the top and right of the first box overlay all the others - creating the impossible perspective.
  • and finally draw it out:
    open FH, ">o.png"; binmode FH; print FH $i->png
Now to save some space:
The call list needs to be shortened. Since X and Y are 2 digit numbers they can be turned into characters, so by changing the part of a() where they are set:
$$_ = ord(shift) - 20 for qw.x y.;
we can then call them like this:
a"]","]"; a"?","l"; a"!","{"; a"!","]"; a"!","?"; a"!","!"; a"?","0"; a"]","?"; a"{","N"; d"]","]"
which then becomes this:
$_ = "]]?l!{!]!?!!?0]?{N"; s#(.)(.)#a"$1","$2";\n#g; /".+;/; $_ .= "d$&"; eval;
ie take two chars out of the string, and replace them with a"$1","$2";, then match the first call and use it to call d();

eval will run the calls, drawing the boxes.

To obfuscate, and save space i then did a form of huffman encoding, where repeated strings are replaced with a single letter, to do this the bulk of the program was but in $_, (using q^..^;) and then run through this:

for$r(qw.$i-> colorAllocate( Polygon shift) l@_, KK); GD 10, I sub 153, 20 new.){$l=chr 65+$c++;s#$l#$r#g}
for each of those strings in the main block, substitute the letter (starting at A (chr 65) ) with the corresponding string, so A is $i-> B is colorAllocat( etc.

finally $_ (all the code) is eval'd

Before posting i run it through my obfu formatter (which i call perlmess - the opposite of perltidy :) ), which simply reformats it as lines of 72 chars. (i also use it in development of these things as it tells me how many chars i'm at, and how many over 4 lines i am etc etc).


Considered by teamster_jr: I was thinking of moving this to mediations as an explanation of obfuscation. is it worth it?
Unconsidered by planetscape: keep votes prevailed (keep:15 edit:3 reap:0)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://540887]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2017-04-26 10:27 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (471 votes). Check out past polls.