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

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
Khranos
Prole
Posts: 30
Joined: Tue Aug 11, 2015 1:22 am

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

Post 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 4471 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!
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

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

Post by raidho36 »

Try rounding pixel coordinates immediately before you sample pixels from the image.
User avatar
Khranos
Prole
Posts: 30
Joined: Tue Aug 11, 2015 1:22 am

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

Post 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)?
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

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

Post 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.
User avatar
zorg
Party member
Posts: 3470
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

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

Post 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.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

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

Post 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.
User avatar
Khranos
Prole
Posts: 30
Joined: Tue Aug 11, 2015 1:22 am

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

Post 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!
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

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

Post 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.
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

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

Post 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?
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

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

Post 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.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 6 guests