Author Topic: Impossible Expanding Graphics  (Read 6397 times)

0 Members and 1 Guest are viewing this topic.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Impossible Expanding Graphics
« on: January 23, 2022, 06:04:03 am »
@bplus and several other folks all like playing around with graphics a lot, so I thought I'd have a little fun and write a simple little graphic program to see who can sort out how the magic here works.

Here's the program:
Code: QB64: [Select]
  1. Screen _NewImage(1000, 1000, 32)
  2. Cls , -1
  3.  
  4. Circle (400, 400), 80, &HFF000000
  5. Paint (400, 400), &HFF000000
  6. Circle (400, 600), 80, &HFF000000
  7. Paint (400, 600), &HFF000000
  8. Circle (600, 600), 80, &HFF000000
  9. Paint (600, 600), &HFF000000
  10. Circle (600, 400), 80, &HFF000000
  11. Paint (600, 400), &HFF000000
  12. Circle (400, 400), 80, &HFF000000
  13. Paint (400, 400), &HFF000000
  14. Line (499, 300)-(501, 700), &HFF000000, B
  15. Line (400, 400)-(600, 600), -1, BF
  16.  
  17.     _PutImage (1000, 1000)-(0, 0) 'flip the bottom to the top
  18.     _Display
  19.     _Limit 30
  20.  

What this does is draw a simple little pattern on the screen for us, and then the DO...LOOP flips that pattern repeatedly from bottom to top, basically mirroring it for us.

And yet...

Something *magical* happens with this simple little patch of mirror code!!

Who wants to explain how it's doing what it's doing here?  I'm not giving any hints, and I encourage folks not to read anyone else's responses until they have a chance to try this out and see if they can sort out what's happening here on their own.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Impossible Expanding Graphics
« Reply #1 on: January 23, 2022, 10:00:48 am »
Related to the first program above, but a little more subtle, I present the Impossible Twitching Screen!

This little snippet is a graphical routine which causes my eyeballs to twitch and bug out if I stare at it for a while.

Code: QB64: [Select]
  1. Screen _NewImage(1000, 1000, 32)
  2. Cls , -1
  3. For i = 800 To 0 Step -100
  4.     If i Mod 200 = 0 Then
  5.         Circle (500, 500), i, &HFFFF0000
  6.         Paint (500, 500), &HFFFF0000
  7.     Else
  8.         Circle (500, 500), i, &HFFFFFF00
  9.         Paint (500, 500), &HFFFFFF00
  10.     End If
  11. Circle (400, 400), 80, &HFF000000
  12. Paint (400, 400), &HFF000000
  13. Circle (400, 600), 80, &HFF000000
  14. Paint (400, 600), &HFF000000
  15. Circle (600, 600), 80, &HFF000000
  16. Paint (600, 600), &HFF000000
  17. Circle (600, 400), 80, &HFF000000
  18. Paint (600, 400), &HFF000000
  19. Circle (400, 400), 80, &HFF000000
  20. Paint (400, 400), &HFF000000
  21. Line (499, 300)-(501, 700), &HFF000000, B
  22. Line (400, 400)-(600, 600), -1, BF
  23.  
  24.     _PutImage (999, 999)-(0, 0) 'mirror the image
  25.     _Limit 60
  26.     _Display
  27.  

Now, this draws us a perfectly symmetrical image on the screen.  Up, down, left, right, this image is a mirror of itself.

So, somebody explain WHY it appears that this image "twitches" on us, when we mirror it upon itself!

There's some sort of optical illusion going on here, with the way our eyes pick up the colors and such of the screen, which makes it seem as if its jerking slightly, while in reality its not.  Unless it really is, and I've got something off and my screen isn't truly symmetrical... 

Anyone with a fresh set of eyes want to see what (if anything) I've got wrong here to cause this insufferable twitching?

Is this a patented Steve Glitch(tm), or just something with the display, refresh rate, and a human's eyeballs?
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Impossible Expanding Graphics
« Reply #2 on: January 23, 2022, 10:13:57 am »
hmm... @SMcNeill your scrren height is beyond the limits of my little laptop so I convert your code to 500 X 500 Screen and use Widow so I can use same code as you, I get no effect.
See for yourself:
Code: QB64: [Select]
  1. Screen _NewImage(500, 500, 32)
  2. Window (0, 0)-(1000, 1000)
  3. Cls , -1
  4.  
  5. Circle (400, 400), 80, &HFF000000
  6. Paint (400, 400), &HFF000000
  7. Circle (400, 600), 80, &HFF000000
  8. Paint (400, 600), &HFF000000
  9. Circle (600, 600), 80, &HFF000000
  10. Paint (600, 600), &HFF000000
  11. Circle (600, 400), 80, &HFF000000
  12. Paint (600, 400), &HFF000000
  13. Circle (400, 400), 80, &HFF000000
  14. Paint (400, 400), &HFF000000
  15. Line (499, 300)-(501, 700), &HFF000000, B
  16. Line (400, 400)-(600, 600), -1, BF
  17.  
  18.     _PutImage (1000, 1000)-(0, 0) 'flip the bottom to the top
  19.     _Display
  20.     _Limit 30
  21.  
  22.  

So fine I check for difference and run your code as is, it does magically expand. It's a mystery alright, why does my use of Window ruin the magic?

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Impossible Expanding Graphics
« Reply #3 on: January 23, 2022, 10:22:57 am »
Oh I see, this makes it magically shrink
Code: QB64: [Select]
  1. Screen _NewImage(1000, 1000, 32)
  2. Cls , -1
  3.  
  4. Circle (400, 400), 80, &HFF000000
  5. Paint (400, 400), &HFF000000
  6. Circle (400, 600), 80, &HFF000000
  7. Paint (400, 600), &HFF000000
  8. Circle (600, 600), 80, &HFF000000
  9. Paint (600, 600), &HFF000000
  10. Circle (600, 400), 80, &HFF000000
  11. Paint (600, 400), &HFF000000
  12. Circle (400, 400), 80, &HFF000000
  13. Paint (400, 400), &HFF000000
  14. Line (499, 300)-(501, 700), &HFF000000, B
  15. Line (400, 400)-(600, 600), -1, BF
  16.  
  17.  
  18.     _PutImage (998, 998)-(0, 0) 'flip the bottom to the top
  19.     _Display
  20.     _Limit 30

And this makes it magically wobble,
Code: QB64: [Select]
  1. Screen _NewImage(1000, 1000, 32)
  2. Cls , -1
  3.  
  4. Circle (400, 400), 80, &HFF000000
  5. Paint (400, 400), &HFF000000
  6. Circle (400, 600), 80, &HFF000000
  7. Paint (400, 600), &HFF000000
  8. Circle (600, 600), 80, &HFF000000
  9. Paint (600, 600), &HFF000000
  10. Circle (600, 400), 80, &HFF000000
  11. Paint (600, 400), &HFF000000
  12. Circle (400, 400), 80, &HFF000000
  13. Paint (400, 400), &HFF000000
  14. Line (499, 300)-(501, 700), &HFF000000, B
  15. Line (400, 400)-(600, 600), -1, BF
  16.  
  17.  
  18.     _PutImage (999, 999)-(0, 0) 'flip the bottom to the top
  19.     _Display
  20.     _Limit 30
  21.  


Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Impossible Expanding Graphics
« Reply #4 on: January 23, 2022, 10:23:34 am »
Clearly you are programing near a fault line.

Failing that, the image is not perfectly symmetrical as it's constantly moving on each flip. Perhaps it the difference between the Screen declaration and the display co-ordinates being slightly out of symmetry.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Impossible Expanding Graphics
« Reply #5 on: January 23, 2022, 10:30:29 am »
Ding Dong the twitch is dead!
Code: QB64: [Select]
  1. Screen _NewImage(1000, 1000, 32)
  2. Cls , -1
  3. For i = 800 To 0 Step -100
  4.     If i Mod 200 = 0 Then
  5.         Circle (500, 500), i, &HFFFF0000
  6.         Paint (500, 500), &HFFFF0000
  7.     Else
  8.         Circle (500, 500), i, &HFFFFFF00
  9.         Paint (500, 500), &HFFFFFF00
  10.     End If
  11. Circle (400, 400), 80, &HFF000000
  12. Paint (400, 400), &HFF000000
  13. Circle (400, 600), 80, &HFF000000
  14. Paint (400, 600), &HFF000000
  15. Circle (600, 600), 80, &HFF000000
  16. Paint (600, 600), &HFF000000
  17. Circle (600, 400), 80, &HFF000000
  18. Paint (600, 400), &HFF000000
  19. Circle (400, 400), 80, &HFF000000
  20. Paint (400, 400), &HFF000000
  21. Line (499, 300)-(501, 700), &HFF000000, B
  22. Line (400, 400)-(600, 600), -1, BF
  23.  
  24.     _PutImage (999, 999)-(0, 0), 0, 0, (1, 1)-(1000, 1000) 'mirror the image
  25.     _Limit 60
  26.     _Display
  27.  
  28.  

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Impossible Expanding Graphics
« Reply #6 on: January 23, 2022, 10:52:28 am »
Ding Dong the twitch is dead!
Code: QB64: [Select]
  1. Screen _NewImage(1000, 1000, 32)
  2. Cls , -1
  3. For i = 800 To 0 Step -100
  4.     If i Mod 200 = 0 Then
  5.         Circle (500, 500), i, &HFFFF0000
  6.         Paint (500, 500), &HFFFF0000
  7.     Else
  8.         Circle (500, 500), i, &HFFFFFF00
  9.         Paint (500, 500), &HFFFFFF00
  10.     End If
  11. Circle (400, 400), 80, &HFF000000
  12. Paint (400, 400), &HFF000000
  13. Circle (400, 600), 80, &HFF000000
  14. Paint (400, 600), &HFF000000
  15. Circle (600, 600), 80, &HFF000000
  16. Paint (600, 600), &HFF000000
  17. Circle (600, 400), 80, &HFF000000
  18. Paint (600, 400), &HFF000000
  19. Circle (400, 400), 80, &HFF000000
  20. Paint (400, 400), &HFF000000
  21. Line (499, 300)-(501, 700), &HFF000000, B
  22. Line (400, 400)-(600, 600), -1, BF
  23.  
  24.     _PutImage (999, 999)-(0, 0), 0, 0, (1, 1)-(1000, 1000) 'mirror the image
  25.     _Limit 60
  26.     _Display
  27.  
  28.  

The problem here is you're putting the image off the screen.  There is no point (1000,1000).  😱

The issue, in all honesty, is that there is NO center of the screen.  No even pixel screen has a "perfect center".   For example, which pixel is the center of my 2x2 "screen of X's" below?

XX
XX

Now, with a 3x3 screen, we have a perfect center:

XXX
XOX
XXX

But with an even number of pixels??  It doesn't exist!



For our expanding screen, the issue is with us going beyond the screen limits.  Our _NEWIMAGE is (1000, 1000, 32), but our screen limits are from (0,0) to (999,999).  By trying to copy from (0,0) to (1000,1000), we're blowing up the screen.

As Richard so elegantly mentioned: "When you put 1000 pickles into a barrel made to hold 999, vinegar spills over!"



And our twitch?

Same style common misconception.  With a screen 1000x1000 pixels, the point (500, 500) is NOT the perfect center of the screen.  It's half a pixel off, which rounds to being a whole pixel off-center.

My symmetrical image truly isn't symmetrical, and mirroring it repeatedly easily highlights that with the twitch.



As to why WINDOW works for you without expanding??

You made a 1001x1001 coordinate system and 1000,1000 wasn't off screen. (0,0) to (1000,1000). 



Simple little truths about graphics which folks either never learned, or else forgot.  I got a message from someone wanting help with something very similar to this, so I thought I'd share for everyone else to play around with the issue some.  ;)

Honestly, I think it's this "non-center" that has OpenGL and all use a different coordinate system with (0,0) as the center of the screen and then you go left/right, up/down from there.  I just thought it'd be something worth pointing out while it was fresh in my mind.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Impossible Expanding Graphics
« Reply #7 on: January 23, 2022, 01:01:43 pm »
@SMcNeill As per your command, I haven't looked at anybody else's replies & I tried the code from your initial post.  Things expand gradually.  So you think "why should that happen?".

Then you observe that the expansion is 1 pixel per cycle in x- and y-.  The _PUTIMAGE is (1000,1000)-(0,0).  The (1000,1000) co-ordinates are 1 pixel bigger than the screen.  If you change the _PUTIMAGE to (999,999)-(0,0), the image (flickers a little) and stays where it is.  Just a Steve exercise is noting the _PUTIMAGE co-ordinates are 0 to _NEWIMAGE(upper values minus 1).

QED!  Qwerkey to go to the top of the class!???

After being marked by teacher McNeill, I'll read bplus's replies (doubtless will put mine to shame).


Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Impossible Expanding Graphics
« Reply #8 on: January 23, 2022, 01:13:10 pm »
I think it is a great point to share. Maybe 2 points:
1. even widths or heights have no middle pixel which might explain unsatisfactory results I get from RotoZoom occasionally, which needs a middle point to rotate around.
2.  More basic, _Width and _Height are one pixel more than what can be shown on screen because base 0
eg pset(_width, _height)  is never seen on screen. I made this mistake early on and still forget at times.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Impossible Expanding Graphics
« Reply #9 on: January 23, 2022, 01:57:10 pm »
EDIT: Correction test even and odd widths for screen and pixel counts for each side of middle x, of x axis
Code: QB64: [Select]
  1. _Title "where is the middle of a screen"
  2. ' so you have same amount of pixels on either side
  3.  
  4. Const SW = 1024, SH = 720 ' try odd and even screen _width and _height settings
  5. Screen _NewImage(SW, SH, 32)
  6. _ScreenMove 150, 10
  7. midX = Int((_Width - 1) / 2): midY = Int((_Height - 1) / 2)
  8. Print "middle?"; midX, midY
  9. Print " x pixels on right and on left of middle:"; (midX - 1) - 0, _Width - 1 - (midX + 1)
  10.  
  11.  
  12. PSet (SW, SH) ' NO SEE !!!
  13. 'PSet (SW - 1, SH - 1) ' see!!!
  14.  
  15.  


crazy base 0 ;-))
« Last Edit: January 23, 2022, 02:31:10 pm by bplus »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Impossible Expanding Graphics
« Reply #10 on: January 23, 2022, 02:01:24 pm »
@SMcNeill As per your command, I haven't looked at anybody else's replies & I tried the code from your initial post.  Things expand gradually.  So you think "why should that happen?".

Then you observe that the expansion is 1 pixel per cycle in x- and y-.  The _PUTIMAGE is (1000,1000)-(0,0).  The (1000,1000) co-ordinates are 1 pixel bigger than the screen.  If you change the _PUTIMAGE to (999,999)-(0,0), the image (flickers a little) and stays where it is.  Just a Steve exercise is noting the _PUTIMAGE co-ordinates are 0 to _NEWIMAGE(upper values minus 1).

QED!  Qwerkey to go to the top of the class!???

After being marked by teacher McNeill, I'll read bplus's replies (doubtless will put mine to shame).

@Qwerkey -- Spot on!  Even though the screen is 1000x1000 in size, the coordinates go from 0 to 999.  By using PutImage to point 1000,1000, we're stretching the screen every time we copy it.  This stretch leads to the ever expanding graphics that we see in the first demo.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: Impossible Expanding Graphics
« Reply #11 on: January 23, 2022, 02:09:52 pm »
Bplus,

That is a very good simulation. When we were kids, our parents would determine that we had watched enough Television for the day, then turned it off. We would sit there and watch the screen's glow reduce to a single point on the screen's centre... Just like your image! Many thanks for the memories! Much appreciated!
Logic is the beginning of wisdom.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Impossible Expanding Graphics
« Reply #12 on: January 23, 2022, 02:13:23 pm »
Correction Even Widths and Heights set in _NewImage do have middles:
Code: QB64: [Select]
  1. Const SW = 1024, SH = 720
  2. Screen _NewImage(SW, SH, 32)
  3. _ScreenMove 150, 10
  4. Print "middle?"; _Width / 2, _Height / 2
  5. PSet (Int(_Width / 2) - 1, Int(_Height / 2) - 1), &HFFFF0000
  6. PSet (_Width / 2, _Height / 2), &HFF008000
  7. PSet (Int(_Width / 2) + 1, Int(_Height / 2) + 1), &HFF0000FF
  8.  
  9. 'see 3 points? in diagonal   then screen has middle
  10.  
  11. PSet (SW, SH) ' NO SEE !!!
  12. 'PSet (SW - 1, SH - 1) ' see!!!
  13.  
  14.  


crazy base 0 ;-))

Your math will give you a midpoint, but it's not truly centered.

For example:  _NEWIMAGE(4,4,32) as represented by X's below:

XXXX
XXXX
XXXX
XXXX

Now center is _WIDTH / 2, _HEIGHT / 2, or point 2,2:


-0123
0XXXX
1XXXX
2Xx@X
3XXXX


Now, as you can see, our little @ is off-center in the screen

For a 4 by 4 screen, our coordinates go from 0 to 3, 0 to 3.  Perfect center would be at point 1.5, 1.5 -- but we don't have a point (1.5, 1.5)!  Rounding is always going to bring us *close* to center but slightly off center.

If you're going to draw a circle on the screen, and need perfect symmetry of your image, make your screen an odd size.  Otherwise mirroring and such effects are going to be off as there's no singular point you can designate to be the "perfect center".
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Impossible Expanding Graphics
« Reply #13 on: January 23, 2022, 02:32:31 pm »
EDIT: Never mind, I corrected my previous post.
« Last Edit: January 23, 2022, 02:38:16 pm by bplus »

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: Impossible Expanding Graphics
« Reply #14 on: January 23, 2022, 02:42:52 pm »
Another nice teaching tidbit... would love to see it in our Learning or Samples for posterity.