Page 1 of 4

How to create a faster/more accurate image alpha check mouse hover function

Posted: Thu Jan 12, 2017 7:12 am
by Khranos
Yeah, there goes Khranos with another convoluted title. To elaborate, I'm working with menus right now and I have buttons with kind of wander around a small area on the screen. When the mouse hovers over the initial parameters of an image (it's x/y in a table + its height/width), it checks up to 3 layers down in pixels checking for an alpha property greater than 0.

Before implementing the wandering feature of the buttons, everything was working perfectly. Post-wander, it's now kind of half-triggering. I assume it's because the x/y locations are changing while it's in the middle of checking the pixel it was on, causing it to become disoriented, but that could be incorrect.

Below is a .gif of the issue, if it clears up any confusion from above. As is seen, it's finding alpha particles where there should not be any (it isn't detecting the background, as it isn't in the table for detection).
This button is in two parts -- the inner black fading portion, and the outer white portion.
This button is in two parts -- the inner black fading portion, and the outer white portion.
menuButtonProblem.gif (4.48 MiB) Viewed 4477 times
The mouse alpha particle detection function I'm using is below:

Code: Select all

function cursorIsOverMenu(moX, moY, exception, exception2) -- handles menu button click detection.
  for i, image in ipairs (imagesMenu) do
    if i ~= exception and i ~= exception2 then --if the exception was reached (AKA it had to go 1 or 2 layers deeper on said pixel)
      local x = moX
      local y = moY
      local imgData = image.img:getData()
      if (x > image.x) and (y > image.y) and (x < (image.x + image.img:getWidth())) and (y < (image.y + image.img:getHeight())) then -- ensure the mouse is within the parameters.
        if lume.sign(x) ~= -1 and lume.sign(y) ~= -1 then -- simply a debug that rarely gets used. Better to have it than not.
          local xPix = moX - image.x
          local yPix = moY - image.y
          local r, g, b, a = imgData:getPixel(xPix, yPix)
          if a ~= 0 then
            print("on image "..i)
            if image.visible then
              return true, image.label
            end
          else
            print("not on image "..i)
            if not exception then
              cursorIsOver(moX, moY, i)
            elseif not exception2 then
              cursorIsOver(moX, moY, exception, i)
            end
          end
        end
      end
    end
  end
end
It's messy, but it has been getting the job done. I'm using flux to change a table containing the x/y of the images using a function which randomly selects a new point within its boundaries.

If it helps, I also have the selection of functions I'm using to trigger wandering, as well as the tables that they're pulling from located here: https://hastebin.com/zewedudaju.lua .

I'm thoroughly interested in both code examples and general directions to head towards -- tips are just as useful, if not more useful, than code snippets. Thank you in advance to anybody willing to help out!

Re: How to create a faster/more accurate image alpha check mouse hover function

Posted: Thu Jan 12, 2017 7:53 am
by raidho36
Try rounding pixel coordinates immediately before you sample pixels from the image.

Re: How to create a faster/more accurate image alpha check mouse hover function

Posted: Thu Jan 12, 2017 5:24 pm
by Khranos
raidho36 wrote:Try rounding pixel coordinates immediately before you sample pixels from the image.
Huh, I was initially doubtful but that did indeed fix it -- thank you! I feel like I've had issues like this before, though. I'm guessing it can't exactly sample a pixel with a decimal as they only exist as whole numbers, but is there something more to it (or is that just completely wrong)?

Re: How to create a faster/more accurate image alpha check mouse hover function

Posted: Thu Jan 12, 2017 7:27 pm
by raidho36
Nah it's just LuaJIT does funky stuff when it has to index hardware array by non-integer indices. GPU will automatically fetch neighboring array indices and interpolate, but CPU doesn't do that.

Re: How to create a faster/more accurate image alpha check mouse hover function

Posted: Thu Jan 12, 2017 8:28 pm
by zorg
I don't know whether it is related to LuaJIT or not, but basically, don't use non-integers with ImageData:getPixel;
similar limitations are with SoundData:getSample; it won't magically interpolate between samplepoints for you.

I don't recall whether the two's functionality on non-expected input is the same or not, but best case scenario, it errors; worst case scenario, it returns undefined values.

Re: How to create a faster/more accurate image alpha check mouse hover function

Posted: Thu Jan 12, 2017 9:57 pm
by raidho36
It is, check out the wrap_ImageData.lua - funny thing, in few instances LuaJIT compiled code outperforms framework C++ call to the code that does the same.

In C++ code you're not allowed to use floats to index arrays, period. But LuaJIT wouldn't be Lua if it refused to do it and yet it craps out anyway if you attempt this.

Re: How to create a faster/more accurate image alpha check mouse hover function

Posted: Sat Jan 14, 2017 8:12 am
by Khranos
Huh, guess it's a bit more complicated than expected! As it seems to be deeper than just an issue of how computers work, I'll leave it on a "just don't do this and it'll be fine" basis. Thank you for the explanations!

Re: How to create a faster/more accurate image alpha check mouse hover function

Posted: Sat Jan 14, 2017 10:09 am
by raidho36
One basic rule about programming is "don't assume things". Always check the manual, always do the testing.

Also don't exploit bugs and undefined behaviors. If you're not sure that's how it is deliberately designed to function, don't use it.

Re: How to create a faster/more accurate image alpha check mouse hover function

Posted: Sat Jan 14, 2017 11:13 pm
by airstruck
raidho36 wrote:One basic rule about programming is "don't assume things". Always check the manual, always do the testing.

Also don't exploit bugs and undefined behaviors. If you're not sure that's how it is deliberately designed to function, don't use it.
Can you explain how this comment is relevant to the topic being discussed?

What things are being assumed here? ImageData:getPixel takes two "number" arguments. The wiki doesn't state that they must be integers. The original code is consistent with documentation, I don't see what assumption is being made here.

Where is the bug? Where is the undefined behavior? Surely you're not suggesting that if some function isn't documented as allowing fractional values, that constitutes UB and we should assume it can only take integers. If that were the case, a huge number of wiki pages would need to be updated to say exactly what characteristics each argument may have (or we shouldn't use those functions at all because of UB).

Did you post this in the right thread?

Re: How to create a faster/more accurate image alpha check mouse hover function

Posted: Sun Jan 15, 2017 9:56 am
by raidho36
Assumption was that getPixel would interpolate if you supply it with halfway between pixels coordinates. The undefined behavior remark was there to specifically mention that even if you test something and it works but it's not 100% intended by design, you shouldn't use it anyway - that prevents "works on my machine" debacles.