Click here to Skip to main content
15,881,839 members
Articles / Programming Languages / C#

GridMethod - How to Hack Art

Rate me:
Please Sign up or sign in to vote.
4.14/5 (4 votes)
14 Aug 2020CPOL7 min read 12.1K   240   10   3
Download a masterpiece, set-up this app and hack yourself into an artist
Have you ever wanted to draw a decent mural for your kids' play room? Need to impress your high-school sweet heart who falls for the artsy types and you haven't drawn anything since that flower vase in Mrs. Lehrer's art class way back in Jr. High. Even if you're a mediocre to all out crappy artist, the GridMethod is an engineer's approach to drawing, it's like turning yourself into a dot-matrix printer and you're an artist before you run out of ink. Point on the screen, get the coordinates of what you're looking at to match with where that corresponds on your canvas. You still have to do the drawing but at least you won't get dumped until the middle of next week when she discovers that you're not really an unemployable starving artist but only another great well-paid engineer ... those are the breaks.

Image 1

But Is It Art?

I have a lot of time on my hands and like to fill what I call 'my general knowledge bin' with activities, books and projects that are outside my comfort zone. So, a while back, I ordered a copy of 'Gray's Anatomy' on-line and started making a study of it. No, I will never pass a Med-School Anatomy exam but the time I spent on it certainly improved my general knowledge of human anatomy and, as a bonus, I discovered that putting some effort into drawing all of those 250-odd anatomy illustrations drastically improved my drawing hand. At first, I just dropped the pen on the paper and gave it the old-college try at drawing these anatomical images. But they were sometimes blurry and required careful reading of the text to label all the gooey nerve, tendon and vascular bits. Nevertheless, I would have been proud of the first few illustrations I tested my artistic eye on, had they been drawn by my seven year old. However, putting all that energy into making a study of the text got me to thinking that I could probably do better than those few original warbly doodles.

Behold!

I give you 'the Grid Method'. You measure, and measure then look and draft the curves and measure again. It may be slow and tedious, but the results are pretty good.

My Gray's Anatomy notes are lost and of little use to me now but my ability to replicate an existing painting, photograph or collage of images is enormously satisfying. Sure, I'm still a middling artist who couldn't draw a decent Simpsons' character unless I was trying to draw cute little Lisa and failed so miserably it ended up looking more like wrinkly old Grandpa but at least I have engineering enough to make this app and use it. Now I can doff a scarf and smoke cigarettes with a holder while grandiloquently talking artsy about chiaroscuro like I know what it means. And isn't that what being an artist is all about?

This picture below is a painting by Peter Paul Rubens titled The Fight for the Standard. It's a master-piece and he's a genius.

Image 2

It's definitely one of my favorite paintings and you can read about it here where you'll discover that it was copied from a mural in Florence that was painted by Leonardo daVinci in 1505. That mural has been lost but since I wanted one and the money I'd been holding on to buy the Rubens above (which sold at Sotheby's for $785 000 USD) is tied up in other ventures at the moment, I figured I'd make my own and headed to the Dollar Store for necessities. Using an old yellowish bedsheet, this app and $8 worth of permanent markers I drew it myself in 12 days (March 2020).

Image 3

And I've never even played Pictionary, let alone studied Fine Arts. My tools are For-Loops and Functions, Diodes, widgets and Shift-Registers not brushes, paints or ink pots!

You can see the 'Dry Erase' green marker lines I used to draw the grid (reminder: don't use green Dry Erase markers on cloth if you intend to erase it later). Then I made a rectangular plastic cut-out to place over each grid square one at a time to measure all significant points and hacked away at it for just under two weeks. Each grid square took between 3-4 hours, several took longer for a total of about 100 hours. You may be a crunch-time-hero at your engineering firm but there's nothing like waking up beneath the replica of a Rubens masterpiece that you drew yourself to cheer you up in the morning.

And when that gets dull, you can make another.

Have a look at my latest Art project (June/July 2020), Albrecht Dürer's The Knight, the Devil and Death.

Image 4

I'm still working on 'hacking photography' so the above image is a little blurry but here's a close up of the Knight's horse's head.

Image 5

You can download other close-up shots of my 177cm x 133cm replica of Albrecht Dürer's original copper engraving.

I've spent all this time drawing this masterpiece ... (it looks pretty friggin' awesome on my wall) and I can't even draw Lisa Simpson unless I use this app! It's all a matter of measuring and connecting the dots, a bit of patience and some follow-through during a few weeks of Covid-ing at home alone and you have yourself a great piece of art which no one who didn't actually watch you draw it will ever believe you did because it's obviously that good!

The Grid Method makes art 'hackable'...

Maybe there's a hobby in this for you too.

Grid Method

As described above, this is an app that can make anyone who has the patience and the will to draw something into the semblance of an artist.

Here's a screen capture below:

Image 6

The control panel at the top lets you select the image you want to draw. The grid values (6, 5) shown here correspond to the number of columns and rows in your grid. You can change this at any time but should probably stick to one set of values for the duration of your project. Use a discarded piece of translucent plastic from your recycling bin to make a square frame that's a bit bigger than the size of one grid square on your canvas and draw a ruler on all edges to help you measure, then start from the bottom-right of your canvas and work your way to the top-left one grid-square at a time being certain to always build on what you've already drawn. The Auto-size option lets you enter the size of your canvas and the Grid Method app will center the image on your canvas for you so that all you have to do is point the mouse cursor anywhere on the screen and read the measurements that they correspond to on your canvas. You can see in the image above a small label near the top right of grid (1, 1) that reads (22.04, 5.00) these values are the cartesian coordinates (x, y) of the point on your canvas measured from the top-left of the current grid square. Just point the mouse, read the value, measure and draw. You can use menu options to measure from the top-left of the canvas (as opposed to the current grid square) but that defeats the point of having a grid at all. If you want to exercise your rights as an engineer and do the math yourself, uncheck the auto-size option and ease yourself into the artsy waters with a calculator if it makes you feel better but the auto-size option is pretty handy.

Pick a painting or significant other's portrait and have a go, you'll soon discover you have a talent for this.

The Code

The code is just a simple user-interface. There's nothing really difficult about this project. It makes use of a picture-viewer that I put together a while back that allows the user to zoom into an image on the screen using the mouse-wheel. This is the PictureViewer:PictureBox object called picViewer. Have a look at some of picViewer's event handlers listed below where much of the action is happening.

C++
picViewer.MouseWheel += PicViewer_MouseWheel;
picViewer.MouseMove += PicViewer_MouseMove;
picViewer.MouseDown += PicViewer_MouseDown;
picViewer.MouseUp += PicViewer_MouseUp;
picViewer.MouseLeave += PicViewer_MouseLeave;
picViewer.MouseEnter += PicViewer_MouseEnter;

The text you see in the Cartesian coordinates label is written in either Metric or Standard form which might be of interest for code-reuse:

C++
string RulerText
{
    get
    {
        if (RulerMeasureFromEdge)
        {                    
            if (Metric)
            {
                double dblX = 
                (double)((double)picViewer.lstRegions[0].ptMousePosition.X * Ratio_X);
                double dblY = 
                (double)((double)picViewer.lstRegions[0].ptMousePosition.Y * Ratio_Y);

                return "("
                        + dblX.ToString(".00")
                        + ", "
                        + dblY.ToString(".00")
                        + ")";
            }
            else
            {
                float fltX = 
                (float)((double)picViewer.lstRegions[0].ptMousePosition.X * Ratio_X);
                float fltY = 
                (float)((double)picViewer.lstRegions[0].ptMousePosition.Y * Ratio_Y);

                string strX = Math3.classMath3.FeetDecimalToFraction(fltX/12f);
                string strY = Math3.classMath3.FeetDecimalToFraction(fltY/12f);
                return "(" + strX + ", " + strY + ")";
            }
        }
        else
        {
            double dblX = ((double)picViewer.lstRegions[0].ptMousePosition.X);
            double dblGridWidth = GridWidth;
            while (dblX > dblGridWidth)
                dblX -= dblGridWidth;

            double dblY = (double)picViewer.lstRegions[0].ptMousePosition.Y;
            double dblGridHeight = GridHeight;
            while (dblY > dblGridHeight)
                dblY -= dblGridHeight;
            if (Metric)
                return "("
                        + (dblX * Ratio_X).ToString(".00")
                        + ", "
                        + (dblY * Ratio_Y).ToString(".00")
                        + ")";
            else
            {
                string strX = Math3.classMath3.FeetDecimalToFraction
                              ( (float)((dblX / dblGridWidth * txtCanvas_Width.Value / 
                              (double)nudGridWidth.Value) / 12.0));
                string strY = Math3.classMath3.FeetDecimalToFraction
                              ( (float)((dblY / dblGridHeight * txtCanvas_Height.Value / 
                              (double)nudGridHeight.Value) / 12.0));
                return "(" + strX + ", " + strY + ")";
            }
        }
    }
}

public static string FeetDecimalToFraction(float fltFeet)
{
    int intSign = Math.Sign(fltFeet);
    fltFeet = Math.Abs(fltFeet);

    int intFeet = (int)fltFeet;// - Math.Floor(fltStandard));

    float fltInches = (fltFeet- (float)intFeet) * 12f;
    int intInches = (int)fltInches;// - Math.Floor(fltInches));

    float fltSixteenths = (fltInches - (float)intInches) * 16f;
    int intSixteenths = (int)(fltSixteenths+.5);// - Math.Floor(fltSixteenths));

    classFraction cFraction = new classFraction(intSixteenths, 16);
    classFraction cFraction_Reduced = classFraction.ReduceToLowestTerms(ref cFraction);
    if (intFeet == 0 && intInches == 0 && cFraction_Reduced.Numerator == 0)
        return "0";

    if (cFraction_Reduced.Denominator == cFraction_Reduced.Numerator)
    {
        cFraction_Reduced.Numerator = 0;
        intInches++;
        if (intInches == 12)
        {
            intInches = 0;
            intFeet++;
        }
    }

    string strRetVal = (intSign < 0
                                ? "-"
                                : "")
                        + (intFeet != 0
                                ? intFeet.ToString() + "\""
                                : "")
                        + (intInches > 0 || cFraction_Reduced .Numerator >0
                                ? intInches.ToString() + "'"
                                : "")
                        + (cFraction_Reduced.Numerator > 0
                                ? cFraction_Reduced.toString()
                                : "");
    return strRetVal;
}

Summary

With the Novel Corona Virus Covid-19 locking you indoors, now might be a good time to try your hand at something new. Grab some of your kid's crayons (except the bright pink glossy one she likes so much) and have a go. You might add some color in your life.

History

  • 20th March, 2020
    • Initial version
  • 23rd March, 2020
    • Uploaded new source code - fixed file-dialog issues
  • 17th July, 2020
    • Updated source code - added ruler
  • 14th August, 2020
    • Added CTRL-SHIFT-Z zoom info label
    • Center-mouse button grab and move option
    • Images of my latest project, The Knight, the Devil and Death

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO unemployable
Canada Canada
Christ Kennedy grew up in the suburbs of Montreal and is a bilingual Quebecois with a bachelor’s degree in computer engineering from McGill University. He is unemployable and currently living in Moncton, N.B. writing his next novel.

Comments and Discussions

 
Questionlocation of call to picture Pin
furio5023-Mar-20 2:43
furio5023-Mar-20 2:43 
AnswerRe: location of call to picture Pin
Christ Kennedy23-Mar-20 13:51
Christ Kennedy23-Mar-20 13:51 
thank you for your interest,
you just click the 'Image' button in the controls panel box at the top left of the screen.
if you can't see the controls panel you may have to right click the mouse and use the context-menu to put it back on the screen by selecting the Controls menu option.
alternately, if you see the word 'Controls' on what looks like the control panel at the top of the screen but the panel itself is not visible it is because its been reduced in size, if that's the case click on the word 'Controls' and it will resize to its full size then click the 'image' button and use the Easel-File-Dialog to select the image you want and press 'ok'.
hope that helps,
Christ
my code is perfect until i don't find a bug...

AnswerRe: location of call to picture Pin
Christ Kennedy23-Mar-20 14:20
Christ Kennedy23-Mar-20 14:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.