Author Topic: POINT() gives odd output  (Read 488 times)

lettersquash

  • Newcomer
  • *
  • Posts: 13
    • View Profile
POINT() gives odd output
« on: 18. February 2019, 03:03:08 »
I've been testing colours with POINT(x,y) and got some curious results. If I draw with rgb(255,0,0) and get p = point(x,y), then ? hex(-p) gives FF. With the full blue byte, the same ? hex(-p) gives FF0000.

Is this a bug or am I misunderstanding something?

chrisws

  • Moderator
  • Newcomer
  • *****
  • Posts: 32
    • View Profile
Re: POINT() gives odd output
« Reply #1 on: 18. February 2019, 10:44:08 »
Both POINT and RGB return negative values to dis-disambiguate from the colour constants 0-15. So you just need to compare -rgb(n,n,n) with -point(x,y)

Here's a little test program:

dim x
x << rgb(0,     0,   0)
x << rgb(0,     0, 255)
x << rgb(0,   255,   0)
x << rgb(0,   255, 255)
x << rgb(255,   0,   0)
x << rgb(255,   0, 255)
x << rgb(255, 255,   0)
x << rgb(255, 255, 255)
for c in x
 pset 10, 10, c
 p = point(10, 10)
 if (p != c) then throw
 print space(6-len(hex(-p))) + hex(-p)
next c
 

ZXDunny

  • Full Member
  • ***
  • Posts: 242
    • View Profile
Re: POINT() gives odd output
« Reply #2 on: 18. February 2019, 14:01:40 »
Seems that the RGB function takes colours in the format RGB(red, green, blue), but the POINT function returns BBGGRR. So when you specify full red (255,0,0) you get 0000FF back, but full blue returns FF0000 as expected.

B+

  • Hero Member
  • *****
  • Posts: 802
    • View Profile
Re: POINT() gives odd output
« Reply #3 on: 19. February 2019, 18:37:54 »
Looks OK to me:
Code: [Select]
'whats the point B+ 2019-02-19

dim x
x << rgb(40,     20,   10)
x << rgb(0,     0, 155)
x << rgb(0,   185,   0)
x << rgb(0,   255, 155)
x << rgb(255,   0,   0)
x << rgb(255,   0, 255)
x << rgb(255, 255,   0)
x << rgb(255, 255, 255)
for c in x
  rect 100, 100, 200, 200, c filled
  p = point(105,105)
  color p
  circle 500, 500, 100 filled
  color 15
  ? getRGB(p)
  input "OK? press enter ";wate$   'consistent
  cls
next

func getRGB(pointValue)
  sh = right(space(6)+str(hex(-p)), 6)
  r = left(sh, 2)
  g = mid(sh, 3, 2)
  b = right(sh, 2)
  getRGB = "rgb("+str(val("&H"+r)) +", "+str(val("&H"+g))+", "+str(val("&H"+b))+")"
end
« Last Edit: 19. February 2019, 18:39:34 by B+ »

chrisws

  • Moderator
  • Newcomer
  • *****
  • Posts: 32
    • View Profile
Re: POINT() gives odd output
« Reply #4 on: 19. February 2019, 21:31:46 »
Here's another test program:

pset 0, 0, rgb(0,0,0xFF): if "FF" != hex(-point(0,0)) then throw
pset 0, 0, rgb(0,0xFF,0): if "FF00" != hex(-point(0,0)) then throw
pset 0, 0, rgb(0xFF,0,0): if "FF0000" != hex(-point(0,0)) then throw

lettersquash

  • Newcomer
  • *
  • Posts: 13
    • View Profile
Re: POINT() gives odd output
« Reply #5 on: 24. February 2019, 02:37:54 »
Aha, I think I've discovered the problem, Chris. Sure, I didn't realise the point value to use was negative, but there is another problem. The tests work fine on Windows, but on my Galaxy Tab 3, running Android 4.4.2, it returns the red and blue values the wrong way round, as I said, and as ZXDunny describes. Plotting, filling etc. are fine and give correct colours. It may not be all Androids - I hear they're a bit crazy with some odd hardware. I'll test my phone next.

Your second program throws the exception on the first line,
Code: [Select]
pset 0, 0, rgb(0,0,0xFF): if "FF" != hex(-point(0,0)) then throwbut not if I give
if "FF0000" != hex(-point(0,0)) then throw
(incidentally, on Android, with a black screen background, you need to throw more than a null string, as the toast notification is hardly noticable).

I've discovered something else weird too. Running your first test program, I get (EXPR):SYNTAX ERROR (10) on the second line, where it's trying to append the array - again, this is fine on Windows. OK - this is the extra spaces (tabs?) in the parameters, they're fine without those.

I just tried re-writing the code without the array, doing various things along these lines:
Code: [Select]
for r=0 to 255 step 255
   for g=0 to 255 step 255
      for b=0 to 255 step 255
          c=rgb(r,g,b)
          pset 10, 10, c
          p = point(10,10)
          if (p != c) then ? "Wrong"
       next b
    next g
next r
 
and I'm getting all manner of curious reports, depending on how I phrase it (I've forgotten all the permutations as I was trying to debug it):

Reports include, "Statement PRINT must be on the left side (first keyword of the line)", when it was (and wasn't even under a conditional, just trying to print); "Undefined SUB/FUNC code: if"; "Undefined SUB/FUNC code: PSET"; and "EXP/RT: Variable is not an array (use DIM)".

I also had THROW must be the first keyword...this was when I discovered the problem with the spaces in the rgb() and tried your code again without them. I didn't change anything else, just remove the spaces. Putting THEN: THROW, I've now got "FOR: Missing NEXT on same level."

With the code above, the nested for-next loops, I also tried getting it to just print r, g, b on each iteration (which is correct, going through the combinations), followed by print p and print c, which are both showing 0. I tried a delay between pset and point, still 0.

I've plotted with pset using rgb values in another program, and that seems to be working fine. I updated to 0.12.15 since the OP. I'm not sure if some of these issues have come with the update, but the point being read as BGR was there with 0.12.14, and looks like just a peculiarity of the Samsung Galaxy.

chrisws

  • Moderator
  • Newcomer
  • *****
  • Posts: 32
    • View Profile
Re: POINT() gives odd output
« Reply #6 on: 24. February 2019, 06:24:33 »
Aha, I think I've discovered the problem, Chris. Sure, I didn't realise the point value to use was negative, but there is another problem. The tests work fine on Windows, but on my Galaxy Tab 3, running Android 4.4.2, it returns the red and blue values the wrong way round, as I said, and as ZXDunny describes. Plotting, filling etc. are fine and give correct colours. It may not be all Androids - I hear they're a bit crazy with some odd hardware. I'll test my phone next.

Thanks for persevering with this. Yes I get the same problem on my mobile. I'll fix this soon and make another update.


lettersquash

  • Newcomer
  • *
  • Posts: 13
    • View Profile
Re: POINT() gives odd output
« Reply #7 on: 24. February 2019, 13:27:51 »
No problem - I'm very glad to help when I can with such great freeware. (And relieved it's not totally my programming!)

I'm pretty sure one of the problems with pset on my Tablet is that rgb() doesn't return a usable value.

pset x, y, rgb(n1, n2, n3) ' is fine, but

c = rgb(n1, n2, n3) ' gives 0 for all params, so
pset x, y, c ' plots a black dot.

Sorry I bundled a lot into one post and didn't have much time to debug, late at night.

chrisws

  • Moderator
  • Newcomer
  • *****
  • Posts: 32
    • View Profile
Re: POINT() gives odd output
« Reply #8 on: 02. March 2019, 23:53:08 »
Just made another update to hopefully fix the problem. I've also changed the status bar in the editor, please let me know if this causes any issues.

Here's my test program:

Code: [Select]
sub testPoint
  pset 0, 0, rgb(0,0,0xFF): if "FF" != hex(-point(0,0)) then throw
  pset 0, 0, rgb(0,0xFF,0): if "FF00" != hex(-point(0,0)) then throw
  pset 0, 0, rgb(0xFF,0,0): if "FF0000" != hex(-point(0,0)) then throw
end

sub testImageScrape
  cls
  for z=0 to 255
    for t=0 to 255
      pset t+000,z,rgb(255-z,255-t,255-t)
      pset t+257,z,rgb(255-t,255-z,255-t)
      pset t+514,z,rgb(255-t,255-t,255-z)
      pset z+000,(t/4)+260,rgb(255-t,0,0)
      pset z+257,(t/4)+260,rgb(0,255-t,0)
      pset z+514,(t/4)+260,rgb(0,0,255-t)
    next
  next
  z=image(0,0,xmax,325)
  z.show(0,350)
end

sub testImageLoad
  url ="http://pngimg.com/uploads/tesla_car/tesla_car_PNG26.png"
  open url as #1
  i = image(#1)
 
  x_left = xmax/4
  y_top = ymax/4
  r =xmax/4
  y_step = 10
  n_points =20
  n = 0
  while gg < 25
    gg++
    n= (n+1) mod n_points
    x = x_left + r * sin(n* pi / n_points)
    y = y_top + (n * y_step)
    i.show(x,y, 1,  80)
    delay 10
  wend

  i.show(20,20,1) :delay 100
  i.show(201,20,1, 56) :delay 100
  i.show(120,20,1, 56) :delay 100
  i.show(40,120,1,100) :delay 100
  j = image(#1)
  j.show(10,425,4,20)
  close #1
  delay 1000
end

testPoint
testImageLoad
testImageScrape
testImageLoad

lettersquash

  • Newcomer
  • *
  • Posts: 13
    • View Profile
Re: POINT() gives odd output
« Reply #9 on: 03. March 2019, 12:55:01 »
Hi Chris,

Great stuff - that's fixed the GBR values returned by my tablet - now RGB as plotted, and all looks identical on PC or Android.

Incidentally, I discovered that I must have made a mistake before when I said that rgb(a,b,c) was returning 0, because I checked the method again:

newvar = rgb(0,0,0xFF)
pset 0, 0, newvar

and thought you'd fixed that - then discovered that the installation from the PlayStore hadn't worked and I was on the old version! (Sorry, my bad.)

Unfortunately, the status bar is still there. Is it an option I should change? I didn't see it on any of the menus. It might be best as an option in case people want it, and the more verbose reporting on the PC (or larger screen) is useful.

One other thing while we're on the subject of colours - I've been reading that 'point' values returned can be messed up if antialiasing is on. Do I need to worry about that in sb? Does it always have antialiasing off, or always on, or is it a system setting I can change independent of sb programs, or is it something I can switch within sb?

Many thanks
~

chrisws

  • Moderator
  • Newcomer
  • *****
  • Posts: 32
    • View Profile
Re: POINT() gives odd output
« Reply #10 on: 03. March 2019, 21:28:26 »
I made it so that status bar becomes hidden when you scroll down. It also re-appears when you press the number column to begin scrolling - and re-hides when you release. The idea was to still show the information, but move it out of the way after you get cooking.

The POINT command doesn't return alpha information. You can do more advanced handling using the IMAGE command. There's some basic information about that here: http://smallbasic.github.io/reference/617.html (I still need to clean this page up a bit).
« Last Edit: 03. March 2019, 21:31:13 by chrisws »

lettersquash

  • Newcomer
  • *
  • Posts: 13
    • View Profile
Re: POINT() gives odd output
« Reply #11 on: 04. March 2019, 12:19:36 »
Hi Chris, thanks, I'll look into that IMAGE command. But I think there's still a potential issue with RGB values taken from the screen with POINT(), and I think it's probably due to antialiasing. I've found that drawing circles and then addressing random points gives different results from those drawn, which I'm guessing is an antialiasing effect. The following code just takes random positions for their colour rather than the same one plotted or within a larger area of solid colour, so it occasionally gets edges. If I run this and switch drawing mode (pset, rect and circle) only the circles cause different results (I was also causing them earlier by printing results to the same portion of screen I was taking point info from, which also causes the effect).  This is on both Android and Windows. I imagine that if I knew how to switch off antialiasing on either machine, or could do it from the programming language somehow, shapes like circles would just be drawn with the given colour (allowing 'jaggies') and only those colours could be found. I just happened to bump into the issue because I was using POINT() to test for 'collision' of graphic shapes I moved about on screen. As long as people are aware of it, it's just one of those things, a "known issue", so it's not a big deal. My little program can work fine just using pset or drawing rectangles, but if someone was moving circles about and seeing if they meet another (for ball-bouncing games, etc.) they'd meet this issue. They could get round it by just checking for non-background colours or whatever, just not assume that a yellow ball will be the same yellow all over it.

Another slight issue, by the way, is that if I draw circles (filled or unfilled) with radius R in a foreground colour, and then (in order to move them) draw over them in background, I have to use R+1, or they leave little ghost images of themselves. I guess this may also be the antialiased parts.

One possible solution would be if you can implement a command to set or unset antialiasing.

I'll check out the status bar again and get back to you.

Code: [Select]
REM SmallBASIC
REM created: 03/03/2019
repeat
  x=int(rnd*(xmax-300)):y=int(rnd*ymax)
  ' Try each of the following individually...
  'pset x,y,rgb(0xAB,0xCD,0xEF)
  'rect x,y,x+2,y+2,rgb(0xAB,0xCD,0xEF)
  circle x,y,5,1,rgb(0xAB,0xCD,0xEF)
  x=int(rnd*(xmax-300)):y=int(rnd*ymax)
  p = hex(-point(x,y))
  if p != "0" then at xmax-250,py: ? "p = ";p:pause:py+=20
  byte = right(p,2)
  if byte <> "EF" and byte <> "0" then at xmax-250,py: ? "blue = ";byte:pause:py+=20
until 0

Cheers
~

lettersquash

  • Newcomer
  • *
  • Posts: 13
    • View Profile
Re: POINT() gives odd output
« Reply #12 on: 04. March 2019, 19:38:00 »
Yes, you're right, the status bar does disappear on scrolling down in Android. Neat. It stays put in Windows, but that's fine for me. (I scroll with the trackpad gestures on Win.)

chrisws

  • Moderator
  • Newcomer
  • *****
  • Posts: 32
    • View Profile
Re: POINT() gives odd output
« Reply #13 on: 05. March 2019, 10:22:14 »
Hi Chris, thanks, I'll look into that IMAGE command. But I think there's still a potential issue with RGB values taken from the screen with POINT(), and I think it's probably due to antialiasing. I've found that drawing circles and then addressing random points gives different results from those drawn, which I'm guessing is an antialiasing effect. The following code just takes random positions for their colour rather than the same one plotted or within a larger area of solid colour, so it occasionally gets edges. If I run this and switch drawing mode (pset, rect and circle) only the circles cause different results (I was also causing them earlier by printing results to the same portion of screen I was taking point info from, which also causes the effect).  This is on both Android and Windows. I imagine that if I knew how to switch off antialiasing on either machine, or could do it from the programming language somehow, shapes like circles would just be drawn with the given colour (allowing 'jaggies') and only those colours could be found. I just happened to bump into the issue because I was using POINT() to test for 'collision' of graphic shapes I moved about on screen. As long as people are aware of it, it's just one of those things, a "known issue", so it's not a big deal. My little program can work fine just using pset or drawing rectangles, but if someone was moving circles about and seeing if they meet another (for ball-bouncing games, etc.) they'd meet this issue. They could get round it by just checking for non-background colours or whatever, just not assume that a yellow ball will be the same yellow all over it.

Another slight issue, by the way, is that if I draw circles (filled or unfilled) with radius R in a foreground colour, and then (in order to move them) draw over them in background, I have to use R+1, or they leave little ghost images of themselves. I guess this may also be the antialiased parts.

One possible solution would be if you can implement a command to set or unset antialiasing.

I'll check out the status bar again and get back to you.

Code: [Select]
REM SmallBASIC
REM created: 03/03/2019
repeat
  x=int(rnd*(xmax-300)):y=int(rnd*ymax)
  ' Try each of the following individually...
  'pset x,y,rgb(0xAB,0xCD,0xEF)
  'rect x,y,x+2,y+2,rgb(0xAB,0xCD,0xEF)
  circle x,y,5,1,rgb(0xAB,0xCD,0xEF)
  x=int(rnd*(xmax-300)):y=int(rnd*ymax)
  p = hex(-point(x,y))
  if p != "0" then at xmax-250,py: ? "p = ";p:pause:py+=20
  byte = right(p,2)
  if byte <> "EF" and byte <> "0" then at xmax-250,py: ? "blue = ";byte:pause:py+=20
until 0

Cheers
~

You can add this to the start of your program to turn off anti-alias drawing with LINE and CIRCLE:

Code: [Select]
option predef antialias off

I've added a note about this to the LINE and CIRCLE help pages.

lettersquash

  • Newcomer
  • *
  • Posts: 13
    • View Profile
Re: POINT() gives odd output
« Reply #14 on: 10. March 2019, 16:30:38 »
Hi Chris, that's great about the predef option, thanks!

EDITED - Oops, I'm an idiot - I posted a problem I was having, but it's obvious what's wrong, so I've deleted it.

Cheers
~
« Last Edit: 10. March 2019, 16:41:24 by lettersquash »