Author Topic: Celtic Square Knot  (Read 4087 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Celtic Square Knot
« on: September 15, 2020, 01:21:16 pm »
My new Avatar!

Code: QB64: [Select]
  1. _TITLE "Celtic Square Knot" 'b+ 2020-09-15 I am obsessed ;-))
  2.  
  3. SCREEN _NEWIMAGE(500, 500, 32)
  4. _DELAY .25
  5.  
  6. TYPE Box
  7.     x AS SINGLE
  8.     y AS SINGLE
  9.     w AS SINGLE
  10.     h AS SINGLE
  11.  
  12. 'check for overlap , dang ok fix OK good
  13. drawFrame _WIDTH / 2 - 100, _HEIGHT / 2 - 100, 300, 200, 10, &H22FFFFFF
  14. side = 390
  15. CelticSqrKnot _WIDTH / 2 - side / 2, _HEIGHT / 2 - side / 2, side, &HFF00AA55
  16.  
  17.  
  18. 'now for the knot
  19. SUB CelticSqrKnot (x, y, side, backK AS _UNSIGNED LONG) 'if side and thick are multiples of 7 this could work side > 6*th
  20.     ' calc 7*xSpace + 6*th = side  so xspace = (side - 6*th)/7
  21.  
  22.     'if we make it simple x = th then 7*th + 6*th = side so side has to be multiple of 13
  23.     th = INT(side / 13)
  24.  
  25.  
  26.     ' 3 frames  4 boxes each
  27.     DIM f1(1 TO 4) AS Box, f2(1 TO 4) AS Box, f3(1 TO 4) AS Box
  28.     DIM bxs(1 TO 12) AS Box, bi AS INTEGER
  29.     cF1 = &HFF0000AA: cF2 = &HFFFFFF00: cF3 = &HFFAA0000: white = &HFFFFFFFF
  30.  
  31.     LINE (x, y)-STEP(13 * th, 13 * th), backK, BF 'back ground can be transparent
  32.  
  33.     drawFrame x + 5 * th, y + th, 3 * th, 11 * th, th, cF1 'vertical
  34.     frameParts x + 5 * th, y + th, 3 * th, 11 * th, th, f1()
  35.  
  36.  
  37.     drawFrame x + 3 * th, y + 3 * th, 7 * th, 7 * th, th, cF2 'square
  38.     frameParts x + 3 * th, y + 3 * th, 7 * th, 7 * th, th, f2()
  39.  
  40.  
  41.     drawFrame x + th, y + 5 * th, 11 * th, 3 * th, th, cF3 ' horizontal
  42.     frameParts x + th, y + 5 * th, 11 * th, 3 * th, th, f3()
  43.  
  44.     count = 0
  45.     'frame 1, 1234 intersect frame 2 square 5678
  46.     FOR fb1 = 1 TO 4
  47.         FOR fb2 = 1 TO 4
  48.             IF collision(f1(fb1).x, f1(fb1).y, f1(fb1).w, f1(fb1).h, f2(fb2).x, f2(fb2).y, f2(fb2).w, f2(fb2).h) THEN
  49.  
  50.                 ' get the intersecting box
  51.                 collisionIntersect2Boxes f1(fb1).x, f1(fb1).y, f1(fb1).w, f1(fb1).h, f2(fb2).x, f2(fb2).y, f2(fb2).w, f2(fb2).h, bix, biy, biw, bih
  52.                 count = count + 1
  53.                 IF count MOD 4 < 2 THEN LINE (bix, biy)-STEP(biw, bih), cF1, BF
  54.                 IF count MOD 4 > 1 THEN LINE (bix, biy)-STEP(biw, bih), cF2, BF
  55.                 'IF count MOD 4 = 3 THEN LINE (bix, biy)-STEP(biw, bih), cF2, BF
  56.                 'IF count MOD 4 = 0 THEN LINE (bix, biy)-STEP(biw, bih), cF1, BF
  57.             END IF
  58.         NEXT
  59.     NEXT
  60.  
  61.     count = 0
  62.     'frame 1, 1234 intersect frame 3 intersect 9, 10, 11, 12
  63.     FOR fb1 = 1 TO 4
  64.         FOR fb2 = 1 TO 4
  65.             IF collision(f1(fb1).x, f1(fb1).y, f1(fb1).w, f1(fb1).h, f3(fb2).x, f3(fb2).y, f3(fb2).w, f3(fb2).h) THEN
  66.  
  67.                 ' get the intersecting box
  68.                 collisionIntersect2Boxes f1(fb1).x, f1(fb1).y, f1(fb1).w, f1(fb1).h, f3(fb2).x, f3(fb2).y, f3(fb2).w, f3(fb2).h, bix, biy, biw, bih
  69.                 count = count + 1
  70.                 IF count MOD 4 < 2 THEN LINE (bix, biy)-STEP(biw, bih), cF3, BF
  71.                 IF count MOD 4 > 1 THEN LINE (bix, biy)-STEP(biw, bih), cF1, BF
  72.                 'IF count MOD 4 = 3 THEN LINE (bix, biy)-STEP(biw, bih), cF1, BF
  73.                 'IF count MOD 4 = 0 THEN LINE (bix, biy)-STEP(biw, bih), cF3, BF
  74.             END IF
  75.         NEXT
  76.     NEXT
  77.  
  78.     count = 0
  79.     'frame 2, 5678 intersect frame 3 intersect 9, 10, 11, 12
  80.     FOR fb1 = 1 TO 4
  81.         FOR fb2 = 1 TO 4
  82.             IF collision(f2(fb1).x, f2(fb1).y, f2(fb1).w, f2(fb1).h, f3(fb2).x, f3(fb2).y, f3(fb2).w, f3(fb2).h) THEN
  83.  
  84.                 ' get the intersecting box
  85.                 collisionIntersect2Boxes f2(fb1).x, f2(fb1).y, f2(fb1).w, f2(fb1).h, f3(fb2).x, f3(fb2).y, f3(fb2).w, f3(fb2).h, bix, biy, biw, bih
  86.                 count = count + 1
  87.                 IF count MOD 4 < 2 THEN LINE (bix, biy)-STEP(biw, bih), cF2, BF
  88.                 IF count MOD 4 > 1 THEN LINE (bix, biy)-STEP(biw, bih), cF3, BF
  89.                 'IF count MOD 4 = 3 THEN LINE (bix, biy)-STEP(biw, bih), cF3, BF
  90.                 'IF count MOD 4 = 0 THEN LINE (bix, biy)-STEP(biw, bih), cF2, BF
  91.             END IF
  92.         NEXT
  93.     NEXT
  94.  
  95.  
  96. SUB drawFrame (x, y, w, h, th, k AS _UNSIGNED LONG)
  97.     LINE (x, y)-STEP(w, th), k, BF 'two horizontal
  98.     LINE (x, y + h - th)-STEP(w, th), k, BF
  99.     LINE (x, y + th + 1)-STEP(th, h - 2 * th - 2), k, BF 'try not to overlap boxes in case k is transparent
  100.     LINE (x + w - th, y + th + 1)-STEP(th, h - 2 * th - 2), k, BF
  101.  
  102. SUB frameParts (x, y, w, h, th, bxs() AS Box)
  103.  
  104.     'for each line in drawFrame
  105.  
  106.     'LINE (x, y)-STEP(w, th), k, BF 'two horizontal
  107.     bxs(1).x = x
  108.     bxs(1).y = y
  109.     bxs(1).w = w
  110.     bxs(1).h = th
  111.  
  112.     'LINE (x, y + h - th)-STEP(w, th), k, BF
  113.     bxs(2).x = x
  114.     bxs(2).y = y + h - th
  115.     bxs(2).w = w
  116.     bxs(2).h = th
  117.  
  118.     'LINE (x, y + th + 1)-STEP(th, h - 2 * th - 2), k, BF 'try not to overlap boxes in case k is transparent
  119.     bxs(3).x = x
  120.     bxs(3).y = y + th + 1
  121.     bxs(3).w = th
  122.     bxs(3).h = h - 2 * th - 2
  123.  
  124.     'LINE (x + w - th, y + th + 1)-STEP(th, h - 2 * th - 2), k, BF
  125.     bxs(4).x = x + w - th
  126.     bxs(4).y = y + th + 1
  127.     bxs(4).w = th
  128.     bxs(4).h = h - 2 * th - 2
  129.  
  130.  
  131. FUNCTION collision% (b1x, b1y, b1w, b1h, b2x, b2y, b2w, b2h)
  132.     ' x, y represent the box left most x and top most y
  133.     ' w, h represent the box width and height which is the usual way sprites / tiles / images are described
  134.     ' such that boxbottom = by + bh
  135.     '        and boxright = bx + bw
  136.  
  137.     IF (b1y + b1h < b2y) OR (b1y > b2y + b2h) OR (b1x > b2x + b2w) OR (b1x + b1w < b2x) THEN
  138.         collision% = 0
  139.     ELSE
  140.         collision% = 1
  141.     END IF
  142.  
  143. SUB collisionIntersect2Boxes (b1x, b1y, b1w, b1h, b2x, b2y, b2w, b2h, bix, biy, biw, bih)
  144.     IF b2x >= b1x AND b2x <= b1x + b1w AND b2y >= b1y AND b2y <= b1y + b1h THEN 'top left corner in 2nd box
  145.         bix = b2x: biy = b2y
  146.         IF b2x + b2w <= b1x + b1w THEN
  147.             biw = b2w
  148.         ELSE
  149.             biw = b1x + b1w - b2x
  150.         END IF
  151.         IF b2y + b2h <= b1y + b1h THEN
  152.             bih = b2h
  153.         ELSE
  154.             bih = b1y + b1h - b2y
  155.         END IF
  156.     ELSEIF b2x >= b1x AND b2x <= b1x + b1w AND b2y + b2h >= b1y AND b2y + b2h <= b1y + b1h THEN 'bottom left corner of 2nd box in first
  157.         bix = b2x
  158.         IF b2x + b2w <= b1x + b1w THEN
  159.             biw = b2w
  160.         ELSE
  161.             biw = b1x + b1w - b2x
  162.         END IF
  163.         IF b2y <= b1y THEN
  164.             biy = b1y
  165.             bih = b2y + b2h - b1y
  166.         ELSE
  167.             biy = b2y
  168.             bih = b2h
  169.         END IF
  170.     ELSEIF b2x + b2w >= b1x AND b2x + b2w <= b1x + b1w AND b2y >= b1y AND b2y <= b1y + b1h THEN 'right top corner 2nd box in first
  171.         IF b2x >= b1x THEN
  172.             bix = b2x
  173.             biw = b2w
  174.         ELSE
  175.             bix = b1x
  176.             biw = b2x + b2w - b1x
  177.         END IF
  178.         biy = b2y
  179.         IF b2y + b2h <= b1y + b1h THEN
  180.             bih = b2h
  181.         ELSE
  182.             bih = b1y + b1h - b2y
  183.         END IF
  184.     ELSEIF b2x + b2w >= b1x AND b2x + b2w <= b1x + b1w AND b2y + b2h >= b1y AND b2y + b2h <= b1y + b1h THEN 'left bottom corners in first box
  185.         IF b2x >= b1x THEN
  186.             bix = b2x
  187.             biw = b2w
  188.         ELSE
  189.             bix = b1x
  190.             biw = b2x + b2w - b1x
  191.         END IF
  192.         IF b2y >= b1y THEN
  193.             biy = b2y
  194.             bih = b2h
  195.         ELSE
  196.             biy = b1y
  197.             bih = b2y + b2h - b1y
  198.         END IF
  199.     ELSEIF collision%(b1x, b1y, b1w, b1h, b2x, b2y, b2w, b2h) THEN
  200.         bix = max(b1x, b2x): biy = max(b1y, b2y)
  201.         biw = min(b1x + b1w, b2x + b2w) - bix: bih = min(b1y + b1h, b2y + b2h) - biy
  202.     ELSE 'no intersect
  203.         bix = -1: biy = -1: biw = 0: bih = 0
  204.     END IF
  205.  
  206. FUNCTION max (a, b)
  207.     IF a > b THEN max = a ELSE max = b
  208.  
  209. FUNCTION min (a, b)
  210.     IF a < b THEN min = a ELSE min = b
  211.  
  212.  
  213.  

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Celtic Square Knot
« Reply #1 on: September 15, 2020, 02:40:06 pm »
New day, New avatar.....

Fairly cool, I must admit it surprised me how simple it was. I actually thought it was going to be a much more complex knot. But nice and simple!

Though it got me thinking, and I may start a new topic on it but wanted to ask here real quick cause I'm pretty sure you can probably think of a way to pull it off fairly easy, I have a continuing issue trying to pull something off that I just can't quite nail down.

I have a grid 194x79  with two boxes(or Rooms) on either side that I need a meandering path between. Not just a straight shot but something that uses a portion of the area to reach from one side to the other. My issue is the path I generate tends to just "scribble" ,best way I can describe, and it basically wipes the entire grid clear. rather than making a path.

There are no obstacles so no like path-finding(A*, what not) stuff of that type needed just a non-direct route between 2 points.
« Last Edit: September 15, 2020, 02:54:54 pm by Cobalt »
Granted after becoming radioactive I only have a half-life!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Celtic Square Knot
« Reply #2 on: September 15, 2020, 03:10:44 pm »
I am reminded of an old recursive routine that does lightning (connecting between 2 points) or mountain ranges also connecting between two points.

I imagine you'd want your path squared off, 90 degree turns? so a mod of lighting or mountain range.

Am I off track? or should I dig up code and mod? Maybe you know this code?

This might not meander enough because x step will advance to other room or won't advance but will never reverse meanwhile, y is going up and down but never so far away that it won't be back "in time" again to enter the opposite room.

Actually this sounds a little like what @SierraKen is working with cave paths. For real time meandering you'd need to track where you've meandered already and just how much you want to fill up the screen with meanderings :)

Come to think, you could generate a maze between the 2 rooms! Just feed it an enter point and exit point and the rectangle between the 2 rooms. Now there's meandering that doesn't waste a single square!



« Last Edit: September 15, 2020, 03:21:41 pm by bplus »

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Celtic Square Knot
« Reply #3 on: September 15, 2020, 03:18:45 pm »
thats pretty spot on, right angle turns.

I'll have to look at SK's post.

it was just the look of your output that made me think about asking.

an example of what I am trying to come close too,
GoalExample.jpg
* GoalExample.jpg (Filesize: 43.35 KB, Dimensions: 581x236, Views: 232)
« Last Edit: September 15, 2020, 03:24:32 pm by Cobalt »
Granted after becoming radioactive I only have a half-life!

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Celtic Square Knot
« Reply #4 on: September 15, 2020, 03:28:11 pm »
this is what I usually end up with,
WhatIendupwith.jpg
* WhatIendupwith.jpg (Filesize: 46.14 KB, Dimensions: 580x235, Views: 229)
Granted after becoming radioactive I only have a half-life!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Celtic Square Knot
« Reply #5 on: September 15, 2020, 03:54:52 pm »
That's kinda an interesting problem:

Measure the distance x, and y, for destination or target.

Every step towards or away will add to or subtract to distance, when time is up make bee line to next room first all x then all y or vice versa. If you changed x last time you have to change y at next change in direction.

Goody something to play with :)

Offline SierraKen

  • Forum Resident
  • Posts: 1454
    • View Profile
Re: Celtic Square Knot
« Reply #6 on: September 16, 2020, 01:08:07 am »
Cobalt, what I do is this:

IF ROOMX > YOUX THEN YOUX = YOUX + 20
IF ROOMX < YOUX THEN YOUX = YOUX - 20
IF ROOMY > YOUY THEN YOUY = YOUY + 20
IF ROOMY < YOUY THEN YOUY = YOUY - 20

And to make longer paths before they turn, I use a counter before the random direction change.