gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Filtering touch screen jumping

#160793 - Thor - Tue Jul 22, 2008 4:42 pm

I'm porting my Java program Sketcher to C++ on the NDS. I'm using libnds and I notice that the touch screen coordinates sometimes jump. I'm looking for some way of filtering them out. Does anyone have suggestions?

#160796 - silent_code - Tue Jul 22, 2008 5:00 pm

When touching very slightly, (pseudo) random values may be returned. Try to test for a pressure threshold. Remember that pressure is not an officially supported feature.

You could also measure the square distance between two points and then choose to skip the new point, if the distance is over a certain threshold.
_________________
July 5th 08: "Volumetric Shadow Demo" 1.6.0 (final) source released
June 5th 08: "Zombie NDS" WIP released!
It's all on my page, just click WWW below.

#160822 - josath - Wed Jul 23, 2008 1:19 am

silent_code wrote:
When touching very slightly, (pseudo) random values may be returned. Try to test for a pressure threshold. Remember that pressure is not an officially supported feature.

It's not officially supported because different DS's report the pressure values differently, and there's no easy way to calibrate it. So even if it works fine on your (the coder's) DS, it may work very poorly on other people's

Quote:
You could also measure the square distance between two points and then choose to skip the new point, if the distance is over a certain threshold.

This is a bad idea for a drawing program...means you can't scribble quickly, eg while shading in an area.

Another option is to disregard the first touch position after the pen is put down, and then disregard the last touch position just before the pen is lifted. This will solve the problem 80%-90% of the time, in my experience.

Might want to look into the source of the few drawing apps out there, to see if they've done anything in particular.

#160848 - Thor - Wed Jul 23, 2008 3:58 pm

I tried measuring the distance between points, and it -does- give me the problem of killing quick strokes.

Measuring the pressure was mentioned, so I tried this as well. I found that ordinary pressure values are quite far removed from the values you typically get when the cursor jumps. Whereas regular values lie approximately in the range of 80 - 130, cursor jumps are typically well above 340.

I still get jumps but they're minor compared to what I had before. I figure there must be a way to catch these, as they are very easy to spot. I am thinking about measuring acceleration. The jumps are impossibly fast and a human hand could never accelerate that quickly.

Or perhaps I could pair the square distance measurement with the pressure threshold.

#160852 - Lazy1 - Wed Jul 23, 2008 6:30 pm

Measure the touchscreen over 8 frames, 99% of jitter problems fixed for me anyways.
I can PM you some code showing how I do it, but it's pretty messy and could be done better.

#160853 - Thor - Wed Jul 23, 2008 6:36 pm

Lazy1 wrote:
I can PM you some code showing how I do it, but it's pretty messy and could be done better.

I'm interested. Perhaps it's better to just give an explanation than code?

#160855 - josath - Wed Jul 23, 2008 6:40 pm

Does that mean it introduces an 8-frame lag between touching the screen and it being input into the application? Sounds like it might be annoying for a drawing app.

#160861 - Lazy1 - Wed Jul 23, 2008 6:55 pm

It might, I didn't notice it though.

All you need is an array of the touch coordinates of the last 8 frames, then your final position is the average of those 8.
It also helps do discard small jumps like those between 1 to 2 pixels.

When the pen is first put down set all the array elements to the current touch spot and when it goes up set them all to 0.

Worked fine for me, but a drawing app may be different.

#160863 - Thor - Wed Jul 23, 2008 7:37 pm

I have tested to measure acceleration and it removes almost all the jumps. I keep 2 previous touch screen points and there is no lag.

Next, I'll try to combine this with cutting off wildly high pressure values (like before). Perhaps that will clean up the rest.

#160866 - DekuTree64 - Wed Jul 23, 2008 8:15 pm

In Animanatee (Input.c), I use the current state and 2 previous frames to detect jumps, which causes a lag of one frame (it's treated more like the previous, current, and future next frame).

Basically it does 4 major things:
1) It discards the first frame's position, unless the screen was only touched for one frame. First position is often wrong, but feels unresponsive if a quick tap is ignored entirely.
2) If the touch screen is only released for one frame, the release is ignored (position for the missing frame is replaced by the midpoint of the previous and next frames). Happens when not pressing hard enough.
3) If the position jumps 16 pixels to the edge of the screen, the position is discarded (replaced by midpoint again). You shouldn't normally be able to reach all the way to the edge anyway, and that's where most jumps go to.
4) If the position jumps "out and back" by more than 16 pixels, the position is discarded. This mostly happens when drawing lines at medium speed and fairly low pressure, you get a little spike off the side sometimes.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#160867 - Thor - Wed Jul 23, 2008 8:37 pm

Okay. Now I'm using both pressure (> 340) and square acceleration (> 576) as indicators and I can't provoke any jumps anymore. Anyone else care to test on their DS? Here is what I have so far. Draw on the bottom screen. The top screen is unused. Clear with X.

#160870 - DekuTree64 - Wed Jul 23, 2008 9:30 pm

Works pretty good on my brick. I only got it to jump once out of a couple minutes of trying. I was scribbling with light pressure near the top left corner, and it jumped to maybe 30 pixels from the bottom (slightly angled line, not straight down).

You might want to put in the special case for quick taps that I mentioned though. It seems to take a couple frames before it registers a touch, so for example it's tough to draw a dotted line.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#160875 - Thor - Wed Jul 23, 2008 10:39 pm

I have a special case for taps but it's not working for some reason. I have to move my stylus one pixel before keysHeld() or readTouchX() register anything.

#160882 - kusma - Wed Jul 23, 2008 11:32 pm

Works more or less flawlessly here, great work.