Morph 104 - Drawing the polygons

This section shows how we can draw a crudly textured polygon like I did in 1991.

We are going to draw each polygon using a series of lines going down the polygon like so







How many lines are we going to draw and how long are they?

We can start to think about the start of the vertical line (x,y) by using Linear Interpolation again







How do we increment from sx1 to sx2 to obtain (t)? Well we can do this by taking the difference between the 2 points.  length=(sx2-sx1), t = i/length,  when 0<i<length


This would also work for the bottom line (sx3 to sx4), but only if the bottom lines difference between sx3 and sx4 was the same or less.
If it was greater then we would get stripes like this. Not that some of the pixels are blank and not processed, creating stripes.







So horizontal length has to be the max value of (sx2-sx1) and (sx4-sx3). Like I said before, this just means that we are now repeating calculations on the top line. But I'm not worried at the mo.

  ' first point of line
  lx1 = LI(sx1,sx2,x/hlength)
  ly1 = LI(sy1,sy2,x/hlength)

  ' second point of line
  lx2 = LI(sx3,sx4,x/hlength)
  ly2 = LI(sy3,sy4,x/hlength)

Now that we have the start (x,y) and finish (x,y) of a vertical line, we can now traverse that using Linear Interpolation again.

We would get the same striping if we didnt have enough steps in the line. Again we take the max value for the vertical length as the max value of (y3-y1) and (y4-y2)

Once we have that, we can traverse the polygon

' we use Abs() to get the length in case a negative number is produced
hlength = Max(Abs(sx2-sx1),Abs(sx4-sx3))
vlength = Max(Abs(sy3-sy1),Abs(sy4-sy2))
x=0
while x<hlength
  ' first point of line
  lx1 = LI(sx1,sx2,x/hlength)
  ly1 = LI(sy1,sy2,x/hlength)

  ' second point of line
  lx2 = LI(sx3,sx4,x/hlength)
  ly2 = LI(sy3,sy4,x/hlength)

  y=0
  while y<vlength
    fx = LI(lx1,lx2,y/vlength)
    fy = LI(ly1,ly2,y/vlength)

    WritePixel fx,fy,$fff
    y=y+1

  x=x+1

This is not very optimised as the same pixel could get written multiple times

Now that we have the basics of drawing the polygon, we are going to utilise it 3 times in our drawing loop..
1) Get the colour of the source pixel in the source polygon
2) Get the colour of the destination pixel in the destination polygon
3) Write a mix of the 2 pixels to the new polygon position






Previously we found the max length of the sides of the same polygon. In this example we are going to need to find the max of the lengths of the source polygon and destination polygon so that we avoid striping as the shape changes.

By adding source and destination interpolation, the code now looks something like this...
(we are not writing the new pixel yet)

' we use Abs() to get the length incase a negative number is produced
' find max length on source and destination
hlength = Max(Max(Abs(sx2-sx1),Abs(sx4-sx3)),Max(Abs(dx2-dx1),Abs(dx4-dx3)))
vlength = Max(Max(Abs(sy3-sy1),Abs(sy4-sy2)),Max(Abs(dy3-dy1),Abs(dy4-dy2)))
x=0
while x<hlength
  ' first point of source line
  slx1 = LI(sx1,sx2,x/hlength)
  sly1 = LI(sy1,sy2,x/hlength)

  ' second point of source line
  slx2 = LI(sx3,sx4,x/hlength)
  sly2 = LI(sy3,sy4,x/hlength)

  ' first point of destination line
  dlx1 = LI(dx1,dx2,x/hlength)
  dly1 = LI(dy1,dy2,x/hlength)

  ' second point of destination line
  dlx2 = LI(dx3,dx4,x/hlength)
  dly2 = LI(dy3,dy4,x/hlength)

  y=0
  while y<vlength
    sx = LI(slx1,slx2,y/vlength)
    sy = LI(sly1,sly2,y/vlength)
    source_col = source_img.ReadPixel(sx,sy)

    dx = LI(dlx1,dlx2,y/vlength)
    dy = LI(dly1,dly2,y/vlength)
    destination_col = destination_img.ReadPixel(dx,dy)
    y=y+1

  x=x+1

Now we can add the code to calculate the new polygon and writing the new pixel

' we use Abs() to get the length incase a negative number is produced
' find max length on source and destination
hlength = Max(Max(Abs(sx2-sx1),Abs(sx4-sx3)),Max(Abs(dx2-dx1),Abs(dx4-dx3)))
vlength = Max(Max(Abs(sy3-sy1),Abs(sy4-sy2)),Max(Abs(dy3-dy1),Abs(dy4-dy2)))


' work out a polygon step (t) between source and destination
Local x1:Float = LI(sx1,dx1,t)
Local y1:Float = LI(sy1,dy1,t) 
Local x2:Float = LI(sx2,dx2,t) 
Local y2:Float = LI(sy2,dy2,t) 
Local x3:Float = LI(sx3,dx3,t) 
Local y3:Float = LI(sy3,dy3,t) 
Local x4:Float = LI(sx4,dx4,t) 
Local y4:Float = LI(sy4,dy4,t)

x=0
while x<hlength
  ' first point of source line
  slx1 = LI(sx1,sx2,x/hlength)
  sly1 = LI(sy1,sy2,x/hlength)

  ' second point of source line
  slx2 = LI(sx3,sx4,x/hlength)
  sly2 = LI(sy3,sy4,x/hlength)

  ' first point of destination line
  dlx1 = LI(dx1,dx2,x/hlength)
  dly1 = LI(dy1,dy2,x/hlength)

  ' second point of destination line
  dlx2 = LI(dx3,dx4,x/hlength)
  dly2 = LI(dy3,dy4,x/hlength)

  ' first point of line in new polygon
  plx1 = LI(x1,x2,x/hlength)
  ply1 = LI(y1,y2,x/hlength)

  ' second point of line in new polygon
  plx2 = LI(x3,x4,x/hlength)
  ply2 = LI(y3,y4,x/hlength)

  y=0
  while y<vlength
    ' source pixel vertical line
    sx = LI(slx1,slx2,y/vlength)
    sy = LI(sly1,sly2,y/vlength)
    source_col = source_img.ReadPixel(sx,sy)


    ' destination pixel vertical line
    dx = LI(dlx1,dlx2,y/vlength)
    dy = LI(dly1,dly2,y/vlength)
    destination_col = destination_img.ReadPixel(dx,dy)

    ' new polygon vertical line
    px = LI(plx1,plx2,y/vlength)
    py = LI(plx2,ply2,y/vlength)

    WritePixel px,py,LI(source_col,destination_col,t)
    y=y+1

  x=x+1

A final CerberusX example can be found here. The sample data for our favorite marvel heroes can also be found here




Next Chapter - 105 - Lets optimise - https://devdevandmoredev.blogspot.com/2019/08/morph-105-optimisation.html

Links to all chapters
Part 1 https://devdevandmoredev.blogspot.com/2019/08/morph-101-intro-to-morphing.html
Part 2 https://devdevandmoredev.blogspot.com/2019/08/morph-102-colour-changing.html
Part 3 https://devdevandmoredev.blogspot.com/2019/08/morph-103-moving-pixels.html
Part 4 https://devdevandmoredev.blogspot.com/2019/08/morph-104-drawing-polygons.html
Part 5 https://devdevandmoredev.blogspot.com/2019/08/morph-105-optimisation.html
Part 6 https://devdevandmoredev.blogspot.com/2019/08/morph-106-final-thoughts.html

Comments