Finding the slope of an edge in a BufferedImage

Hey guys. I’m having a hell of a time computing the slope of an edge in a BufferedImage – it’s a very difficult operation, and I don’t necessarily have the math skills to get it completely right without a lot of effort.

So I’m asking for some insight.

Basically, I have one BufferedImage that collides with another at a certain velocity, and I want it to properly reflect off at the correct angle when it hits the second BufferedImage.

This gives me a single pixel of collision (where the two images touched, or at least the first place), and so I need to use the location of that pixel to scan all surrounding pixels and find the slope. In concept this doesn’t seem too bad, but there’s so many fringe cases it’s making everything pretty difficult.

And out of a grid of pixels, how am I to find the slope, even without fringe cases? Essentially each pixel is the center piece in a 3x3 grid, as in it is completely surrounded by other pixels. Just looking at these 9 pixels, this creates only 4 real possibilities – up/down, right/left, and each diagonal. Naturally, that is not definite enough to find a real slope, so I have to expand the check to the surrounding 5x5 grid, creating a total of 25 pixels. And from there I’m not quite sure where to go. Unless an edge has one of those four slopes, then each pixel along it will definitely not be perfect. I can obviously count slope by rise over run, but this still creates problems with a potentially curving slope.

So I guess my real question is, how many pixels should I scan out, and how do I know when I found the real edge? And what do I do in some of the fringe cases, like single floating lone pixels or being completely surrounded in dirt?

Thanks.

You can use the Marching Squares algorithm to compute a geometrical outline from your image. It’s not a very cheap operation though, so you’d probably be best caching the results for later use.

I’ve also just remembered a 2D physics engine that I saw linked from a GameDev thread a while ago that might obviate the need to use geometry for physics. The idea was that bodies are made of large numbers of particles that have mass, velocity and so on, stuck together with distance constraints. Collisions were handled purely at the particle level, with simple billiard-ball type behaviour, and the distance constraints took care of the rest. In your case, each pixel of the images would be a particle, constrained to each neighbouring pixel
The advantages:

  • Simple to implement
  • You can get bodies to break apart by removing distance constraints when they get too stretched or compressed

The disadvantages:

  • A particle per pixel is a lot of particles to simulate

Something to think about anyway…

my suggestion would be to not model your game (?) using pixels, but geometric objects, and use pixels (bufferedImages) just as a “view” of your underwater-geometric world. Once you reduce your world to polygons, collision and physics emulation becomes much easier.

Okay, these replies make sense. I’ve had an idea that works pretty well with pixels, but it sometimes performs very strangely, because it doesn’t account for all the fringe cases. Essentially I scan every pixel around the collided pixel (so 9 pixels total), then depending on the placement of the colored pixels vs. transparent pixels can result in a total of 16 different angles, which is enough to show some pretty realistic bouncing and angled collision. In all other cases, which turn up rarely (like floating pixels, isolated pixels, etc.), I just return a flat deflection (reverse x and y direction). It can look mildly kinky, but is at least playable.

This DameDev approach bleb found seems intruiging, but I don’t quite understand. Are you saying basically that we would assume every particle has a certain repulsion, like a magnet, and then depending on their distance and direction from the object they apply and certain amount of force? If so, that is a very good idea, and I’ll definitely mess around with it. Maybe whenever there is a collision I will scan a certain radius of pixels and apply their repulsion, rather than constantly doing it with every pixel. That would certainly be expensive, to say the least. Or I can just have every object constantly scan a radius around it, colliding or no.

My only issue with this would be not overlapping repulsion too much, if you get my meaning. Like say an obect is resting on entirely flat ground. Now say I am scanning a 5 pixel radius around the object for repulsion. That means there are 5 pixels below the object trying to push it up. If there were only one pixel below the object, it should still resist gravity, therefore applying 9.8 m/s up. Now, say the amount of force replied is (1 - pixel distance/5.0)*9.8 that means that with five pixels below the object, which in total equals 29.4 m/s of force. This means the object will constantly bounce up and down as it drifts away from the pixels, then gravity pulls it back down. I can’t make it so that each pixel applies a reduced force, because then a single pixel won’t be able to defy gravity on its own.

So, rather than a fixed application, I can say (1 - pixel distance/5.0)*(object force), which will give me the correct bounce (an object going faster will bounce off further), but the same problem will result. A “denser” material should not deflect an object more than a single pixel line. So… how do I fix that? Only scan a single pixel radius? Not sure on that.

I’ve had another look, and have just found the link!

Ta-daaa!

There’s not much in the way of detail in these pages, but it’s somewhere to start.

Excellent! I’ll take a look, thanks a lot. I’ll report how it goes here.