Click here to Skip to main content
Rate this: bad
Please Sign up or sign in to vote.
See more: C#4.0
Hi all,
I am currently stuck on a personal challenge project. To build a 3D engine in C# using only the GDI (to learn c# & 3d math to go with). I have currently built an engine that can have 3D objects added to it, with basic face drawing (Also has basic lighting using inverse square law Smile | :) ). I am stuck at drawing a texture to a given face/triangle.
How could I draw an Image to a parallelogram/triangle such that the corners of the original image match that of a parallelogram? Confused | :confused:
(Bare in mind that these are the 2D co-ordinates not the 3D ones they were calculated from)

Thank you all who help me solve this Smile | :) Smile | :)
example code situation
Image Texture;      //From engine source
Point[] DrawPoints; //4 points of parallelogram // 3 points of triangle (either)
Graphics Drawer;
//TODO - Draw Texture to map to the 3/4 points of draw points
Posted 19-Jan-11 6:23am
JOAT-MON at 19-Jan-11 16:26pm
Suggestion: I don't have an answer for you off-hand, I haven't morphed images in this manner, but have you looked at the capabilities of either the GraphicsPath class and/or Matrix class to accomplish this?
Thomas.D Williams at 19-Jan-11 16:48pm
I have looked, however it has not been that useful. I have only found it useful in retrieving a part of an image/texture (e.g a triangle shape) to draw but not actually drawing it 3D. I'm not aware that it can actually transform an image. I may have to research more into paths. Thank you for the suggestion :) :)
Rate this: bad
Please Sign up or sign in to vote.

Solution 1

This is going to be a long answer. I post the code, which I think is rather straightforward, but if you feel you need further explanations, I will post comments.
I guess you can accomplish this more easily (and faster) with advanced math, but I bet you'll get the main idea from the simple code below. I warn you that this code is very slow; try it with small images. Due to lack of time this code is not optimized at all, you can easily improve speed by changing a few lines, but I leave it to you Smile | :)
        protected override void OnPaint(PaintEventArgs e)
            if (Texture == null)
            Bitmap bmp = (Bitmap)Texture;
            int width = Texture.Width;
            int height = Texture.Height;
            using (Graphics g = this.CreateGraphics())
                Point[] Dwu = this.DivideEdge(DrawPoints[0], DrawPoints[1], width, false);
                Point[] Dwd = this.DivideEdge(DrawPoints[2], DrawPoints[3], width, true);
                Point[] Dhl = this.DivideEdge(DrawPoints[3], DrawPoints[0], height, false);
                Point[] Dhr = this.DivideEdge(DrawPoints[1], DrawPoints[2], height, true);
                for (int x = 0; x < width; x++)
                    for (int y = 0; y < height; y++)
                        Point a = GetIntersection(Dwu[x], Dwd[x], Dhl[y], Dhr[y]);
                        g.DrawRectangle(new Pen(bmp.GetPixel(x, y)), a.X, a.Y, 1, 1);
        Point[] DivideEdge(Point a, Point b, int points, bool reverse)
            Point[] d = new Point[points + 1];
            for (int i = 0; i <= points; i++)
                d[i] = new Point(a.X + (b.X - a.X) * i / points, a.Y + (b.Y - a.Y) * i / points);
            if (reverse)
                Point[] d2 = new Point[points + 1];
                for (int j = 0; j <= points; j++)
                    d2[points - j] = d[j];
                return d2;
                return d;
        public Point GetIntersection(Point p1, Point p2, Point p3, Point p4)
            int x1 = p1.X;int x2 = p2.X;int x3 = p3.X;int x4 = p4.X;
            int y1 = p1.Y;int y2 = p2.Y;int y3 = p3.Y;int y4 = p4.Y;
            float d = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
            if (d == 0f)
                return new Point(0, 0);
            float na = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3);
            float nb = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3);
            float ua = na / d;
            float ub = nb / d;
            return new Point((int)(x1 + ua * (x2 - x1)), (int)(y1 + ua * (y2 - y1)));
Hope this helps, good luck!
Thomas.D Williams at 20-Jan-11 2:52am
Thank you. I never thought of doing it like this. From what I can make of your code you re-draw every pixel from a texture to a different location you calculate in 'GetIntersection'. I have already seen I can speed it up in my Engines draw sequence, Mainly by using pre-defined graphics objects. I have found it rather interesting how slow 'CreateGraphics' is. I will be looking at it later when I get back from college. Thank you so much :) and thank you for the time you put in getting a solution :) :)
Rate this: bad
Please Sign up or sign in to vote.

Solution 2

I have found a solution to the problem.
I stumbled on this application somewhere on the web[^]
The source code in the example does exactly what I asked. I am now implementing a solution Smile | :) Smile | :) thank you to all those who have helped.

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

  Print Answers RSS
Your Filters
0 Sergey Alexandrovich Kryukov 367
1 Abhinav S 226
2 thatraja 220
3 OriginalGriff 195
4 Peter Leow 160
0 Sergey Alexandrovich Kryukov 8,849
1 OriginalGriff 5,035
2 Peter Leow 3,949
3 Maciej Los 3,535
4 Abhinav S 3,148

Advertise | Privacy | Mobile
Web02 | 2.8.140415.2 | Last Updated 20 Jan 2011
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Use
Layout: fixed | fluid