Posts: 323
Threads: 46
Joined: Apr 2022
Reputation:
11
08-14-2022, 02:19 AM
(This post was last modified: 08-14-2022, 02:19 AM by SierraKen.)
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.
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
Posts: 263
Threads: 14
Joined: Apr 2022
Reputation:
23
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:
Posts: 1,507
Threads: 160
Joined: Apr 2022
Reputation:
116
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) ' *
' ***
'*****
' ***
' *
Posts: 263
Threads: 14
Joined: Apr 2022
Reputation:
23
(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?
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:
Posts: 323
Threads: 46
Joined: Apr 2022
Reputation:
11
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.
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
Posts: 323
Threads: 46
Joined: Apr 2022
Reputation:
11
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!
Posts: 263
Threads: 14
Joined: Apr 2022
Reputation:
23
(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:
Posts: 2,700
Threads: 124
Joined: Apr 2022
Reputation:
134
08-15-2022, 12:09 AM
(This post was last modified: 08-15-2022, 12:30 AM by bplus.)
Should we suggest fat diamonds and skinny diamonds? Just a step away literally!
Hey I'd like _ATan2 ;-))
b = b + ...
Posts: 2,700
Threads: 124
Joined: Apr 2022
Reputation:
134
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 + ...
Posts: 263
Threads: 14
Joined: Apr 2022
Reputation:
23
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:
|