Drawing diagonal lines on an image

前端 未结 3 1176
轻奢々
轻奢々 2021-01-21 23:57

Hi im trying to draw diagonal lines across an image top right to bottom left here is my code so far.

  width = getWidth(picture)
  height = getHeight(picture)
           


        
3条回答
  •  Happy的楠姐
    2021-01-22 00:46

    I would like to add some math considerations to the discussion...

    (Just because it is sad that JES's addLine function draws black lines only and is quite limited...)

    Note : The following code uses the Bresenham's Line Algorithm pointed out by MartinStettner (so thanks to him).

    The Bresenham's line algorithm is an algorithm which determines which order to form a close approximation to a straight line between two given points. Since a pixel is an atomic entity, a line can only be drawn on a computer screen by using some kind of approximation.

    Note : To understand the following code, you will need to remember a little bit of your basic school math courses (line equation & trigonometry).

    Code :

    # The following is fast implementation and contains side effects...
    
    import random
    
    # Draw point, with check if the point is in the image area
    def drawPoint(pic, col, x, y):
       if (x >= 0) and (x < getWidth(pic)) and (y >= 0) and (y < getHeight(pic)):
         px = getPixel(pic, x, y)
         setColor(px, col)
    
    
    # Draw line segment, given two points
    # From Bresenham's line algorithm
    # http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
    def drawLine(pic, col, x0, y0, x1, y1):
    
       dx = abs(x1-x0)
       dy = abs(y1-y0) 
       sx = sy = 0
    
       #sx = 1 if x0 < x1 else -1
       #sy = 1 if y0 < y1 else -1
    
       if (x0 < x1): 
         sx = 1 
       else: 
         sx = -1
       if (y0 < y1):
         sy = 1 
       else: 
         sy = -1
    
       err = dx - dy
    
       while (True):
    
         drawPoint(pic, col, x0, y0)
    
         if (x0 == x1) and (y0 == y1): 
           break
    
         e2 = 2 * err
         if (e2 > -dy):
           err = err - dy
           x0 = x0 + sx
    
         if (x0 == x1) and (y0 == y1):
           drawPoint(pic, col, x0, y0)
           break
    
         if (e2 <  dx):
           err = err + dx
           y0 = y0 + sy 
    
    
    # Draw infinite line from segment
    def drawInfiniteLine(pic, col, x0, y0, x1, y1):
       # y = m * x + b
       m = (y0-y1) / (x0-x1)
       # y0 = m * x0 + b   =>   b = y0 - m * x0
       b = y0 - m * x0
    
       x0 = 0
       y0 = int(m*x0 + b)
       # get a 2nd point far away from the 1st one
       x1 = getWidth(pic) 
       y1 = int(m*x1 + b)
    
       drawLine(pic, col, x0, y0, x1, y1)
    
    
    # Draw infinite line from origin point and angle
    # Angle 'theta' expressed in degres
    def drawInfiniteLineA(pic, col, x, y, theta):
    
       # y = m * x + b
       dx = y * tan(theta * pi / 180.0)  # (need radians)
       dy = y
    
       if (dx == 0):
         dx += 0.000000001 # Avoid to divide by zero 
    
       m = dy / dx
    
       # y = m * x + b   =>   b = y - m * x
       b = y - m * x
    
       # get a 2nd point far away from the 1st one
       x1 = 2 * getWidth(pic)
       y1 = m*x1 + b
    
       drawInfiniteLine(pic, col, x, y, x1, y1)
    
    
    # Draw multiple parallele lines, given offset and angle
    def multiLines(pic, col, offset, theta, randOffset = 0):
       # Range is [-2*width, 2*width] to cover the whole surface
       for i in xrange(-2*getWidth(pic), 2*getWidth(pic), offset):
          drawInfiniteLineA(pic, col, i + random.randint(0, randOffset), 1, theta)
    
    # Draw multiple lines, given offset, angle and angle offset
    def multiLinesA(pic, col, offsetX, offsetY, theta, offsetA):
       j = 0
       # Range is [-2*width, 2*width] to cover the whole surface
       for i in xrange(-2*getWidth(pic), 2*getWidth(pic), offsetX):
          drawInfiniteLineA(pic, col, i, j, theta)
          j += offsetY
          theta += offsetA
    
    
    
    file = pickAFile()
    picture = makePicture(file)
    color = makeColor(0, 65, 65) #pickAColor()
    #drawline(picture, color, 10, 10, 100, 100)
    #drawInfiniteLine(picture, color, 10, 10, 100, 100)
    #drawInfiniteLineA(picture, color, 50, 50, 135.0)
    #multiLines(picture, color, 20, 56.0)
    #multiLines(picture, color, 10, 56.0, 15)
    multiLinesA(picture, color, 10, 2, 1.0, 1.7) 
    
    show(picture)
    


    Output (Painting by Pierre Soulages) :


    enter image description here

    enter image description here

    enter image description here


    Hope this gave some fun and ideas to JES students... And to others as well...

提交回复
热议问题