Author Topic: Cresent Pattern Challenge from JB  (Read 8906 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Cresent Pattern Challenge from JB
« Reply #30 on: June 29, 2019, 12:57:42 pm »
Hi Steve,

That is about the simplest, most direct, easy to understand (and math lazy) way to assemble a twirler yet, though I haven't studied Petr's or quite follow _vince method (even though I modified it to line fill method from PAINT).

I always thought a horizontal row of cogs would alternate in spinning, the way you have them packed I think they would not be able to spin at all (assuming they are all touching). ???


To all,

I did work out a line filled circular arc crescent pattern and it looks much better than the one filled with PAINT method, it might be judged too complex compared to Steve's method of rendering. Can he do tri-color twirlers?

Code: QB64: [Select]
  1. _TITLE "Crescent Line Filled Circle Arcs" 'b+ 2019-06-29
  2. CONST xmax = 800, ymax = 600, pi = 3.14159265
  3. SCREEN _NEWIMAGE(xmax, ymax, 32)
  4. DIM aof
  5. COLOR &HFF000000, &HFFFFFFFF
  6.     CLS
  7.     'aof = 0 'ALL Stop   to view fill: hey that's a darn good fill!!!!
  8.     aof = aof + pi / 18
  9.     crescentLFCA xmax / 2, ymax / 2, 50, aof
  10.     _DISPLAY
  11.     _LIMIT 30
  12. 'cresecent Line Filled Circular Arcs  combines arc drawing sub with crescentPattern sub
  13. SUB crescentLFCA (x0, y0, r6, aoff) 'r6 is radius of 6 crescent pattern
  14.     DIM a12, r1, a6, x6, y6, x6m12, y6m12, i, al, a, x1, y1, x2, y2, c~&
  15.     r1 = r6 / 2 ' the radius of each crescent
  16.     a12 = 2 * pi / 12 ' 30 degrees to draw 12 arcs about x0, y0
  17.     a6 = 2 * pi / 6
  18.     FOR i = 1 TO 6 'draw 6 crescents find x, y of leading and trailing edges
  19.         x6 = x0 + r1 * COS(i * a6 + aoff): y6 = y0 + r1 * SIN(i * a6 + aoff) 'origins of leading edges
  20.         x6m12 = x0 + r1 * COS(i * a6 - a12 + aoff): y6m12 = y0 + r1 * SIN(i * a6 - a12 + aoff) 'origins of trailing edges
  21.         al = _PI * r1 * r1 * (pi + pi / 6) / _PI(2)
  22.         FOR a = (i * a6 + aoff - pi / 6) TO (i * a6 + aoff + pi) STEP 1 / al 'draw arc chords for dist a
  23.             x1 = x6 + r1 * COS(a): y1 = y6 + r1 * SIN(a) ' point on leading edge
  24.             x2 = x6m12 + r1 * COS(a): y2 = y6m12 + r1 * SIN(a) 'eqivalent point on trailing edge
  25.             IF i MOD 3 = 0 THEN
  26.                 c~& = &HFF990000
  27.             ELSEIF i MOD 3 = 1 THEN
  28.                 c~& = &HFF008800
  29.             ELSEIF i MOD 3 = 2 THEN
  30.                 c~& = &HFF000099
  31.             END IF
  32.             LINE (x1, y1)-(x2, y2), c~&
  33.         NEXT
  34.     NEXT
  35.  

  [ You are not allowed to view this attachment ]  

Here is wallpaper version for tiny wall:
Code: QB64: [Select]
  1. _TITLE "Crescent Line Filled Circular Arcs Wallpaper"
  2. CONST xmax = 200, ymax = 240, pi = 3.14159265
  3. SCREEN _NEWIMAGE(xmax, ymax, 32)
  4. DIM aof, polyr, stepX, stepY, y, xoff, x
  5. polyr = 20
  6. stepX = polyr * 2 + 1
  7. stepY = polyr * 1 * SQR(3) + 1
  8. COLOR , &HFFFFFFFF
  9.     CLS
  10.     xoff = 0
  11.     FOR y = polyr / 2 TO ymax - polyr / 2 STEP stepY
  12.         xoff = (xoff + 1) MOD 2
  13.         FOR x = 0 TO xmax + 7 * polyr STEP stepX
  14.             crescentLFCA x - xoff * 1.5 * stepX, y, polyr, aof
  15.         NEXT
  16.     NEXT
  17.     aof = aof + pi / 36
  18.     _DISPLAY
  19.     _LIMIT 200
  20.  
  21. 'cresecent Line Filled Circular Arcs  combines arc drawing sub with crescentPattern sub
  22. SUB crescentLFCA (x0, y0, r6, aoff) 'r6 is radius of 6 crescent pattern
  23.     DIM a12, r1, a6, x6, y6, x6m12, y6m12, i, al, a, x1, y1, x2, y2, c~&
  24.     r1 = r6 / 2 ' the radius of each crescent
  25.     a12 = 2 * pi / 12 ' 30 degrees to draw 12 arcs about x0, y0
  26.     a6 = 2 * pi / 6
  27.     FOR i = 1 TO 6 'draw 6 crescents find x, y of leading and trailing edges
  28.         x6 = x0 + r1 * COS(i * a6 + aoff): y6 = y0 + r1 * SIN(i * a6 + aoff) 'origins of leading edges
  29.         x6m12 = x0 + r1 * COS(i * a6 - a12 + aoff): y6m12 = y0 + r1 * SIN(i * a6 - a12 + aoff) 'origins of trailing edges
  30.         al = _PI * r1 * r1 * (pi + pi / 6) / _PI(2)
  31.         FOR a = (i * a6 + aoff - pi / 6) TO (i * a6 + aoff + pi) STEP 1 / al 'draw arc chords for dist a
  32.             x1 = x6 + r1 * COS(a): y1 = y6 + r1 * SIN(a) ' point on leading edge
  33.             x2 = x6m12 + r1 * COS(a): y2 = y6m12 + r1 * SIN(a) 'eqivalent point on trailing edge
  34.             IF i MOD 3 = 0 THEN
  35.                 c~& = &HFF990000
  36.             ELSEIF i MOD 3 = 1 THEN
  37.                 c~& = &HFF008800
  38.             ELSEIF i MOD 3 = 2 THEN
  39.                 c~& = &HFF000099
  40.             END IF
  41.             LINE (x1, y1)-(x2, y2), c~&
  42.         NEXT
  43.     NEXT
  44.  
« Last Edit: June 29, 2019, 01:30:27 pm by bplus »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Cresent Pattern Challenge from JB
« Reply #31 on: June 29, 2019, 01:12:19 pm »
Hi Steve,

That is about the simplest, most direct, easy to understand (and math lazy) way to assemble a twirler yet, though I haven't studied Petr's or quite follow _vince method (even though I modified it to line fill method from PAINT).

I always thought a horizontal row of cogs would alternate in spinning, the way you have them packed I think they would not be able to spin at all (assuming they are all touching). ???


To all,

I did work out a line filled circular arc crescent pattern and it looks much better than the one filled with PAINT method, it might be judged too complex compared to Steve's method of rendering. Can he do tri-color twirlers?

Looking at these, they appear to me to be more like designs on the edge of a wheel, than they do to be actual gears.  As such, the idea that each row would rotate in an opposite direction is rather quite natural (at least to my way of thinking).  The first row of "wheels" all rotate to the right, and the row under them would rotate to the left, with the next row rotating back to the right -- which is why I coded it the way I have.

As for using multiple colors, that's an easy modification as well:

Code: [Select]
DEFLNG A-Z
SCREEN _NEWIMAGE(640, 480, 32)
DIM Colors(3)
Colors(0) = &HFFFF0000 'Red
Colors(1) = &HFF0000FF 'Blue
Colors(2) = &HFF00FF00 'Green
Colors(3) = &HFFF0F00F 'Something... I just made up a value!

FOR i = 0 TO 8
    k = i MOD 4
    x = 25 * SIN(_D2R(30 * i)) + 50
    y = 25 * COS(_D2R(30 * i)) + 50
    CIRCLE (x, y), 25, Colors(k)
    PAINT (x, y), Colors(k)
NEXT

halfimage = _NEWIMAGE(50, 100, 32)
_PUTIMAGE , 0, halfimage, (50, 0)-(100, 100)
fullimage = _NEWIMAGE(100, 100, 32)
_DEST fullimage
DisplayImage halfimage, 50, 0, 0, 1
DisplayImage halfimage, 0, 0, 180, 4
_DEST 0

CLS ', Colors(-1)

DO
    angle = (angle + 1) MOD 360
    FOR y = -50 TO _HEIGHT + 50 STEP 82
        Insert = NOT Insert
        IF Insert THEN direction = -1 ELSE direction = 1
        FOR x = -50 TO _WIDTH + 50 STEP 100
            DisplayImage fullimage, x + Insert * 50, y, direction * angle, 0
        NEXT
    NEXT
    _DISPLAY
LOOP UNTIL _KEYHIT


SUB PlacePattern (Xwhere, Ywhere, WhichPattern)
    DisplayImage WhichPattern, Xwhere, Ywhere, 0, 1
    DisplayImage tempimage, Xwhere - 50, Ywhere, 180, 4
END SUB



SUB DisplayImage (Image AS LONG, x AS INTEGER, y AS INTEGER, angle AS SINGLE, mode AS _BYTE)
    'Image is the image handle which we use to reference our image.
    'x,y is the X/Y coordinates where we want the image to be at on the screen.
    'angle is the angle which we wish to rotate the image.
    'mode determines HOW we place the image at point X,Y.
    'Mode 0 we center the image at point X,Y
    'Mode 1 we place the Top Left corner of oour image at point X,Y
    'Mode 2 is Bottom Left
    'Mode 3 is Top Right
    'Mode 4 is Bottom Right


    DIM px(3) AS INTEGER, py(3) AS INTEGER, w AS INTEGER, h AS INTEGER
    DIM sinr AS SINGLE, cosr AS SINGLE, i AS _BYTE
    w = _WIDTH(Image): h = _HEIGHT(Image)
    SELECT CASE mode
        CASE 0 'center
            px(0) = -w \ 2: py(0) = -h \ 2: px(3) = w \ 2: py(3) = -h \ 2
            px(1) = -w \ 2: py(1) = h \ 2: px(2) = w \ 2: py(2) = h \ 2
        CASE 1 'top left
            px(0) = 0: py(0) = 0: px(3) = w: py(3) = 0
            px(1) = 0: py(1) = h: px(2) = w: py(2) = h
        CASE 2 'bottom left
            px(0) = 0: py(0) = -h: px(3) = w: py(3) = -h
            px(1) = 0: py(1) = 0: px(2) = w: py(2) = 0
        CASE 3 'top right
            px(0) = -w: py(0) = 0: px(3) = 0: py(3) = 0
            px(1) = -w: py(1) = h: px(2) = 0: py(2) = h
        CASE 4 'bottom right
            px(0) = -w: py(0) = -h: px(3) = 0: py(3) = -h
            px(1) = -w: py(1) = 0: px(2) = 0: py(2) = 0
    END SELECT
    sinr = SIN(angle / 57.2957795131): cosr = COS(angle / 57.2957795131)
    FOR i = 0 TO 3
        x2 = (px(i) * cosr + sinr * py(i)) + x: y2 = (py(i) * cosr - px(i) * sinr) + y
        px(i) = x2: py(i) = y2
    NEXT
    _MAPTRIANGLE (0, 0)-(0, h - 1)-(w - 1, h - 1), Image TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
    _MAPTRIANGLE (0, 0)-(w - 1, 0)-(w - 1, h - 1), Image TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
END SUB

The above has a real pretty little FOUR color pattern, which (I think, at least) helps to showcase the directional spin on our wheels.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Cresent Pattern Challenge from JB
« Reply #32 on: June 29, 2019, 02:57:38 pm »
I apologize in advance for the fact that this is only partially related to the topic. How to rotate the image - My frame method is memory -intensive as I have shown them. Turning with Steve's method in turn consumes a small amount of power. The worst method is direct rotation and direct rendering of everything at once. It depends on the particular program, when it fits best.
With both rotation method and with SaveImage can every from us easy sprite image files to do. If you set rotation center to correct place, you can rotate just piece of image  for example, just the character's hand, but not the whole character....

Bplus here hidden draw galaxy...



Code: [Select]
OPTION _EXPLICIT
_TITLE "Crescent Line Filled Circle Arcs" 'b+ 2019-06-29
CONST xmax = 800, ymax = 600, pi = 3.14159265
DIM aof
DIM Frames(35) AS LONG, CreateFrames AS INTEGER, X AS SINGLE, Z AS SINGLE, angle AS SINGLE, height AS SINGLE, f AS _BYTE

FOR CreateFrames = 0 TO 35
    Frames(CreateFrames) = _NEWIMAGE(101, 101, 32)
    _DEST Frames(CreateFrames)
    CLS
    'aof = 0 'ALL Stop   to view fill: hey that's a darn good fill!!!!
    aof = aof + pi / 18
    crescentLFCA 50, 50, 50, aof
    _CLEARCOLOR &HFF000000
NEXT
_DEST 0
transform Frames()


_DISPLAYORDER _SOFTWARE , _HARDWARE

DO
    Circled X, Z, angle, 1.3
    angle = angle + .01

    FOR height = 1.2 - Z TO 1.2 - Z + .1 STEP .01 'this is BAD METHOD, because i am too lasy. For best power muss be next segment defined and draw between segment A and segment B with MAPTRIANGLE.
        view3D 0 + X, height, -4 + Z, Frames(), f
    NEXT

    LOCATE 1, 1: PRINT "BPlus created color galaxy!"
    _DISPLAY
    f = f - 1: IF f < LBOUND(frames) THEN f = UBOUND(frames)
    _LIMIT 20
LOOP
'cresecent Line Filled Circular Arcs  combines arc drawing sub with crescentPattern sub
SUB crescentLFCA (x0, y0, r6, aoff) 'r6 is radius of 6 crescent pattern
    DIM a12, r1, a6, x6, y6, x6m12, y6m12, i, al, a, x1, y1, x2, y2, c~&
    r1 = r6 / 2 ' the radius of each crescent
    a12 = 2 * pi / 12 ' 30 degrees to draw 12 arcs about x0, y0
    a6 = 2 * pi / 6
    FOR i = 1 TO 6 'draw 6 crescents find x, y of leading and trailing edges
        x6 = x0 + r1 * COS(i * a6 + aoff): y6 = y0 + r1 * SIN(i * a6 + aoff) 'origins of leading edges
        x6m12 = x0 + r1 * COS(i * a6 - a12 + aoff): y6m12 = y0 + r1 * SIN(i * a6 - a12 + aoff) 'origins of trailing edges
        al = _PI * r1 * r1 * (pi + pi / 6) / _PI(2)
        FOR a = (i * a6 + aoff - pi / 6) TO (i * a6 + aoff + pi) STEP 1 / al 'draw arc chords for dist a
            x1 = x6 + r1 * COS(a): y1 = y6 + r1 * SIN(a) ' point on leading edge
            x2 = x6m12 + r1 * COS(a): y2 = y6m12 + r1 * SIN(a) 'eqivalent point on trailing edge
            IF i MOD 3 = 0 THEN
                c~& = &HFF990000
            ELSEIF i MOD 3 = 1 THEN
                c~& = &HFF008800
            ELSEIF i MOD 3 = 2 THEN
                c~& = &HFF000099
            END IF
            LINE (x1, y1)-(x2, y2), c~&
        NEXT
    NEXT
END SUB

SUB transform (arr() AS LONG)
    DIM t AS INTEGER, img32 AS LONG
    FOR t = LBOUND(arr) TO UBOUND(arr)
        img32 = _COPYIMAGE(arr(t))
        arr(t) = _COPYIMAGE(img32, 33)
        _FREEIMAGE img32
    NEXT
END SUB

SUB view3D (x AS SINGLE, y AS SINGLE, z AS SINGLE, arr() AS LONG, frameNR AS INTEGER)
    DIM w AS INTEGER, h AS INTEGER, width3d AS _BYTE, height3d AS _BYTE, depth3d AS _BYTE

    w = _WIDTH(arr(frameNR))
    h = _HEIGHT(arr(frameNR))

    width3d = 1
    height3d = 1
    depth3d = 1

    _MAPTRIANGLE (0, 0)-(w, 0)-(0, h), arr(frameNR) TO(x - width3d, y - height3d, z - 3 * depth3d)-(x + width3d, y - height3d, z - 3 * depth3d)-(x - width3d, y - height3d, z + 3 * depth3d)
    _MAPTRIANGLE (w, 0)-(0, h)-(w, h), arr(frameNR) TO(x + width3d, y - height3d, z - 3 * depth3d)-(x - width3d, y - height3d, z + 3 * depth3d)-(x + width3d, y - height3d, z + 3 * depth3d)
END SUB

SUB Circled (GetX, GetZ, angle, radius)
    GetX = SIN(angle) * radius
    GetZ = COS(angle) * radius
END SUB

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Cresent Pattern Challenge from JB
« Reply #33 on: June 29, 2019, 04:29:57 pm »
Thanks Petr for taking code to a higher place :D

Eye Champagne:
Code: QB64: [Select]
  1. _TITLE "Cresent Pattern in Cog Layout" 'b+ 2019-06-29 using part of Petr's mod and Steve's cog idea, I mod again
  2. CONST xmax = 800, ymax = 600, pi = 3.14159265
  3. SCREEN _NEWIMAGE(xmax, ymax, 32)
  4. _SCREENMOVE 300, 40
  5. DIM SHARED clr, r, g, b
  6. DIM Frames(35) AS LONG, CreateFrames AS INTEGER, x, y, aof, f AS INTEGER, yAlt, xAlt, i
  7.  
  8. FOR CreateFrames = 0 TO 35
  9.     Frames(CreateFrames) = _NEWIMAGE(101, 101, 32)
  10.     _DEST Frames(CreateFrames)
  11.     CLS
  12.     'aof = 0 'ALL Stop   to view fill: hey that's a darn good fill!!!!
  13.     aof = aof + pi / 18
  14.     crescentLFCA 50, 50, 50, aof
  15.     _CLEARCOLOR &HFF000000
  16.  
  17. COLOR , &HFFFFFFFF
  18.     FOR i = 0 TO xmax
  19.         chColor
  20.         LINE (i, 0)-(i, ymax)
  21.     NEXT
  22.     f = (f + 1) MOD 36
  23.     FOR y = 0 TO ymax - 100 STEP 100
  24.         yAlt = (yAlt + 1) MOD 2
  25.         xAlt = yAlt
  26.         FOR x = 0 TO xmax - 100 STEP 200
  27.             IF xAlt THEN
  28.                 _PUTIMAGE (x, y)-STEP(100, 100), Frames(f), 0, (0, 0)-(100, 100)
  29.                 _PUTIMAGE (x + 100, y)-STEP(100, 100), Frames(f), 0, (100, 0)-(0, 100)
  30.             ELSE
  31.                 _PUTIMAGE (x, y)-STEP(100, 100), Frames(f), 0, (100, 0)-(0, 100)
  32.                 _PUTIMAGE (x + 100, y)-STEP(100, 100), Frames(f), 0, (0, 0)-(100, 100)
  33.             END IF
  34.         NEXT
  35.     NEXT
  36.     _DISPLAY
  37.     _LIMIT 10
  38.  
  39. 'cresecent Line Filled Circular Arcs  combines arc drawing sub with crescentPattern sub
  40. SUB crescentLFCA (x0, y0, r6, aoff) 'r6 is radius of 6 crescent pattern
  41.     DIM a12, r1, a6, x6, y6, x6m12, y6m12, i, al, a, x1, y1, x2, y2, c~&
  42.     r1 = r6 / 2 ' the radius of each crescent
  43.     a12 = 2 * pi / 12 ' 30 degrees to draw 12 arcs about x0, y0
  44.     a6 = 2 * pi / 6
  45.     al = _PI * r1 * r1 * (pi + pi / 6) / _PI(2) '<<<<<<<<<<<<<<<< this needs to be calc only once
  46.     FOR i = 1 TO 6 'draw 6 crescents find x, y of leading and trailing edges
  47.         x6 = x0 + r1 * COS(i * a6 + aoff): y6 = y0 + r1 * SIN(i * a6 + aoff) 'origins of leading edges
  48.         x6m12 = x0 + r1 * COS(i * a6 - a12 + aoff): y6m12 = y0 + r1 * SIN(i * a6 - a12 + aoff) 'origins of trailing edges
  49.         FOR a = (i * a6 + aoff - pi / 6) TO (i * a6 + aoff + pi) STEP 1 / al 'draw arc chords for dist a
  50.             x1 = x6 + r1 * COS(a): y1 = y6 + r1 * SIN(a) ' point on leading edge
  51.             x2 = x6m12 + r1 * COS(a): y2 = y6m12 + r1 * SIN(a) 'eqivalent point on trailing edge
  52.             IF i MOD 3 = 0 THEN
  53.                 c~& = &HFF990000
  54.             ELSEIF i MOD 3 = 1 THEN
  55.                 c~& = &HFF008800
  56.             ELSEIF i MOD 3 = 2 THEN
  57.                 c~& = &HFF000099
  58.             END IF
  59.             LINE (x1, y1)-(x2, y2), c~&
  60.         NEXT
  61.     NEXT
  62.  
  63. SUB chColor ()
  64.     IF r = 0 THEN r = RND * 255
  65.     IF g = 0 THEN g = RND * 255
  66.     IF b = 0 THEN b = RND * 255
  67.     clr = clr + .3
  68.     COLOR _RGB32(127 + 127 * SIN(r * clr), 127 + 127 * SIN(g * clr), 127 + 127 * SIN(b * clr))
  69.     IF clr > 40000 THEN r = RND: g = RND: b = RND: clr = 0
  70.  
  71.  
« Last Edit: June 29, 2019, 04:34:28 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Cresent Pattern Challenge from JB
« Reply #34 on: June 29, 2019, 07:52:13 pm »
Hi _vince,

I got as far as I could translating your algo to QB64. First I had to cut down screen size and scale radius.
Then replace CIRCLE commands with my Arc code because kept getting illegal calls with CIRCLE.
Then to get a decent draw I had to change sign on y coordinate as noted below.
OK got a hexagonal shape of twirls but! they are misaligned a bit, the crescents are at wrong angles for nice draw.
Then go to PAINT and the PAINT points all fit in crescents but the first is drawn outside the crescent drawn causing paint to paint entire the screen.

I think there is just one angle that needs fixing so everything lines up correctly.

Code: QB64: [Select]
  1. _TITLE "Cresent Pattern in Hexagon Layout" 'b+ translated algo 2019-06-29
  2.  
  3. CONST sw = 1068, sh = 600, pi = 3.14159265
  4. SCREEN _NEWIMAGE(sw, sh, 32)
  5. _SCREENMOVE 300, 40
  6.  
  7. 'sw = 1920     ' 1.78 ratio 600 X 1.78 = 1068
  8. 'sh = 1080
  9.  
  10. 'fill in
  11. DIM xx, yy, a, b, c, r, i AS INTEGER, x, y, j AS INTEGER, p, q, rr, k AS INTEGER, u
  12.  
  13. xx = sw / 2
  14. yy = sh / 2
  15. a = pi / 2 - pi / 4 - pi / 15 + 0.05 - 0.15
  16. b = pi / 6
  17. c = 0.2
  18. r = 100 / 1.78
  19.  
  20. FOR i = 0 TO 5
  21.     x = xx + 2 * r * COS(i * pi / 3 + c)
  22.     y = yy + 2 * r * SIN(i * pi / 3 + c)
  23.     FOR j = 0 TO 5
  24.         p = x + 2 * r * COS(j * pi / 3 + c)
  25.         q = y + 2 * r * SIN(j * pi / 3 + c)
  26.  
  27.         rr = 1.03 * r
  28.         FOR k = 0 TO 5
  29.             u = k * pi / 3 + a
  30.  
  31.             ' In next lines I change  y coordinate  q - ... to q + ... or get crap!
  32.             arc p + 0.5 * rr * COS(u), q + 0.5 * rr * SIN(u), 0.5 * rr, u + b, u + pi, &HFF0000FF
  33.             arc p + 0.5 * rr * COS(u + b), q + 0.5 * rr * SIN(u + b), 0.5 * rr, u, u + pi + b, &HFF0000FF
  34.  
  35.             'test paint points oops they are all outside the last drawn crescent!
  36.             CIRCLE (p + 0.5 * rr * COS(u + 0.2), q + 0.5 * rr * SIN(u + 0.2)), 2 'test point
  37.             'PAINT (p + 0.5 * rr * COS(u + 0.2), q + 0.5 * rr * SIN(u + 0.2)), &HFFFFFFFF, &HFF0000FF
  38.             _DELAY 2
  39.  
  40.  
  41.         NEXT
  42.     NEXT
  43.  
  44. SUB arc (x, y, r, raStart, raStop, c AS _UNSIGNED LONG)
  45.     'x, y origin, r = radius, c = color
  46.  
  47.     'raStart is first angle clockwise from due East = 0 degrees
  48.     ' arc will start drawing there and clockwise until raStop angle reached
  49.  
  50.     DIM al, a
  51.     IF raStop < raStart THEN
  52.         arc x, y, r, raStart, _PI(2), c
  53.         arc x, y, r, 0, raStop, c
  54.     ELSE
  55.         ' modified to easier way suggested by Steve
  56.         'Why was the line method not good? I forgot.
  57.         al = _PI * r * r * (raStop - raStart) / _PI(2)
  58.         FOR a = raStart TO raStop STEP 1 / al
  59.             PSET (x + r * COS(a), y + r * SIN(a)), c
  60.         NEXT
  61.     END IF
  62.  

I think you can find the angle faster than I.

This gave me idea how to layout a Hexagon pattern though! :-)
« Last Edit: June 30, 2019, 10:02:04 am by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Cresent Pattern Challenge from JB
« Reply #35 on: June 29, 2019, 10:46:45 pm »
OK Tricolor Crescent Pattern on slightly tilted Hexagonal Layout:

Code: QB64: [Select]
  1. _TITLE "Crescent LFCA Hexagonal Layout" 'b+ 2019-06-29   LFCA = Lined Filled Circular Arcs
  2. CONST xmax = 800, ymax = 600, pi = 3.14159265
  3. SCREEN _NEWIMAGE(xmax, ymax, 32)
  4.  
  5. TYPE xy
  6.     x AS INTEGER
  7.     y AS INTEGER
  8. DIM h(45) AS xy, tilt, hex, x0, y0, a, i, r, j, k, cnt
  9. r = 50
  10. tilt = -pi / 8 'looks to match original challenge
  11. hex = 2 * pi / 6
  12. x0 = xmax / 2
  13. y0 = ymax / 2
  14. FOR a = tilt TO 2 * pi STEP hex
  15.     h(i).x = x0 + 2 * r * COS(a)
  16.     h(i).y = y0 + 2 * r * SIN(a)
  17.     i = i + 1
  18. FOR k = 0 TO i - 1
  19.     'PRINT k, h(k).x, h(k).y
  20.     CIRCLE (h(k).x, h(k).y), 2
  21. FOR j = 0 TO 5
  22.     FOR a = tilt TO 2 * pi - tilt - 1 STEP hex
  23.         h(i).x = h(j).x + 2 * r * COS(a)
  24.         h(i).y = h(j).y + 2 * r * SIN(a)
  25.         'PRINT i, h(i).x, h(i).y
  26.         CIRCLE (h(i).x, h(i).y), 4
  27.         i = i + 1
  28.     NEXT
  29. i = i - 1
  30. FOR j = 0 TO i - 1
  31.     FOR k = j + 1 TO i
  32.         IF h(j).x THEN
  33.             IF h(j).x = h(k).x AND h(j).y = h(k).y THEN h(k).x = 0
  34.         END IF
  35.     NEXT
  36. COLOR , &HFFFFFFFF
  37. FOR j = 0 TO i
  38.     IF h(j).x <> 0 THEN cnt = cnt + 1: PRINT h(j).x, h(j).y: crescentLFCA h(j).x, h(j).y, r, -3 * tilt
  39. PRINT "n pts = "; cnt
  40.  
  41. 'cresecent Line Filled Circular Arcs  combines arc drawing sub with crescentPattern sub
  42. SUB crescentLFCA (x0, y0, r6, aoff) 'r6 is radius of 6 crescent pattern
  43.     DIM a12, r1, a6, x6, y6, x6m12, y6m12, i, al, a, x1, y1, x2, y2, c~&
  44.     r1 = r6 / 2 ' the radius of each crescent
  45.     a12 = 2 * pi / 12 ' 30 degrees to draw 12 arcs about x0, y0
  46.     a6 = 2 * pi / 6
  47.     al = 10 * _PI * r1 * r1 * (pi + pi / 6) / _PI(2)
  48.     FOR i = 1 TO 6 'draw 6 crescents find x, y of leading and trailing edges
  49.         x6 = x0 + r1 * COS(i * a6 + aoff): y6 = y0 + r1 * SIN(i * a6 + aoff) 'origins of leading edges
  50.         x6m12 = x0 + r1 * COS(i * a6 - a12 + aoff): y6m12 = y0 + r1 * SIN(i * a6 - a12 + aoff) 'origins of trailing edges
  51.         FOR a = (i * a6 + aoff - pi / 6) TO (i * a6 + aoff + pi) STEP 1 / al 'draw arc chords for dist a
  52.             x1 = x6 + r1 * COS(a): y1 = y6 + r1 * SIN(a) ' point on leading edge
  53.             x2 = x6m12 + r1 * COS(a): y2 = y6m12 + r1 * SIN(a) 'eqivalent point on trailing edge
  54.             IF i MOD 3 = 0 THEN
  55.                 c~& = &HFF990000
  56.             ELSEIF i MOD 3 = 1 THEN
  57.                 c~& = &HFF008800
  58.             ELSEIF i MOD 3 = 2 THEN
  59.                 c~& = &HFF000099
  60.             END IF
  61.             LINE (x1, y1)-(x2, y2), c~&
  62.         NEXT
  63.     NEXT
  64.  

The angles of tilt were eyeballed but turns out it was about -pi/8 then I had to turn the crescent patterns until they matched up at the nice round number of -3*tilt.
« Last Edit: June 30, 2019, 10:05:24 am by bplus »

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: Cresent Pattern Challenge from JB
« Reply #36 on: June 30, 2019, 08:36:16 pm »
Nice work bplus, that's pretty much it.  I think the way the original image has them interconnected is by giving the arcs a radius slightly larger than half the radius of the invisible circle within which they're embedded, which explains the rr = 1.01*r line in my code but in yours it looks like you connected them with a thin rectangle.  Anyways, I think we've beaten this pattern to death, lets find more!