'Space Filling with Polygon
'By Ashish
'b+ copy and mod 2020-04-29 https://www.qb64.org/forum/index.php?topic=2515.msg117572#msg117572
'b+ mod 2 color changing
_TITLE "Space Filling with Polygon" 'INPUT "Enter the number of side for a polygon (must be greater than 2) : ", x%
'IF x% < 3 THEN PRINT "It must be greate than 2!, taking default value of 3. Hit ENTER.": SLEEP: x% = 3
' b+ loads an image and takes some measurements
'what is it's color
'END
polySides = 4
DIM tempPoly1
(polySides
- 1) AS XY
, tempPoly2
(polySides
- 1) AS XY
init = 0
poly_index = 0
i = 1
c = 1.1
failed = 0
LINE (0, y
)-(800, y
), midInk
(0, 0, 255, 255, 255, 0, y
/ 600) r = p5random(150, 200)
rStart = r
FOR j
= 0 TO polySides
- 1 polys
(j
).x
= ox
+ COS(j
* (_PI(2 / polySides
)) + offAng
) * r
polys
(j
).y
= oy
+ SIN(j
* (_PI(2 / polySides
)) + offAng
) * r
'clr~& = midColor(_RGB(255, 255, 0), _RGB(255, 100, 0), map(r, 200, 3, 0, 1))
drawPoly polys(), midInk~&(0, 128, 0, 255, 0, 255, (rStart - r) / rStart)
init = 1
poly_index = poly_index + polySides
r = 200 / (c ^ i)
collided = 0
FOR j
= 0 TO polySides
- 1 tempPoly1
(j
).x
= ox
+ COS(j
* (_PI(2 / polySides
)) + offAng
) * r
tempPoly1
(j
).y
= oy
+ SIN(j
* (_PI(2 / polySides
)) + offAng
) * r
FOR k
= j
TO j
+ polySides
- 1 tempPoly2(k - j) = polys(k)
IF polyCollide
(tempPoly1
(), tempPoly2
()) THEN collided
= -1:
EXIT FOR ' _echo "yes"
FOR j
= poly_index
TO poly_index
+ polySides
- 1 polys(j) = tempPoly1(j - poly_index)
clr~&
= midColor
(_RGB(255, 255, 0), _RGB(255, 100, 0), map
(r
, 200, 3, 0, 1)) drawPoly tempPoly1(), midInk~&(0, 128, 0, 255, 0, 255, (rStart - r) / rStart)
poly_index = poly_index + polySides
failed = failed + 1
IF failed
> (i
* 60) THEN i
= i
+ 1: failed
= 0
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
)))
'n = UBOUND(vert)
'DIM cx, cy
'FOR i = 0 TO n
' LINE (vert(i).x, vert(i).y)-(vert((i + 1) MOD (n + 1)).x, vert((i + 1) MOD (n + 1)).y), clr
' cx = cx + vert(i).x: cy = cy + vert(i).y
'NEXT
'cx = cx / (n + 1): cy = cy / (n + 1)
'PAINT (cx, cy), clr, clr
cx = (vert(0).x + vert(2).x) / 2 'find the center, radius and tilt
cy = (vert(0).y + vert(2).y) / 2
r
= SQR(2) * _HYPOT(cx
- vert
(0).x
, cy
- vert
(0).y
) 'mult bty SQR(2) locating sq top left corner from a
= _ATAN2(vert
(0).y
- cy
, vert
(0).x
- cx
) - _PI / 4 'subtract 45 degrees because square is off by that new& = swapColor&(ih&, origClr, clr)
RotoZoom3 cx, cy, new&, r / wi, r / hi, a
'checking if any point of polygon 1 inside polygon 2
'checking if any point of polygon 2 inside polygon 1
' checking the edge intersection
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
'from paulbourke.net
ax1 = polyVert(i).x - p.x
ay1 = polyVert(i).y - p.y
ax2
= polyVert
((i
+ 1) MOD (n
+ 1)).x
- p.x
ay2
= polyVert
((i
+ 1) MOD (n
+ 1)).y
- p.y
ang = ang + angle2D(ax1, ay1, ax2, ay2)
pointInsidePoly
= (ABS(ang
) >= _PI)
'from paulbourke.net
DIM theta1
, theta2
, ftheta
ftheta = theta1 - theta2
angle2D = ftheta
FUNCTION lineIntersect
(__x1
, __y1
, __x2
, __y2
, __x3
, __y3
, __x4
, __y4
) DIM a1
, b1
, c1
, a2
, b2
, c2
DIM a1b2_minus_a2b1
, b1c2_minus_b2c1
, a2c1_minus_a1c2
x1 = __x1: x2 = __x2: x3 = __x3: x4 = __x4
y1 = __y1: y2 = __y2: y3 = __y3: y4 = __y4
a1 = __y2 - __y1: b1 = -(__x2 - __x1): c1 = (__x2 * __y1) - (__x1 * __y2)
a2 = __y4 - __y3: b2 = -(__x4 - __x3): c2 = (__x4 * __y3) - (__x3 * __y4)
'check if lines are perfectly vertical or horizontal
'check if the whole line segments coincide with each other.
IF (a1
/ a2
) = (b1
/ b2
) AND (b1
/ b2
) = (c1
/ c2
) THEN skip_component_ratio:
'check if the line segments have same slope.
lineIntersect = (c1 = c2) 'special case, when they still coincide (as c1=c2)
'check if the line do intersect between the segments.
a1b2_minus_a2b1 = (a1 * b2) - (a2 * b1): b1c2_minus_b2c1 = (b1 * c2) - (b2 * c1): a2c1_minus_a1c2 = (a2 * c1) - (a1 * c2)
inter_x = b1c2_minus_b2c1 / a1b2_minus_a2b1: inter_y = a2c1_minus_a1c2 / a1b2_minus_a2b1
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
))
'taken from p5js.bas
FUNCTION map!
(value!
, minRange!
, maxRange!
, newMinRange!
, newMaxRange!
) map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
p5random!
= RND * (mx!
- mn!
) + mn!
' b+ added some helpers =====================================================================================
DIM W&
, H&
, sinr!
, cosr!
, i&
, x2&
, y2&
px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
sinr!
= SIN(-radianRotation
): cosr!
= COS(-radianRotation
) x2& = xScale * (px(i&) * cosr! + sinr! * py(i&)) + X: y2& = yScale * (py(i&) * cosr! - px(i&) * sinr!) + Y
px(i&) = x2&: py(i&) = y2&
FUNCTION midInk~&
(r1%
, g1%
, b1%
, r2%
, g2%
, b2%
, fr##
) midInk~&
= _RGB32(r1%
+ (r2%
- r1%
) * fr##
, g1%
+ (g2%
- g1%
) * fr##
, b1%
+ (b2%
- b1%
) * fr##
)
' create new Image Handle for an image copy with a color changed from original image, returns new Handle&
'https://www.qb64.org/forum/index.php?topic=2451.0
' from Petr to Craz1000
FUNCTION swapColor&
(oldHandle&
, oldcolor~&
, newcolor~&
) a& = a& + 4