Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to fill-in a diamond without PAINT
#1
After trial and error, I figured out a way to make filled-in diamonds using the LINE command and loops and without PAINT. I'm going to add this in my Explorer game.

If anyone needs this, you can use this code. Feel free to make it any size, shape, whatever. Smile 

Code: (Select All)
Screen _NewImage(800, 600, 32)
x = 400
y = 300
For xx = 0 To 20 Step .25
    Line (x + xx, y + xx)-(x - xx, y + xx)
Next xx
For yy = 20 To 0 Step -.25
    Line (x + yy, y - yy + 40)-(x - yy, y - yy + 40)
Next yy
Reply
#2
That's cool, it's reminiscent of Steve's circle fill algorithm.

I was playing with it a bit and came up with a few optimizations and observations.

Code: (Select All)
SCREEN _NEWIMAGE(800, 600, 32)
x = 400
y = 300
s = 20
FOR xx = 0 TO s STEP .25
    yy = s - xx
    LINE (x + xx, y + xx)-(x - xx, y + xx)
    LINE (x + yy, y - yy + _SHL(s, 1))-(x - yy, y - yy + _SHL(s, 1))
    'SLEEP
NEXT xx

Substituting 's' for 20 makes it a snap to change the size. Adding yy = s - xx, and moving the second line command into the first iteration, eliminates the entire second reversed iteration.

Also, try running it with the SLEEP command enabled and watch the action. The quarter stepping means that the loop will run 4 times for each time anything is drawn, since the drawing only advances on whole integers. Then comment out the STEP .25, with sleep still enabled, and watch the action. My testing so far indicates the quarter stepping is unnecessary for the end result and just adds processing time.

The sleep trick was how I figured out how Steve's circle fill routine worked, so when I tried it here, it revealed the extra cycles.

It would make a great little SUB that you can send position and size parameters (or even color) to, and throw them up anywhere on the screen.
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Reply
#3
Wouldn't a diamond be just a line in the middle, then a line 2 pixels smaller above and below, until it reachs less than 2 pixels?

Code: (Select All)
'  *
' ***
'*****
' ***
'  *
Reply
#4
(08-14-2022, 05:39 PM)SMcNeill Wrote: Wouldn't a diamond be just a line in the middle, then a line 2 pixels smaller above and below, until it reachs less than 2 pixels?

Well....yes, but where's the fun in that? Big Grin

Code: (Select All)
SCREEN _NEWIMAGE(800, 600, 32)
x = 200
y = 200
s = 100: s1 = _SHR(s, 1): s2 = s1
DO
    LINE (x - s1, y - (s2 - s1))-(x + s1, y - (s2 - s1))
    LINE (x - s1, y + (s2 - s1))-(x + s1, y + (s2 - s1))
    s1 = s1 - 1
LOOP UNTIL s1 < 0
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Reply
#5
Thanks for telling me about the not-needed .25. I was just so used to filling in circles that way. Here is my updated version. I haven't tried yours yet. I also changed 2 variable names to make it clearer. Plus I took your size variable idea and made it into mine. Smile 

Code: (Select All)
Screen _NewImage(800, 600, 32)
x = 400
y = 300
size = 100

For a = 0 To size / 2
    Line (x + a, y + a)-(x - a, y + a)
Next a
For b = size / 2 To 0 Step -1
    Line (x + b, y - b + size)-(x - b, y - b + size)
Next b
Reply
#6
I have no idea what "bit shifting" means, except that the Wiki page says it divides it by 2 faster. Oh well, I try not to use things I don't understand unless I have to. But still interesting!
Reply
#7
(08-14-2022, 07:38 PM)SierraKen Wrote: I have no idea what "bit shifting" means, except that the Wiki page says it divides it by 2 faster. Oh well, I try not to use things I don't understand unless I have to. But still interesting!

I don't think many people use bit shifting that often, it is a tad incomprehensible, and it's really only useful where there's an integer with an even power of two. It just happened to be ok for a diamond with a size of 20.

_SHR(variable%, x%) will divide variable% by 2 ^ x%, dropping fractions
_SHL (variable%, x%) will multiply variable% by 2 ^ x%,

I do it just to get used to it, really, for the eventual day where it actually might save some processor time in a fast application. It doesn't do well for precision division because, like an integer, it drops fractional results since it won't preserve overflow bits. I like it for dividing a screen into halves, quarters, eighths, etc., or for converting between LOCATE positions and _PRINTSTRING positions. In those cases one pixel one way or the other doesn't make a big difference on most screens and there isn't a half pixel anyway. You don't need it for most stuff, but it's cool to know it.

Example:
a% = 15 '                            in binary that's a% = &B0000000000001111   (big endian form here for clarity)

b% = _SHL(a%, 1) '            shifting a% one bit to the left, b% = &B0000000000011110  or b% = 30

c% = _SHR(a%, 1) '            shifting a% one bit to the right, c% = &B0000000000000111 or c% = 7

If you shift around a lot without care, you lose precision quickly, for example:
Code: (Select All)
a% = 15
PRINT a%
b% = _SHR(a%, 1)
PRINT b%
c% = _SHL(b%, 1)
PRINT c%


If I want to put something a quarter of the way across a screen width I would do _SHR(_WIDTH(0), 2) for an X position, which is the same as  _WIDTH(0) / 4
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Reply
#8
Should we suggest fat diamonds and skinny diamonds? Just a step away literally!

Hey I'd like _ATan2 ;-))
b = b + ...
Reply
#9
OK here is my hat in the ring:
Code: (Select All)
_Title "test diamond" 'b+ 2022-08-14
Randomize Timer
Screen _NewImage(800, 600, 32)
drawDiamond 400, 300, 200, 400, &HFF990000
Print "press any to see a diamond mine!"
Sleep
Cls
While _KeyDown(27) = 0
    drawDiamond Rnd * 800, Rnd * 600, Rnd * 100, Rnd * 100, _RGB32(Rnd * 255, Rnd * 255, Rnd * 255)
    _Display
    _Limit 30
Wend

Sub drawDiamond (x, y, w, h, K As _Unsigned Long)
    For xx = 0 To w / 2
        yy = h / 2 - h / w * xx
        Line (x + xx, y + yy)-Step(0, -2 * yy), K
        Line (x - xx, y + yy)-Step(0, -2 * yy), K
    Next
End Sub
b = b + ...
Reply
#10
Ahhh, I was wondering what you meant by "step away", and I was thinking you were going to do something with the for..next loop. I forgot about using step in the line command. A very cool solution.
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Reply




Users browsing this thread: 1 Guest(s)