badso
badso

Reputation: 109

How to detect collision in not easily polygon divided body

Say we are coding something in Javascript and we have a body, say an apple, and want to detect collision of a rock being thrown at it: it's easy because we can simply consider the apple as a circle. But how about we have, for example, a "very complex" fractal? Then there is no polygon similar to it and we also cannot break it into smaller polygons without a herculean amount of effort. Is there any way to detect perfect collision in this case, as opposed to making something that "kind" of works, like considering the fractal a polygon (not perfect because there will be collision detected even in blank spaces)?

Upvotes: 0

Views: 314

Answers (3)

Timo Kähkönen
Timo Kähkönen

Reputation: 12210

If you have coordinates of the polygons, you can make an intersection of subject and clip polygons using Javascript Clipper

enter image description here

The question doesn't provide too much information of the collision objects, but usually anything can be represented as polygon(s) to certain precision.

EDIT:

It should be fast enough for real time rendering (depending of complexity of polygons). If the polygons are complex (many self intersections and/or many points), there are many methods to speedup the intersection detection:

  • reduce the point count using ClipperLib.JS.Lighten(). It removes the points that have no effect to the outline (eg. duplicate points and points on edge)
  • get first bounding rectangles of polygons using ClipperLib.JS.BoundsOfPath() or ClipperLib.JS.BoundsOfPaths(). If bounding rectangles are not in collision, there is no need to make intersection operation. This function is very fast, because it just gets min/max of x and y.
  • If the polygons are static (ie their geometry/pointdata doesn't change during animation), you can lighten and get bounds of paths and add polygons to Clipper before animation starts. Then during each frame, you have to do only minimal effort to get the actual intersections.

EDIT2:

If you are worried about the framerate, you could consider using an experimental floating point (double) Clipper, which is 4.15x faster than IntPoint version and when big integers are needed in IntPoint version, the float version is 8.37x faster than IntPoint version. The final speed is actually a bit higher because IntPoint Clipper needs that coordinates are first scaled up (to integers) and then scaled down (to floats) and this scaling time is not taken into account in the above measurements. However float version is not fully tested and should be used with care in production environments.

The code of experimental float version: http://jsclipper.sourceforge.net/6.1.3.4b_fpoint/clipper_unminified_6.1.3.4b_fpoint.js

Demo: http://jsclipper.sourceforge.net/6.1.3.4b_fpoint/main_demo3.html

Playground: http://jsbin.com/sisefo/1/edit?html,javascript,output

EDIT3:

If you don't have polygon point coordinates of your objects and the objects are bitmaps (eg. png/canvas), you have to first trace the bitmaps eg. using Marching Squares algorithm. One implementation is at https://github.com/sakri/MarchingSquaresJS.

There you get an array of outline points, but because the array consists of huge amount of unneeded points (eg. straight lines can easily be represented as start and end point), you can reduce the point count using eg. ClipperLib.JS.Lighten() or http://mourner.github.io/simplify-js/.

After these steps you have very light polygonal representations of your bitmap objects, which are fast to run through intersection algorithm.

Upvotes: 1

Mistergreen
Mistergreen

Reputation: 1052

You can use a physics editor https://www.codeandweb.com/physicseditor

It'll work with most game engines. You'll have to figure how to make it work in JS.

Here's an tutorial from the site using typescript - related to JS http://www.gamefromscratch.com/post/2014/11/27/Adventures-in-Phaser-with-TypeScript-Physics-using-P2-Physics-Engine.aspx

Upvotes: 1

Rodrigo5244
Rodrigo5244

Reputation: 5535

You can create bitmaps that indicate the area occupied by your objects in pixels. If there is intersection between the bitmaps, then there is a collision.

Upvotes: 0

Related Questions