Author Topic: Space Filling with Polygons  (Read 7794 times)

0 Members and 1 Guest are viewing this topic.

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Space Filling with Polygons
« on: April 28, 2020, 07:42:44 am »
Hey everyone!

This program fills the space with a polygon (triangles, squares, etc) in such a way that any two polygon must not overlap/collide.
The polygon size gradually reduces and it try to fill as much space as possible.
The color of polygon also changes gradually, resulting in a beautiful pattern. :)

I took some help for concepts behind this from here - http://paulbourke.net/fractals/randomtile/

Run the program & Enjoy.

Instruction :  Enter the number of sides of the polygon you want to fill with (of course, it must greater than 2). Higher values will result
in slow speed. :)

Code: QB64: [Select]
  1. 'Space Filling with Polygon
  2. 'By Ashish
  3.  
  4. TYPE XY
  5.     x AS SINGLE
  6.     y AS SINGLE
  7.  
  8. _TITLE "Space Filling with Polygon"
  9. SCREEN _NEWIMAGE(800, 600, 32)
  10.  
  11. INPUT "Enter the number of side for a polygon (must be greater than 2) : ", x%
  12. IF x% < 3 THEN PRINT "It must be greate than 2!, taking default value of 3. Hit ENTER.": SLEEP: x% = 3
  13. polySides = x%
  14. DIM tempPoly1(polySides - 1) AS XY, tempPoly2(polySides - 1) AS XY
  15. REDIM polys(polySides - 1) AS XY
  16.  
  17.  
  18. init = 0
  19. poly_index = 0
  20. i = 1
  21. c = 1.1
  22. failed = 0
  23.     IF init = 0 THEN
  24.         r = p5random(150, 200)
  25.         ox = p5random(r, _WIDTH - r)
  26.         oy = p5random(r, _HEIGHT - r)
  27.         offAng = p5random(-_PI, _PI)
  28.         FOR j = 0 TO polySides - 1
  29.             polys(j).x = ox + COS(j * (_PI(2 / polySides)) + offAng) * r
  30.             polys(j).y = oy + SIN(j * (_PI(2 / polySides)) + offAng) * r
  31.         NEXT
  32.         clr~& = midColor(_RGB(255, 255, 0), _RGB(255, 100, 0), map(r, 200, 3, 0, 1))
  33.         drawPoly polys(), clr~&
  34.         init = 1
  35.         poly_index = poly_index + polySides
  36.     ELSE
  37.         r = 200 / (c ^ i)
  38.         ox = p5random(r, _WIDTH - r)
  39.         oy = p5random(r, _HEIGHT - r)
  40.         collided = 0
  41.         offAng = p5random(-_PI, _PI)
  42.         FOR j = 0 TO polySides - 1
  43.             tempPoly1(j).x = ox + COS(j * (_PI(2 / polySides)) + offAng) * r
  44.             tempPoly1(j).y = oy + SIN(j * (_PI(2 / polySides)) + offAng) * r
  45.         NEXT
  46.         FOR j = 0 TO UBOUND(polys) STEP polySides
  47.             FOR k = j TO j + polySides - 1
  48.                 tempPoly2(k - j) = polys(k)
  49.             NEXT
  50.             IF polyCollide(tempPoly1(), tempPoly2()) THEN collided = -1: EXIT FOR
  51.         NEXT
  52.         IF NOT collided THEN
  53.             ' _echo "yes"
  54.             REDIM _PRESERVE polys(UBOUND(polys) + polySides) AS XY
  55.             FOR j = poly_index TO poly_index + polySides - 1
  56.                 polys(j) = tempPoly1(j - poly_index)
  57.             NEXT
  58.             clr~& = midColor(_RGB(255, 255, 0), _RGB(255, 100, 0), map(r, 200, 3, 0, 1))
  59.             drawPoly tempPoly1(), clr~&
  60.             poly_index = poly_index + polySides
  61.         ELSE
  62.             failed = failed + 1
  63.             IF failed > (i * 60) THEN i = i + 1: failed = 0
  64.         END IF
  65.     END IF
  66. LOOP UNTIL r < 3
  67.  
  68. FUNCTION midColor~& (clr1 AS _UNSIGNED LONG, clr2 AS _UNSIGNED LONG, v)
  69.     midColor~& = _RGB(map(v, 0, 1, _RED(clr1), _RED(clr2)), map(v, 0, 1, _GREEN(clr1), _GREEN(clr2)), map(v, 0, 1, _BLUE(clr1), _BLUE(clr2)))
  70.  
  71. SUB drawPoly (vert() AS XY, clr AS _UNSIGNED LONG)
  72.     n = UBOUND(vert)
  73.     DIM cx, cy
  74.     FOR i = 0 TO n
  75.         LINE (vert(i).x, vert(i).y)-(vert((i + 1) MOD (n + 1)).x, vert((i + 1) MOD (n + 1)).y), clr
  76.         cx = cx + vert(i).x: cy = cy + vert(i).y
  77.     NEXT
  78.     cx = cx / (n + 1): cy = cy / (n + 1)
  79.     PAINT (cx, cy), clr, clr
  80.  
  81.  
  82. FUNCTION polyCollide (vert1() AS XY, vert2() AS XY)
  83.     DIM n1 AS INTEGER, n2 AS INTEGER
  84.     n1 = UBOUND(vert1): n2 = UBOUND(vert2)
  85.     'checking if any point of polygon 1 inside polygon 2
  86.     FOR i = 0 TO n1
  87.         IF pointInsidePoly(vert1(i), vert2()) THEN polyCollide = -1: EXIT FUNCTION
  88.     NEXT
  89.     'checking if any point of polygon 2 inside polygon 1
  90.     FOR i = 0 TO n2
  91.         IF pointInsidePoly(vert2(i), vert1()) THEN polyCollide = -1: EXIT FUNCTION
  92.     NEXT
  93.     ' checking the edge intersection
  94.     FOR i = 0 TO n1
  95.         FOR j = 0 TO n2
  96.             IF lineIntersect(vert1(i).x, vert1(i).y, vert1((i + 1) MOD (n1 + 1)).x, vert1((i + 1) MOD (n1 + 1)).y, vert2(j).x, vert2(j).y, vert2((j + 1) MOD (n2 + 1)).x, vert2((j + 1) MOD (n2 + 1)).y) THEN polyCollide = -1: EXIT FUNCTION
  97.         NEXT
  98.     NEXT
  99.  
  100. 'from paulbourke.net
  101. FUNCTION pointInsidePoly (p AS XY, polyVert() AS XY)
  102.     DIM ax1, ax2, ay1, ay2
  103.     n = UBOUND(polyVert)
  104.     FOR i = 0 TO n
  105.         ax1 = polyVert(i).x - p.x
  106.         ay1 = polyVert(i).y - p.y
  107.         ax2 = polyVert((i + 1) MOD (n + 1)).x - p.x
  108.         ay2 = polyVert((i + 1) MOD (n + 1)).y - p.y
  109.         ang = ang + angle2D(ax1, ay1, ax2, ay2)
  110.     NEXT
  111.     pointInsidePoly = (ABS(ang) >= _PI)
  112.  
  113. 'from paulbourke.net
  114. FUNCTION angle2D (x1, y1, x2, y2)
  115.     DIM theta1, theta2, ftheta
  116.     theta1 = _ATAN2(y1, x1)
  117.     theta2 = _ATAN2(y2, x2)
  118.     ftheta = theta1 - theta2
  119.     WHILE ftheta > _PI: ftheta = ftheta - _PI(2): WEND
  120.     WHILE ftheta < -_PI: ftheta = ftheta + _PI(2): WEND
  121.     angle2D = ftheta
  122.  
  123. FUNCTION lineIntersect (__x1, __y1, __x2, __y2, __x3, __y3, __x4, __y4)
  124.     DIM x1 AS INTEGER, y1 AS INTEGER, x2 AS INTEGER, y2 AS INTEGER, x3 AS INTEGER, y3 AS INTEGER, x4 AS INTEGER, y4 AS INTEGER
  125.     DIM a1, b1, c1, a2, b2, c2
  126.     DIM a1b2_minus_a2b1, b1c2_minus_b2c1, a2c1_minus_a1c2
  127.     DIM inter_x AS INTEGER, inter_y AS INTEGER
  128.  
  129.     x1 = __x1: x2 = __x2: x3 = __x3: x4 = __x4
  130.     y1 = __y1: y2 = __y2: y3 = __y3: y4 = __y4
  131.    
  132.     IF x1 > x2 THEN SWAP x1, x2
  133.     IF x3 > x4 THEN SWAP x3, x4
  134.     IF y1 > y2 THEN SWAP y1, y2
  135.     IF y3 > y4 THEN SWAP y3, y4
  136.    
  137.     a1 = __y2 - __y1: b1 = -(__x2 - __x1): c1 = (__x2 * __y1) - (__x1 * __y2)
  138.     a2 = __y4 - __y3: b2 = -(__x4 - __x3): c2 = (__x4 * __y3) - (__x3 * __y4)
  139.  
  140.     'check if lines are perfectly vertical or horizontal
  141.     IF a1 = 0 AND a2 = 0 THEN lineIntersect = (__y1 = __y3): _DEST 0: EXIT FUNCTION
  142.     IF b1 = 0 AND b2 = 0 THEN lineIntersect = (__x1 = __x3): _DEST 0: EXIT FUNCTION
  143.     IF a2 = 0 OR b2 = 0 THEN GOTO skip_component_ratio
  144.    
  145.     'check if the whole line segments coincide with each other.
  146.     IF c2 <> 0 THEN
  147.         IF (a1 / a2) = (b1 / b2) AND (b1 / b2) = (c1 / c2) THEN
  148.             lineIntersect = -1: EXIT FUNCTION
  149.         END IF
  150.     END IF
  151.     skip_component_ratio:
  152.     'check if the line segments have same slope.
  153.     IF a1 * b2 = a2 * b1 THEN
  154.         lineIntersect = (c1 = c2) 'special case, when they still coincide (as c1=c2)
  155.         EXIT FUNCTION
  156.     END IF
  157.     'check if the line do intersect between the segments.
  158.     a1b2_minus_a2b1 = (a1 * b2) - (a2 * b1): b1c2_minus_b2c1 = (b1 * c2) - (b2 * c1): a2c1_minus_a1c2 = (a2 * c1) - (a1 * c2)
  159.     inter_x = b1c2_minus_b2c1 / a1b2_minus_a2b1: inter_y = a2c1_minus_a1c2 / a1b2_minus_a2b1
  160.    
  161.     lineIntersect = ((inter_x >= x1 AND inter_x <= x2 AND inter_y >= y1 AND inter_y <= y2)) and ((inter_x >= x3 AND inter_x <= x4 AND inter_y >= y3 AND inter_y <= y4))
  162.  
  163. 'taken from p5js.bas
  164. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  165.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  166.  
  167. FUNCTION p5random! (mn!, mx!)
  168.     IF mn! > mx! THEN
  169.         SWAP mn!, mx!
  170.     END IF
  171.     p5random! = RND * (mx! - mn!) + mn!
  172.  


Screenshot_1.png

Program output for the input value of 3, i.e. for a triangle.
« Last Edit: April 28, 2020, 07:47:20 am by Ashish »
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: Space Filling with Polygons
« Reply #1 on: April 28, 2020, 09:11:42 am »
Nice one, Ashish!

- Dav

FellippeHeitor

  • Guest
Re: Space Filling with Polygons
« Reply #2 on: April 28, 2020, 09:18:35 am »
Doritos!

Offline TerryRitchie

  • Seasoned Forum Regular
  • Posts: 495
  • Semper Fidelis
    • View Profile
Re: Space Filling with Polygons
« Reply #3 on: April 28, 2020, 11:19:32 am »
Nacho cheese, please.
In order to understand recursion, one must first understand recursion.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Space Filling with Polygons
« Reply #4 on: April 28, 2020, 12:22:06 pm »
Nice one!

I remember doing circle fills with images awhile back. That was a Coding Challenge or Coding Train session with that crazy YouTube guy, Daniel Shiffman.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Space Filling with Polygons
« Reply #5 on: April 28, 2020, 07:33:03 pm »
Hi Ashish
what fine colors in this geometric application!
Cool!
spaceFillingwithPoligons.jpg
Programming isn't difficult, only it's  consuming time and coffee

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Space Filling with Polygons
« Reply #6 on: April 28, 2020, 11:24:04 pm »
@Dav @FellippeHeitor  @TerryRitchie @bplus @TempodiBasic
Thank you for trying this!

Ok, here is a new MOD. Now, it draws the polygon with shaded effect. To get variation, you can change value of polygonSides.

Code: QB64: [Select]
  1. 'Space Filling with Polygon
  2. 'By Ashish
  3.  
  4. TYPE gl_vertex_type
  5.     'position of vertex
  6.     x AS SINGLE
  7.     y AS SINGLE
  8.     'center
  9.     cx AS SINGLE
  10.     cy AS SINGLE
  11.     'color of the vertex to be used
  12.     r AS SINGLE
  13.     g AS SINGLE
  14.     b AS SINGLE
  15.  
  16. _TITLE "Space Filling with Polygon [MOD:SHADED SHAPE]"
  17. SCREEN _NEWIMAGE(800, 600, 32)
  18.  
  19. DIM SHARED init, polySides
  20. 'warning : polySides must always be greater than 2
  21. polySides = 3 'change its value to get different polygons
  22. DIM tempPoly1(polySides - 1) AS gl_vertex_type, tempPoly2(polySides - 1) AS gl_vertex_type
  23. REDIM SHARED polys(polySides - 1) AS gl_vertex_type
  24.  
  25.  
  26. init = 0
  27. poly_index = 0
  28. i = 1
  29. c = 1.05
  30. failed = 0
  31.     IF init = 0 THEN
  32.         r = p5random(150, 200)
  33.         ox = p5random(r, _WIDTH - r)
  34.         oy = p5random(r, _HEIGHT - r)
  35.         offAng = p5random(-_PI, _PI)
  36.         clr~& = midColor(_RGB(255, 255, 0), _RGB(255, 100, 0), map(r, 200, 3, 0, 1))
  37.         red = map(_RED(clr~&), 0, 255, 0, 1): green = map(_GREEN(clr~&), 0, 255, 0, 1): blue = map(_BLUE(clr~&), 0, 255, 0, 1)
  38.         FOR j = 0 TO polySides - 1
  39.             polys(j).x = ox + COS(j * (_PI(2 / polySides)) + offAng) * r
  40.             polys(j).y = oy + SIN(j * (_PI(2 / polySides)) + offAng) * r
  41.             polys(j).cx = ox: polys(j).cy = oy
  42.             polys(j).r = red: polys(j).g = green: polys(j).b = blue
  43.         NEXT
  44.         init = -1
  45.         poly_index = poly_index + polySides
  46.     ELSE
  47.         r = 200 / (c ^ i)
  48.         ox = p5random(r, _WIDTH - r)
  49.         oy = p5random(r, _HEIGHT - r)
  50.         collided = 0
  51.         offAng = p5random(-_PI, _PI)
  52.         FOR j = 0 TO polySides - 1
  53.             tempPoly1(j).x = ox + COS(j * (_PI(2 / polySides)) + offAng) * r
  54.             tempPoly1(j).y = oy + SIN(j * (_PI(2 / polySides)) + offAng) * r
  55.         NEXT
  56.         FOR j = 0 TO UBOUND(polys) STEP polySides
  57.             FOR k = j TO j + polySides - 1
  58.                 tempPoly2(k - j) = polys(k)
  59.             NEXT
  60.             IF polyCollide(tempPoly1(), tempPoly2()) THEN collided = -1: EXIT FOR
  61.         NEXT
  62.         IF NOT collided THEN
  63.             REDIM _PRESERVE polys(UBOUND(polys) + polySides) AS gl_vertex_type
  64.             clr~& = midColor(_RGB(255, 255, 0), _RGB(255, 100, 0), map(r, 200, 3, 0, 1))
  65.             red = map(_RED(clr~&), 0, 255, 0, 1): green = map(_GREEN(clr~&), 0, 255, 0, 1): blue = map(_BLUE(clr~&), 0, 255, 0, 1)
  66.             FOR j = poly_index TO poly_index + polySides - 1
  67.                 polys(j) = tempPoly1(j - poly_index)
  68.                 polys(j).cx = ox: polys(j).cy = oy
  69.                 polys(j).r = red: polys(j).g = green: polys(j).b = blue
  70.             NEXT
  71.             poly_index = poly_index + polySides
  72.         ELSE
  73.             failed = failed + 1
  74.             IF failed > (i * 60) THEN i = i + 1: failed = 0
  75.         END IF
  76.     END IF
  77. LOOP UNTIL r < 3
  78.  
  79.  
  80. SUB _GL ()
  81.     IF NOT init THEN EXIT SUB
  82.     _glMatrixMode _GL_MODELVIEW
  83.  
  84.     'set the gl screen so that it can work normal screen coordinates
  85.     _glTranslatef -1, 1, 0
  86.     _glScalef 1 / 400, -1 / 300, 1
  87.      
  88.     'to get shaded effect, we will divide polygon into smaller triangles from center of polygon in a cyclic way.
  89.     FOR n = 0 TO UBOUND(polys) STEP polySides
  90.         _glPushMatrix
  91.         _glTranslatef polys(n).cx, polys(n).cy, 0
  92.         _glBegin _GL_TRIANGLES
  93.         FOR j = n TO n + polySides - 1
  94.             _glColor3f 0, 0, 0
  95.             _glVertex2i 0, 0
  96.             _glColor3f polys(n).r, polys(n).g, polys(n).b
  97.             _glVertex2i polys(j).x - polys(n).cx, polys(j).y - polys(j).cy
  98.             IF (j + 1) MOD (n + polySides) = 0 THEN _glVertex2i polys(n).x - polys(n).cx, polys(n).y - polys(j).cy ELSE _glVertex2i polys(j + 1).x - polys(n).cx, polys(j + 1).y - polys(j).cy
  99.         NEXT
  100.         _glEnd
  101.         _glPopMatrix
  102.     NEXT
  103.  
  104. FUNCTION midColor~& (clr1 AS _UNSIGNED LONG, clr2 AS _UNSIGNED LONG, v)
  105.     midColor~& = _RGB(map(v, 0, 1, _RED(clr1), _RED(clr2)), map(v, 0, 1, _GREEN(clr1), _GREEN(clr2)), map(v, 0, 1, _BLUE(clr1), _BLUE(clr2)))
  106.  
  107. FUNCTION polyCollide (vert1() AS gl_vertex_type, vert2() AS gl_vertex_type)
  108.     DIM n1 AS INTEGER, n2 AS INTEGER
  109.     n1 = UBOUND(vert1): n2 = UBOUND(vert2)
  110.     'checking if any point of polygon 1 inside polygon 2
  111.     FOR i = 0 TO n1
  112.         IF pointInsidePoly(vert1(i), vert2()) THEN polyCollide = -1: EXIT FUNCTION
  113.     NEXT
  114.     'checking if any point of polygon 2 inside polygon 1
  115.     FOR i = 0 TO n2
  116.         IF pointInsidePoly(vert2(i), vert1()) THEN polyCollide = -1: EXIT FUNCTION
  117.     NEXT
  118.     ' checking the edge intersection
  119.     FOR i = 0 TO n1
  120.         FOR j = 0 TO n2
  121.             IF lineIntersect(vert1(i).x, vert1(i).y, vert1((i + 1) MOD (n1 + 1)).x, vert1((i + 1) MOD (n1 + 1)).y, vert2(j).x, vert2(j).y, vert2((j + 1) MOD (n2 + 1)).x, vert2((j + 1) MOD (n2 + 1)).y) THEN polyCollide = -1: EXIT FUNCTION
  122.         NEXT
  123.     NEXT
  124.  
  125. 'from paulbourke.net
  126. FUNCTION pointInsidePoly (p AS gl_vertex_type, polyVert() AS gl_vertex_type)
  127.     DIM ax1, ax2, ay1, ay2
  128.     n = UBOUND(polyVert)
  129.     FOR i = 0 TO n
  130.         ax1 = polyVert(i).x - p.x
  131.         ay1 = polyVert(i).y - p.y
  132.         ax2 = polyVert((i + 1) MOD (n + 1)).x - p.x
  133.         ay2 = polyVert((i + 1) MOD (n + 1)).y - p.y
  134.         ang = ang + angle2D(ax1, ay1, ax2, ay2)
  135.     NEXT
  136.     pointInsidePoly = (ABS(ang) >= _PI)
  137.  
  138. 'from paulbourke.net
  139. FUNCTION angle2D (x1, y1, x2, y2)
  140.     DIM theta1, theta2, ftheta
  141.     theta1 = _ATAN2(y1, x1)
  142.     theta2 = _ATAN2(y2, x2)
  143.     ftheta = theta1 - theta2
  144.     WHILE ftheta > _PI: ftheta = ftheta - _PI(2): WEND
  145.     WHILE ftheta < -_PI: ftheta = ftheta + _PI(2): WEND
  146.     angle2D = ftheta
  147.  
  148. FUNCTION lineIntersect (__x1, __y1, __x2, __y2, __x3, __y3, __x4, __y4)
  149.     DIM x1 AS INTEGER, y1 AS INTEGER, x2 AS INTEGER, y2 AS INTEGER, x3 AS INTEGER, y3 AS INTEGER, x4 AS INTEGER, y4 AS INTEGER
  150.     DIM a1, b1, c1, a2, b2, c2
  151.     DIM a1b2_minus_a2b1, b1c2_minus_b2c1, a2c1_minus_a1c2
  152.     DIM inter_x AS INTEGER, inter_y AS INTEGER
  153.  
  154.     x1 = __x1: x2 = __x2: x3 = __x3: x4 = __x4
  155.     y1 = __y1: y2 = __y2: y3 = __y3: y4 = __y4
  156.    
  157.     IF x1 > x2 THEN SWAP x1, x2
  158.     IF x3 > x4 THEN SWAP x3, x4
  159.     IF y1 > y2 THEN SWAP y1, y2
  160.     IF y3 > y4 THEN SWAP y3, y4
  161.    
  162.     a1 = __y2 - __y1: b1 = -(__x2 - __x1): c1 = (__x2 * __y1) - (__x1 * __y2)
  163.     a2 = __y4 - __y3: b2 = -(__x4 - __x3): c2 = (__x4 * __y3) - (__x3 * __y4)
  164.  
  165.     'check if lines are perfectly vertical or horizontal
  166.     IF a1 = 0 AND a2 = 0 THEN lineIntersect = (__y1 = __y3): _DEST 0: EXIT FUNCTION
  167.     IF b1 = 0 AND b2 = 0 THEN lineIntersect = (__x1 = __x3): _DEST 0: EXIT FUNCTION
  168.     IF a2 = 0 OR b2 = 0 THEN GOTO skip_component_ratio
  169.    
  170.     'check if the whole line segments coincide with each other.
  171.     IF c2 <> 0 THEN
  172.         IF (a1 / a2) = (b1 / b2) AND (b1 / b2) = (c1 / c2) THEN
  173.             lineIntersect = -1: EXIT FUNCTION
  174.         END IF
  175.     END IF
  176.     skip_component_ratio:
  177.     'check if the line segments have same slope.
  178.     IF a1 * b2 = a2 * b1 THEN
  179.         lineIntersect = (c1 = c2) 'special case, when they still coincide (as c1=c2)
  180.         EXIT FUNCTION
  181.     END IF
  182.     'check if the line do intersect between the segments.
  183.     a1b2_minus_a2b1 = (a1 * b2) - (a2 * b1): b1c2_minus_b2c1 = (b1 * c2) - (b2 * c1): a2c1_minus_a1c2 = (a2 * c1) - (a1 * c2)
  184.     inter_x = b1c2_minus_b2c1 / a1b2_minus_a2b1: inter_y = a2c1_minus_a1c2 / a1b2_minus_a2b1
  185.    
  186.     lineIntersect = ((inter_x >= x1 AND inter_x <= x2 AND inter_y >= y1 AND inter_y <= y2)) AND ((inter_x >= x3 AND inter_x <= x4 AND inter_y >= y3 AND inter_y <= y4))
  187.  
  188. 'taken from p5js.bas
  189. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  190.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  191.  
  192. FUNCTION p5random! (mn!, mx!)
  193.     IF mn! > mx! THEN
  194.         SWAP mn!, mx!
  195.     END IF
  196.     p5random! = RND * (mx! - mn!) + mn!
  197.  


Screenshot_1.png

if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Space Filling with Polygons
« Reply #7 on: April 29, 2020, 11:43:03 am »
Cool!

@Ashish, if you try squares maybe you could put images in them? Wouldn't that make things interesting?

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Space Filling with Polygons
« Reply #8 on: April 29, 2020, 04:48:29 pm »
Doritos!

@Fell: Speak English!

@ Ashish: Yep, it's all that, and a bag of chips, but I tried the latest code, and all I got was the bag of chips.. all shaded triangles, not shaded pentagons. What? Edit: Oh, I see, I found the place you mentioned to change the number of sides. Cool!

Pete
« Last Edit: April 29, 2020, 04:50:06 pm by Pete »
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Space Filling with Polygons
« Reply #9 on: April 29, 2020, 08:50:54 pm »
Hey a little mod :)
Code: QB64: [Select]
  1. 'Space Filling with Polygon
  2. 'By Ashish
  3. 'b+ copy and mod 2020-04-29   https://www.qb64.org/forum/index.php?topic=2515.msg117572#msg117572
  4. TYPE XY
  5.     x AS SINGLE
  6.     y AS SINGLE
  7.  
  8. _TITLE "Space Filling with Polygon"
  9. SCREEN _NEWIMAGE(800, 600, 32)
  10. _DELAY .25
  11. 'INPUT "Enter the number of side for a polygon (must be greater than 2) : ", x%
  12. 'IF x% < 3 THEN PRINT "It must be greate than 2!, taking default value of 3. Hit ENTER.": SLEEP: x% = 3
  13.  
  14.  
  15. ' b+ loads an image and takes some measurements
  16. ih& = _LOADIMAGE("Templar.png")
  17. IF ih& = -1 THEN PRINT "Sorry image did not load.": SLEEP: END
  18. DIM SHARED wi, hi
  19. wi = _WIDTH(ih&): hi = _HEIGHT(ih&)
  20.  
  21. polySides = 4
  22. DIM tempPoly1(polySides - 1) AS XY, tempPoly2(polySides - 1) AS XY
  23. REDIM polys(polySides - 1) AS XY
  24.  
  25. init = 0
  26. poly_index = 0
  27. i = 1
  28. c = 1.1
  29. failed = 0
  30. FOR y = 0 TO 600
  31.     midInk 0, 0, 255, 255, 255, 0, y / 600
  32.     LINE (0, y)-(800, y)
  33.     IF init = 0 THEN
  34.         r = p5random(150, 200)
  35.         ox = p5random(r, _WIDTH - r)
  36.         oy = p5random(r, _HEIGHT - r)
  37.         offAng = p5random(-_PI, _PI)
  38.         FOR j = 0 TO polySides - 1
  39.             polys(j).x = ox + COS(j * (_PI(2 / polySides)) + offAng) * r
  40.             polys(j).y = oy + SIN(j * (_PI(2 / polySides)) + offAng) * r
  41.         NEXT
  42.         clr~& = midColor(_RGB(255, 255, 0), _RGB(255, 100, 0), map(r, 200, 3, 0, 1))
  43.         drawPoly polys(), clr~&
  44.         init = 1
  45.         poly_index = poly_index + polySides
  46.     ELSE
  47.         r = 200 / (c ^ i)
  48.         ox = p5random(r, _WIDTH - r)
  49.         oy = p5random(r, _HEIGHT - r)
  50.         collided = 0
  51.         offAng = p5random(-_PI, _PI)
  52.         FOR j = 0 TO polySides - 1
  53.             tempPoly1(j).x = ox + COS(j * (_PI(2 / polySides)) + offAng) * r
  54.             tempPoly1(j).y = oy + SIN(j * (_PI(2 / polySides)) + offAng) * r
  55.         NEXT
  56.         FOR j = 0 TO UBOUND(polys) STEP polySides
  57.             FOR k = j TO j + polySides - 1
  58.                 tempPoly2(k - j) = polys(k)
  59.             NEXT
  60.             IF polyCollide(tempPoly1(), tempPoly2()) THEN collided = -1: EXIT FOR
  61.         NEXT
  62.         IF NOT collided THEN
  63.             ' _echo "yes"
  64.             REDIM _PRESERVE polys(UBOUND(polys) + polySides) AS XY
  65.             FOR j = poly_index TO poly_index + polySides - 1
  66.                 polys(j) = tempPoly1(j - poly_index)
  67.             NEXT
  68.             clr~& = midColor(_RGB(255, 255, 0), _RGB(255, 100, 0), map(r, 200, 3, 0, 1))
  69.             drawPoly tempPoly1(), clr~&
  70.             poly_index = poly_index + polySides
  71.         ELSE
  72.             failed = failed + 1
  73.             IF failed > (i * 60) THEN i = i + 1: failed = 0
  74.         END IF
  75.     END IF
  76. LOOP UNTIL r < 1
  77.  
  78. FUNCTION midColor~& (clr1 AS _UNSIGNED LONG, clr2 AS _UNSIGNED LONG, v)
  79.     midColor~& = _RGB(map(v, 0, 1, _RED(clr1), _RED(clr2)), map(v, 0, 1, _GREEN(clr1), _GREEN(clr2)), map(v, 0, 1, _BLUE(clr1), _BLUE(clr2)))
  80.  
  81. SUB drawPoly (vert() AS XY, clr AS _UNSIGNED LONG)
  82.     'n = UBOUND(vert)
  83.     'DIM cx, cy
  84.     'FOR i = 0 TO n
  85.     '    LINE (vert(i).x, vert(i).y)-(vert((i + 1) MOD (n + 1)).x, vert((i + 1) MOD (n + 1)).y), clr
  86.     '    cx = cx + vert(i).x: cy = cy + vert(i).y
  87.     'NEXT
  88.     'cx = cx / (n + 1): cy = cy / (n + 1)
  89.     'PAINT (cx, cy), clr, clr
  90.  
  91.     cx = (vert(0).x + vert(2).x) / 2 'find the center, radius and tilt
  92.     cy = (vert(0).y + vert(2).y) / 2
  93.     r = SQR(2) * _HYPOT(cx - vert(0).x, cy - vert(0).y) 'mult bty SQR(2) locating sq top left corner from
  94.     a = _ATAN2(vert(0).y - cy, vert(0).x - cx) - _PI / 4 'subtract 45 degrees because square is off by that
  95.     RotoZoom3 cx, cy, ih&, r / wi, r / hi, a
  96.  
  97.  
  98. FUNCTION polyCollide (vert1() AS XY, vert2() AS XY)
  99.     DIM n1 AS INTEGER, n2 AS INTEGER
  100.     n1 = UBOUND(vert1): n2 = UBOUND(vert2)
  101.     'checking if any point of polygon 1 inside polygon 2
  102.     FOR i = 0 TO n1
  103.         IF pointInsidePoly(vert1(i), vert2()) THEN polyCollide = -1: EXIT FUNCTION
  104.     NEXT
  105.     'checking if any point of polygon 2 inside polygon 1
  106.     FOR i = 0 TO n2
  107.         IF pointInsidePoly(vert2(i), vert1()) THEN polyCollide = -1: EXIT FUNCTION
  108.     NEXT
  109.     ' checking the edge intersection
  110.     FOR i = 0 TO n1
  111.         FOR j = 0 TO n2
  112.             IF lineIntersect(vert1(i).x, vert1(i).y, vert1((i + 1) MOD (n1 + 1)).x, vert1((i + 1) MOD (n1 + 1)).y, vert2(j).x, vert2(j).y, vert2((j + 1) MOD (n2 + 1)).x, vert2((j + 1) MOD (n2 + 1)).y) THEN polyCollide = -1: EXIT FUNCTION
  113.         NEXT
  114.     NEXT
  115.  
  116. 'from paulbourke.net
  117. FUNCTION pointInsidePoly (p AS XY, polyVert() AS XY)
  118.     DIM ax1, ax2, ay1, ay2
  119.     n = UBOUND(polyVert)
  120.     FOR i = 0 TO n
  121.         ax1 = polyVert(i).x - p.x
  122.         ay1 = polyVert(i).y - p.y
  123.         ax2 = polyVert((i + 1) MOD (n + 1)).x - p.x
  124.         ay2 = polyVert((i + 1) MOD (n + 1)).y - p.y
  125.         ang = ang + angle2D(ax1, ay1, ax2, ay2)
  126.     NEXT
  127.     pointInsidePoly = (ABS(ang) >= _PI)
  128.  
  129. 'from paulbourke.net
  130. FUNCTION angle2D (x1, y1, x2, y2)
  131.     DIM theta1, theta2, ftheta
  132.     theta1 = _ATAN2(y1, x1)
  133.     theta2 = _ATAN2(y2, x2)
  134.     ftheta = theta1 - theta2
  135.     WHILE ftheta > _PI: ftheta = ftheta - _PI(2): WEND
  136.     WHILE ftheta < -_PI: ftheta = ftheta + _PI(2): WEND
  137.     angle2D = ftheta
  138.  
  139. FUNCTION lineIntersect (__x1, __y1, __x2, __y2, __x3, __y3, __x4, __y4)
  140.     DIM x1 AS INTEGER, y1 AS INTEGER, x2 AS INTEGER, y2 AS INTEGER, x3 AS INTEGER, y3 AS INTEGER, x4 AS INTEGER, y4 AS INTEGER
  141.     DIM a1, b1, c1, a2, b2, c2
  142.     DIM a1b2_minus_a2b1, b1c2_minus_b2c1, a2c1_minus_a1c2
  143.     DIM inter_x AS INTEGER, inter_y AS INTEGER
  144.  
  145.     x1 = __x1: x2 = __x2: x3 = __x3: x4 = __x4
  146.     y1 = __y1: y2 = __y2: y3 = __y3: y4 = __y4
  147.  
  148.     IF x1 > x2 THEN SWAP x1, x2
  149.     IF x3 > x4 THEN SWAP x3, x4
  150.     IF y1 > y2 THEN SWAP y1, y2
  151.     IF y3 > y4 THEN SWAP y3, y4
  152.  
  153.     a1 = __y2 - __y1: b1 = -(__x2 - __x1): c1 = (__x2 * __y1) - (__x1 * __y2)
  154.     a2 = __y4 - __y3: b2 = -(__x4 - __x3): c2 = (__x4 * __y3) - (__x3 * __y4)
  155.  
  156.     'check if lines are perfectly vertical or horizontal
  157.     IF a1 = 0 AND a2 = 0 THEN lineIntersect = (__y1 = __y3): _DEST 0: EXIT FUNCTION
  158.     IF b1 = 0 AND b2 = 0 THEN lineIntersect = (__x1 = __x3): _DEST 0: EXIT FUNCTION
  159.     IF a2 = 0 OR b2 = 0 THEN GOTO skip_component_ratio
  160.  
  161.     'check if the whole line segments coincide with each other.
  162.     IF c2 <> 0 THEN
  163.         IF (a1 / a2) = (b1 / b2) AND (b1 / b2) = (c1 / c2) THEN
  164.             lineIntersect = -1: EXIT FUNCTION
  165.         END IF
  166.     END IF
  167.     skip_component_ratio:
  168.     'check if the line segments have same slope.
  169.     IF a1 * b2 = a2 * b1 THEN
  170.         lineIntersect = (c1 = c2) 'special case, when they still coincide (as c1=c2)
  171.         EXIT FUNCTION
  172.     END IF
  173.     'check if the line do intersect between the segments.
  174.     a1b2_minus_a2b1 = (a1 * b2) - (a2 * b1): b1c2_minus_b2c1 = (b1 * c2) - (b2 * c1): a2c1_minus_a1c2 = (a2 * c1) - (a1 * c2)
  175.     inter_x = b1c2_minus_b2c1 / a1b2_minus_a2b1: inter_y = a2c1_minus_a1c2 / a1b2_minus_a2b1
  176.  
  177.     lineIntersect = ((inter_x >= x1 AND inter_x <= x2 AND inter_y >= y1 AND inter_y <= y2)) AND ((inter_x >= x3 AND inter_x <= x4 AND inter_y >= y3 AND inter_y <= y4))
  178.  
  179. 'taken from p5js.bas
  180. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  181.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  182.  
  183. FUNCTION p5random! (mn!, mx!)
  184.     IF mn! > mx! THEN
  185.         SWAP mn!, mx!
  186.     END IF
  187.     p5random! = RND * (mx! - mn!) + mn!
  188.  
  189. ' b+ added some helpers =====================================================================================
  190.  
  191. SUB RotoZoom3 (X AS LONG, Y AS LONG, Image AS LONG, xScale AS SINGLE, yScale AS SINGLE, radianRotation AS SINGLE) ' 0 at end means no scaling of x or y
  192.     DIM px(3) AS SINGLE: DIM py(3) AS SINGLE
  193.     DIM W&, H&, sinr!, cosr!, i&, x2&, y2&
  194.     W& = _WIDTH(Image&): H& = _HEIGHT(Image&)
  195.     px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
  196.     px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
  197.     sinr! = SIN(-radianRotation): cosr! = COS(-radianRotation)
  198.     FOR i& = 0 TO 3
  199.         x2& = xScale * (px(i&) * cosr! + sinr! * py(i&)) + X: y2& = yScale * (py(i&) * cosr! - px(i&) * sinr!) + Y
  200.         px(i&) = x2&: py(i&) = y2&
  201.     NEXT
  202.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  203.     _MAPTRIANGLE _SEAMLESS(0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  204.  
  205. SUB midInk (r1%, g1%, b1%, r2%, g2%, b2%, fr##)
  206.     COLOR _RGB32(r1% + (r2% - r1%) * fr##, g1% + (g2% - g1%) * fr##, b1% + (b2% - b1%) * fr##)
  207.  
  208.  

 
Space filling polys.PNG


and zip with bas, exe and png
* polygon fill.zip (Filesize: 781.35 KB, Downloads: 187)
« Last Edit: April 29, 2020, 10:03:32 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Space Filling with Polygons
« Reply #10 on: April 29, 2020, 09:55:32 pm »
Here I try swapping color with the image:

Code: QB64: [Select]
  1. 'Space Filling with Polygon
  2. 'By Ashish
  3. 'b+ copy and mod 2020-04-29   https://www.qb64.org/forum/index.php?topic=2515.msg117572#msg117572
  4. 'b+ mod 2 color changing
  5. TYPE XY
  6.     x AS SINGLE
  7.     y AS SINGLE
  8.  
  9. _TITLE "Space Filling with Polygon"
  10. SCREEN _NEWIMAGE(800, 600, 32)
  11. _DELAY .25
  12. 'INPUT "Enter the number of side for a polygon (must be greater than 2) : ", x%
  13. 'IF x% < 3 THEN PRINT "It must be greate than 2!, taking default value of 3. Hit ENTER.": SLEEP: x% = 3
  14.  
  15.  
  16. ' b+ loads an image and takes some measurements
  17. ih& = _LOADIMAGE("Templar.png")
  18. IF ih& = -1 THEN PRINT "Sorry image did not load.": SLEEP: END
  19. DIM SHARED wi, hi
  20. wi = _WIDTH(ih&): hi = _HEIGHT(ih&)
  21. DIM SHARED rStart, origClr AS _UNSIGNED LONG
  22. 'what is it's color
  23.  
  24. _PUTIMAGE , ih&, 0
  25. origClr = POINT(10, 300)
  26. PRINT origClr
  27. 'END
  28.  
  29.  
  30. polySides = 4
  31. DIM tempPoly1(polySides - 1) AS XY, tempPoly2(polySides - 1) AS XY
  32. REDIM polys(polySides - 1) AS XY
  33.  
  34. init = 0
  35. poly_index = 0
  36. i = 1
  37. c = 1.1
  38. failed = 0
  39. FOR y = 0 TO 600
  40.     LINE (0, y)-(800, y), midInk(0, 0, 255, 255, 255, 0, y / 600)
  41.     IF init = 0 THEN
  42.         r = p5random(150, 200)
  43.         rStart = r
  44.         ox = p5random(r, _WIDTH - r)
  45.         oy = p5random(r, _HEIGHT - r)
  46.         offAng = p5random(-_PI, _PI)
  47.         FOR j = 0 TO polySides - 1
  48.             polys(j).x = ox + COS(j * (_PI(2 / polySides)) + offAng) * r
  49.             polys(j).y = oy + SIN(j * (_PI(2 / polySides)) + offAng) * r
  50.         NEXT
  51.         'clr~& = midColor(_RGB(255, 255, 0), _RGB(255, 100, 0), map(r, 200, 3, 0, 1))
  52.         drawPoly polys(), midInk~&(0, 128, 0, 255, 0, 255, (rStart - r) / rStart)
  53.         init = 1
  54.         poly_index = poly_index + polySides
  55.     ELSE
  56.         r = 200 / (c ^ i)
  57.         ox = p5random(r, _WIDTH - r)
  58.         oy = p5random(r, _HEIGHT - r)
  59.         collided = 0
  60.         offAng = p5random(-_PI, _PI)
  61.         FOR j = 0 TO polySides - 1
  62.             tempPoly1(j).x = ox + COS(j * (_PI(2 / polySides)) + offAng) * r
  63.             tempPoly1(j).y = oy + SIN(j * (_PI(2 / polySides)) + offAng) * r
  64.         NEXT
  65.         FOR j = 0 TO UBOUND(polys) STEP polySides
  66.             FOR k = j TO j + polySides - 1
  67.                 tempPoly2(k - j) = polys(k)
  68.             NEXT
  69.             IF polyCollide(tempPoly1(), tempPoly2()) THEN collided = -1: EXIT FOR
  70.         NEXT
  71.         IF NOT collided THEN
  72.             ' _echo "yes"
  73.             REDIM _PRESERVE polys(UBOUND(polys) + polySides) AS XY
  74.             FOR j = poly_index TO poly_index + polySides - 1
  75.                 polys(j) = tempPoly1(j - poly_index)
  76.             NEXT
  77.             clr~& = midColor(_RGB(255, 255, 0), _RGB(255, 100, 0), map(r, 200, 3, 0, 1))
  78.             drawPoly tempPoly1(), midInk~&(0, 128, 0, 255, 0, 255, (rStart - r) / rStart)
  79.             poly_index = poly_index + polySides
  80.         ELSE
  81.             failed = failed + 1
  82.             IF failed > (i * 60) THEN i = i + 1: failed = 0
  83.         END IF
  84.     END IF
  85. LOOP UNTIL r < 4
  86.  
  87. FUNCTION midColor~& (clr1 AS _UNSIGNED LONG, clr2 AS _UNSIGNED LONG, v)
  88.     midColor~& = _RGB(map(v, 0, 1, _RED(clr1), _RED(clr2)), map(v, 0, 1, _GREEN(clr1), _GREEN(clr2)), map(v, 0, 1, _BLUE(clr1), _BLUE(clr2)))
  89.  
  90. SUB drawPoly (vert() AS XY, clr AS _UNSIGNED LONG)
  91.     'n = UBOUND(vert)
  92.     'DIM cx, cy
  93.     'FOR i = 0 TO n
  94.     '    LINE (vert(i).x, vert(i).y)-(vert((i + 1) MOD (n + 1)).x, vert((i + 1) MOD (n + 1)).y), clr
  95.     '    cx = cx + vert(i).x: cy = cy + vert(i).y
  96.     'NEXT
  97.     'cx = cx / (n + 1): cy = cy / (n + 1)
  98.     'PAINT (cx, cy), clr, clr
  99.  
  100.     cx = (vert(0).x + vert(2).x) / 2 'find the center, radius and tilt
  101.     cy = (vert(0).y + vert(2).y) / 2
  102.     r = SQR(2) * _HYPOT(cx - vert(0).x, cy - vert(0).y) 'mult bty SQR(2) locating sq top left corner from
  103.     a = _ATAN2(vert(0).y - cy, vert(0).x - cx) - _PI / 4 'subtract 45 degrees because square is off by that
  104.     new& = swapColor&(ih&, origClr, clr)
  105.     RotoZoom3 cx, cy, new&, r / wi, r / hi, a
  106.     _FREEIMAGE new&
  107.  
  108.  
  109. FUNCTION polyCollide (vert1() AS XY, vert2() AS XY)
  110.     DIM n1 AS INTEGER, n2 AS INTEGER
  111.     n1 = UBOUND(vert1): n2 = UBOUND(vert2)
  112.     'checking if any point of polygon 1 inside polygon 2
  113.     FOR i = 0 TO n1
  114.         IF pointInsidePoly(vert1(i), vert2()) THEN polyCollide = -1: EXIT FUNCTION
  115.     NEXT
  116.     'checking if any point of polygon 2 inside polygon 1
  117.     FOR i = 0 TO n2
  118.         IF pointInsidePoly(vert2(i), vert1()) THEN polyCollide = -1: EXIT FUNCTION
  119.     NEXT
  120.     ' checking the edge intersection
  121.     FOR i = 0 TO n1
  122.         FOR j = 0 TO n2
  123.             IF lineIntersect(vert1(i).x, vert1(i).y, vert1((i + 1) MOD (n1 + 1)).x, vert1((i + 1) MOD (n1 + 1)).y, vert2(j).x, vert2(j).y, vert2((j + 1) MOD (n2 + 1)).x, vert2((j + 1) MOD (n2 + 1)).y) THEN polyCollide = -1: EXIT FUNCTION
  124.         NEXT
  125.     NEXT
  126.  
  127. 'from paulbourke.net
  128. FUNCTION pointInsidePoly (p AS XY, polyVert() AS XY)
  129.     DIM ax1, ax2, ay1, ay2
  130.     n = UBOUND(polyVert)
  131.     FOR i = 0 TO n
  132.         ax1 = polyVert(i).x - p.x
  133.         ay1 = polyVert(i).y - p.y
  134.         ax2 = polyVert((i + 1) MOD (n + 1)).x - p.x
  135.         ay2 = polyVert((i + 1) MOD (n + 1)).y - p.y
  136.         ang = ang + angle2D(ax1, ay1, ax2, ay2)
  137.     NEXT
  138.     pointInsidePoly = (ABS(ang) >= _PI)
  139.  
  140. 'from paulbourke.net
  141. FUNCTION angle2D (x1, y1, x2, y2)
  142.     DIM theta1, theta2, ftheta
  143.     theta1 = _ATAN2(y1, x1)
  144.     theta2 = _ATAN2(y2, x2)
  145.     ftheta = theta1 - theta2
  146.     WHILE ftheta > _PI: ftheta = ftheta - _PI(2): WEND
  147.     WHILE ftheta < -_PI: ftheta = ftheta + _PI(2): WEND
  148.     angle2D = ftheta
  149.  
  150. FUNCTION lineIntersect (__x1, __y1, __x2, __y2, __x3, __y3, __x4, __y4)
  151.     DIM x1 AS INTEGER, y1 AS INTEGER, x2 AS INTEGER, y2 AS INTEGER, x3 AS INTEGER, y3 AS INTEGER, x4 AS INTEGER, y4 AS INTEGER
  152.     DIM a1, b1, c1, a2, b2, c2
  153.     DIM a1b2_minus_a2b1, b1c2_minus_b2c1, a2c1_minus_a1c2
  154.     DIM inter_x AS INTEGER, inter_y AS INTEGER
  155.  
  156.     x1 = __x1: x2 = __x2: x3 = __x3: x4 = __x4
  157.     y1 = __y1: y2 = __y2: y3 = __y3: y4 = __y4
  158.  
  159.     IF x1 > x2 THEN SWAP x1, x2
  160.     IF x3 > x4 THEN SWAP x3, x4
  161.     IF y1 > y2 THEN SWAP y1, y2
  162.     IF y3 > y4 THEN SWAP y3, y4
  163.  
  164.     a1 = __y2 - __y1: b1 = -(__x2 - __x1): c1 = (__x2 * __y1) - (__x1 * __y2)
  165.     a2 = __y4 - __y3: b2 = -(__x4 - __x3): c2 = (__x4 * __y3) - (__x3 * __y4)
  166.  
  167.     'check if lines are perfectly vertical or horizontal
  168.     IF a1 = 0 AND a2 = 0 THEN lineIntersect = (__y1 = __y3): _DEST 0: EXIT FUNCTION
  169.     IF b1 = 0 AND b2 = 0 THEN lineIntersect = (__x1 = __x3): _DEST 0: EXIT FUNCTION
  170.     IF a2 = 0 OR b2 = 0 THEN GOTO skip_component_ratio
  171.  
  172.     'check if the whole line segments coincide with each other.
  173.     IF c2 <> 0 THEN
  174.         IF (a1 / a2) = (b1 / b2) AND (b1 / b2) = (c1 / c2) THEN
  175.             lineIntersect = -1: EXIT FUNCTION
  176.         END IF
  177.     END IF
  178.     skip_component_ratio:
  179.     'check if the line segments have same slope.
  180.     IF a1 * b2 = a2 * b1 THEN
  181.         lineIntersect = (c1 = c2) 'special case, when they still coincide (as c1=c2)
  182.         EXIT FUNCTION
  183.     END IF
  184.     'check if the line do intersect between the segments.
  185.     a1b2_minus_a2b1 = (a1 * b2) - (a2 * b1): b1c2_minus_b2c1 = (b1 * c2) - (b2 * c1): a2c1_minus_a1c2 = (a2 * c1) - (a1 * c2)
  186.     inter_x = b1c2_minus_b2c1 / a1b2_minus_a2b1: inter_y = a2c1_minus_a1c2 / a1b2_minus_a2b1
  187.  
  188.     lineIntersect = ((inter_x >= x1 AND inter_x <= x2 AND inter_y >= y1 AND inter_y <= y2)) AND ((inter_x >= x3 AND inter_x <= x4 AND inter_y >= y3 AND inter_y <= y4))
  189.  
  190. 'taken from p5js.bas
  191. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  192.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  193.  
  194. FUNCTION p5random! (mn!, mx!)
  195.     IF mn! > mx! THEN
  196.         SWAP mn!, mx!
  197.     END IF
  198.     p5random! = RND * (mx! - mn!) + mn!
  199.  
  200. ' b+ added some helpers =====================================================================================
  201.  
  202. SUB RotoZoom3 (X AS LONG, Y AS LONG, Image AS LONG, xScale AS SINGLE, yScale AS SINGLE, radianRotation AS SINGLE) ' 0 at end means no scaling of x or y
  203.     DIM px(3) AS SINGLE: DIM py(3) AS SINGLE
  204.     DIM W&, H&, sinr!, cosr!, i&, x2&, y2&
  205.     W& = _WIDTH(Image&): H& = _HEIGHT(Image&)
  206.     px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
  207.     px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
  208.     sinr! = SIN(-radianRotation): cosr! = COS(-radianRotation)
  209.     FOR i& = 0 TO 3
  210.         x2& = xScale * (px(i&) * cosr! + sinr! * py(i&)) + X: y2& = yScale * (py(i&) * cosr! - px(i&) * sinr!) + Y
  211.         px(i&) = x2&: py(i&) = y2&
  212.     NEXT
  213.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  214.     _MAPTRIANGLE _SEAMLESS(0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  215.  
  216. FUNCTION midInk~& (r1%, g1%, b1%, r2%, g2%, b2%, fr##)
  217.     midInk~& = _RGB32(r1% + (r2% - r1%) * fr##, g1% + (g2% - g1%) * fr##, b1% + (b2% - b1%) * fr##)
  218.  
  219. ' create new Image Handle for an image copy with a color changed from original image, returns new Handle&
  220. 'https://www.qb64.org/forum/index.php?topic=2451.0
  221. ' from Petr to Craz1000
  222. FUNCTION swapColor& (oldHandle&, oldcolor~&, newcolor~&)
  223.     DIM m AS _MEM, c AS _UNSIGNED LONG
  224.     swapColor& = _COPYIMAGE(oldHandle&, 32)
  225.     m = _MEMIMAGE(swapColor)
  226.     DO UNTIL a& = m.SIZE - 4
  227.         a& = a& + 4
  228.         c~& = _MEMGET(m, m.OFFSET + a&, _UNSIGNED LONG)
  229.         IF c~& = oldcolor~& THEN _MEMPUT m, m.OFFSET + a&, newcolor~&
  230.     LOOP
  231.     _MEMFREE m
  232.  
  233.  

Same png as in zip above.
Space filling poly wImage swap color.PNG
* Space filling poly wImage swap color.PNG (Filesize: 117.78 KB, Dimensions: 809x632, Views: 201)
« Last Edit: April 29, 2020, 09:58:36 pm by bplus »

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Space Filling with Polygons
« Reply #11 on: April 30, 2020, 08:41:14 am »
@bplus
Cool! I liked your MOD!
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Space Filling with Polygons
« Reply #12 on: April 30, 2020, 11:40:56 am »
@Ashish

And I like this demo because you are getting in closer with the polygons than you could with circles with the polygons drawn within. ie could almost do same thing with a circle fill and then embed any regular poly within the circles but they could not get as close as they do here, some side by side.

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Space Filling with Polygons
« Reply #13 on: April 30, 2020, 12:14:43 pm »
@bplus
Yeah, thanks for giving the idea
Here we gooo...!!

Code: QB64: [Select]
  1. 'Space Filling with Polygon
  2. 'By Ashish
  3. 'MOD : RESTRICTED AREA
  4. 'circle is situated at the center of the screen
  5.  
  6. TYPE gl_vertex_type
  7.     'position of vertex
  8.     x AS SINGLE
  9.     y AS SINGLE
  10.     'center
  11.     cx AS SINGLE
  12.     cy AS SINGLE
  13.     'color of the vertex to be used
  14.     r AS SINGLE
  15.     g AS SINGLE
  16.     b AS SINGLE
  17.  
  18. _TITLE "Space Filling with Polygon [MOD:RESTRICTED AREA]"
  19. SCREEN _NEWIMAGE(800, 600, 32)
  20.  
  21. DIM SHARED init, polySides
  22. 'warning : polySides must always be greater than 2
  23. polySides = 3 'change its value to get different polygons
  24. DIM tempPoly1(polySides - 1) AS gl_vertex_type, tempPoly2(polySides - 1) AS gl_vertex_type
  25. REDIM SHARED polys(polySides - 1) AS gl_vertex_type
  26.  
  27.  
  28. init = 0
  29. poly_index = 0
  30. i = 1
  31. c = 1.05
  32. failed = 0
  33.         search_new_place:
  34.     IF init = 0 THEN
  35.         r = p5random(100, 150)
  36.         ox = p5random(r, _WIDTH - r)
  37.         oy = p5random(r, _HEIGHT - r)
  38.         offAng = p5random(-_PI, _PI)
  39.         clr~& = midColor(_RGB(255, 255, 0), _RGB(255, 100, 0), map(r, 150, 3, 0, 1))
  40.         red = map(_RED(clr~&), 0, 255, 0, 1): green = map(_GREEN(clr~&), 0, 255, 0, 1): blue = map(_BLUE(clr~&), 0, 255, 0, 1)
  41.         FOR j = 0 TO polySides - 1
  42.             polys(j).x = ox+COS(j * (_PI(2 / polySides)) + offAng) * r
  43.             polys(j).y = oy+SIN(j * (_PI(2 / polySides)) + offAng) * r
  44.                         if not insideCircle(polys(j),400,300,300) then  goto search_new_place
  45.                        
  46.             polys(j).cx = ox: polys(j).cy = oy
  47.             polys(j).r = red: polys(j).g = green: polys(j).b = blue
  48.         NEXT
  49.         init = -1
  50.         poly_index = poly_index + polySides
  51.     ELSE
  52.         r = 120 / (c ^ i)
  53.         ox = p5random(r, _WIDTH - r)
  54.         oy = p5random(r, _HEIGHT - r)
  55.         collided = 0
  56.         offAng = p5random(-_PI, _PI)
  57.         FOR j = 0 TO polySides - 1
  58.             tempPoly1(j).x = ox + COS(j * (_PI(2 / polySides)) + offAng) * r
  59.             tempPoly1(j).y = oy + SIN(j * (_PI(2 / polySides)) + offAng) * r
  60.                         if not insideCircle(tempPoly1(j),400,300,300) then goto search_new_place
  61.         NEXT
  62.         FOR j = 0 TO UBOUND(polys) STEP polySides
  63.             FOR k = j TO j + polySides - 1
  64.                 tempPoly2(k - j) = polys(k)
  65.             NEXT
  66.             IF polyCollide(tempPoly1(), tempPoly2()) THEN collided = -1: EXIT FOR
  67.         NEXT
  68.         IF NOT collided THEN
  69.             REDIM _PRESERVE polys(UBOUND(polys) + polySides) AS gl_vertex_type
  70.             clr~& = midColor(_RGB(255, 255, 0), _RGB(255, 100, 0), map(r, 120, 3, 0, 1))
  71.             red = map(_RED(clr~&), 0, 255, 0, 1): green = map(_GREEN(clr~&), 0, 255, 0, 1): blue = map(_BLUE(clr~&), 0, 255, 0, 1)
  72.             FOR j = poly_index TO poly_index + polySides - 1
  73.                 polys(j) = tempPoly1(j - poly_index)
  74.                 polys(j).cx = ox: polys(j).cy = oy
  75.                 polys(j).r = red: polys(j).g = green: polys(j).b = blue
  76.             NEXT
  77.             poly_index = poly_index + polySides
  78.         ELSE
  79.             failed = failed + 1
  80.             IF failed > (i * 60) THEN i = i + 1: failed = 0
  81.         END IF
  82.     END IF
  83. LOOP UNTIL r < 3
  84.  
  85.  
  86. SUB _GL ()
  87.     IF NOT init THEN EXIT SUB
  88.         _glEnable _GL_TEXTURE_2D
  89.     _glMatrixMode _GL_MODELVIEW
  90.  
  91.     'set the gl screen so that it can work normal screen coordinates
  92.     _glTranslatef -1, 1, 0
  93.     _glScalef 1 / 400, -1 / 300, 1
  94.      
  95.     'to get shaded effect, we will divide polygon into smaller triangles from center of polygon in a cyclic way.
  96.     FOR n = 0 TO UBOUND(polys) STEP polySides
  97.         _glPushMatrix
  98.         _glTranslatef polys(n).cx, polys(n).cy, 0
  99.         _glBegin _GL_TRIANGLES
  100.         FOR j = n TO n + polySides - 1
  101.             _glColor3f 0, 0, 0
  102.             _glVertex2i 0, 0
  103.             _glColor3f polys(n).r, polys(n).g, polys(n).b
  104.             _glVertex2i polys(j).x - polys(n).cx, polys(j).y - polys(j).cy
  105.             IF (j + 1) MOD (n + polySides) = 0 THEN _glVertex2i polys(n).x - polys(n).cx, polys(n).y - polys(j).cy ELSE _glVertex2i polys(j + 1).x - polys(n).cx, polys(j + 1).y - polys(j).cy
  106.         NEXT
  107.         _glEnd
  108.         _glPopMatrix
  109.     NEXT
  110.  
  111. function insideCircle (p as gl_vertex_type, cx, cy, rad)
  112.     insideCircle = (sqr((cx-p.x)^2+(cy-p.y)^2)<=rad)
  113.  
  114. FUNCTION midColor~& (clr1 AS _UNSIGNED LONG, clr2 AS _UNSIGNED LONG, v)
  115.     midColor~& = _RGB(map(v, 0, 1, _RED(clr1), _RED(clr2)), map(v, 0, 1, _GREEN(clr1), _GREEN(clr2)), map(v, 0, 1, _BLUE(clr1), _BLUE(clr2)))
  116.  
  117. FUNCTION polyCollide (vert1() AS gl_vertex_type, vert2() AS gl_vertex_type)
  118.     DIM n1 AS INTEGER, n2 AS INTEGER
  119.     n1 = UBOUND(vert1): n2 = UBOUND(vert2)
  120.     'checking if any point of polygon 1 inside polygon 2
  121.     FOR i = 0 TO n1
  122.         IF pointInsidePoly(vert1(i), vert2()) THEN polyCollide = -1: EXIT FUNCTION
  123.     NEXT
  124.     'checking if any point of polygon 2 inside polygon 1
  125.     FOR i = 0 TO n2
  126.         IF pointInsidePoly(vert2(i), vert1()) THEN polyCollide = -1: EXIT FUNCTION
  127.     NEXT
  128.     ' checking the edge intersection
  129.     FOR i = 0 TO n1
  130.         FOR j = 0 TO n2
  131.             IF lineIntersect(vert1(i).x, vert1(i).y, vert1((i + 1) MOD (n1 + 1)).x, vert1((i + 1) MOD (n1 + 1)).y, vert2(j).x, vert2(j).y, vert2((j + 1) MOD (n2 + 1)).x, vert2((j + 1) MOD (n2 + 1)).y) THEN polyCollide = -1: EXIT FUNCTION
  132.         NEXT
  133.     NEXT
  134.  
  135. 'from paulbourke.net
  136. FUNCTION pointInsidePoly (p AS gl_vertex_type, polyVert() AS gl_vertex_type)
  137.     DIM ax1, ax2, ay1, ay2
  138.     n = UBOUND(polyVert)
  139.     FOR i = 0 TO n
  140.         ax1 = polyVert(i).x - p.x
  141.         ay1 = polyVert(i).y - p.y
  142.         ax2 = polyVert((i + 1) MOD (n + 1)).x - p.x
  143.         ay2 = polyVert((i + 1) MOD (n + 1)).y - p.y
  144.         ang = ang + angle2D(ax1, ay1, ax2, ay2)
  145.     NEXT
  146.     pointInsidePoly = (ABS(ang) >= _PI)
  147.  
  148. 'from paulbourke.net
  149. FUNCTION angle2D (x1, y1, x2, y2)
  150.     DIM theta1, theta2, ftheta
  151.     theta1 = _ATAN2(y1, x1)
  152.     theta2 = _ATAN2(y2, x2)
  153.     ftheta = theta1 - theta2
  154.     WHILE ftheta > _PI: ftheta = ftheta - _PI(2): WEND
  155.     WHILE ftheta < -_PI: ftheta = ftheta + _PI(2): WEND
  156.     angle2D = ftheta
  157.  
  158. FUNCTION lineIntersect (__x1, __y1, __x2, __y2, __x3, __y3, __x4, __y4)
  159.     DIM x1 AS INTEGER, y1 AS INTEGER, x2 AS INTEGER, y2 AS INTEGER, x3 AS INTEGER, y3 AS INTEGER, x4 AS INTEGER, y4 AS INTEGER
  160.     DIM a1, b1, c1, a2, b2, c2
  161.     DIM a1b2_minus_a2b1, b1c2_minus_b2c1, a2c1_minus_a1c2
  162.     DIM inter_x AS INTEGER, inter_y AS INTEGER
  163.  
  164.     x1 = __x1: x2 = __x2: x3 = __x3: x4 = __x4
  165.     y1 = __y1: y2 = __y2: y3 = __y3: y4 = __y4
  166.    
  167.     IF x1 > x2 THEN SWAP x1, x2
  168.     IF x3 > x4 THEN SWAP x3, x4
  169.     IF y1 > y2 THEN SWAP y1, y2
  170.     IF y3 > y4 THEN SWAP y3, y4
  171.    
  172.     a1 = __y2 - __y1: b1 = -(__x2 - __x1): c1 = (__x2 * __y1) - (__x1 * __y2)
  173.     a2 = __y4 - __y3: b2 = -(__x4 - __x3): c2 = (__x4 * __y3) - (__x3 * __y4)
  174.  
  175.     'check if lines are perfectly vertical or horizontal
  176.     IF a1 = 0 AND a2 = 0 THEN lineIntersect = (__y1 = __y3): _DEST 0: EXIT FUNCTION
  177.     IF b1 = 0 AND b2 = 0 THEN lineIntersect = (__x1 = __x3): _DEST 0: EXIT FUNCTION
  178.     IF a2 = 0 OR b2 = 0 THEN GOTO skip_component_ratio
  179.    
  180.     'check if the whole line segments coincide with each other.
  181.     IF c2 <> 0 THEN
  182.         IF (a1 / a2) = (b1 / b2) AND (b1 / b2) = (c1 / c2) THEN
  183.             lineIntersect = -1: EXIT FUNCTION
  184.         END IF
  185.     END IF
  186.     skip_component_ratio:
  187.     'check if the line segments have same slope.
  188.     IF a1 * b2 = a2 * b1 THEN
  189.         lineIntersect = (c1 = c2) 'special case, when they still coincide (as c1=c2)
  190.         EXIT FUNCTION
  191.     END IF
  192.     'check if the line do intersect between the segments.
  193.     a1b2_minus_a2b1 = (a1 * b2) - (a2 * b1): b1c2_minus_b2c1 = (b1 * c2) - (b2 * c1): a2c1_minus_a1c2 = (a2 * c1) - (a1 * c2)
  194.     inter_x = b1c2_minus_b2c1 / a1b2_minus_a2b1: inter_y = a2c1_minus_a1c2 / a1b2_minus_a2b1
  195.    
  196.     lineIntersect = ((inter_x >= x1 AND inter_x <= x2 AND inter_y >= y1 AND inter_y <= y2)) AND ((inter_x >= x3 AND inter_x <= x4 AND inter_y >= y3 AND inter_y <= y4))
  197.  
  198. 'taken from p5js.bas
  199. FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
  200.     map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
  201.  
  202. FUNCTION p5random! (mn!, mx!)
  203.     IF mn! > mx! THEN
  204.         SWAP mn!, mx!
  205.     END IF
  206.     p5random! = RND * (mx! - mn!) + mn!
  207.  



 
Screenshot_1.png

if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Space Filling with Polygons
« Reply #14 on: April 30, 2020, 12:34:20 pm »
@Ashish,

Cool! but can you use this very code (with slight mod) to fill a big triangle with triangles and maybe squares pentagons, hexagons.... but at least triangles?