GC friendly convex clipping (union and difference) algorithm - javascript

I'm looking for algorithm that will cut my convex polygon based on another convex polygon. It is gonna be for destructible terrain (diff) and for creating terrain (union) in 2D map in game.
Algorithm has to be Garbage Collector friendly and the only boolean operations that are neccessary are Union & Difference.
I've done some research and there are some github projects, but all of them produce some garbage more or less.
https://github.com/tmpvar/2d-polygon-boolean
https://github.com/w8r/GreinerHormann
I guess the best solution would be to learn one of these and re-make it my way. But maybe you've heard about some that suits my needs?
Thanks.

This problem involves two subproblems
find the intersection points between the two outlines
join the vertices that mus be joined.
For 1. you can exploit convexity: see both polygons as two monotone chains. When you travel the chains of the twopolygons simultaneously, say by increasing x, the intersections are detected when the ordinates cross each other between two abscissas.
For 2. notice that the union or difference are made of portions of the outlines alternating between one polygon and the other, at every interesection point.
Note that in the case of the difference, there can be several disconnected pieces.
I guess that you can implement this without any allocation/deallocation at all (but for the output polygon).

Related

JavaScript Canvas Complex Shape Collision

I am trying to make a very simple game with the HTML canvas and JavaScript. I have found many tutorials and questions about detecting collisions of basic shapes on a canvas (such as rectangles and circles). But I am wondering is it possible to detect if a complex shape (a shape that is made up of many basic shapes) is colliding with another shape, or even if two complex shapes are colliding. If so, how could this be done? Thanks in advance!
A general algorithm will not provide a better solution than one based specifically on the knowledge of each shape type.
Generally, for complex (i.e. compound) shapes, you would generally try as step #1 and "exit early" test. For optimization reasons, you generally try eliminate false-positives as early in the process as possible.
As simple step #1 is to test for collisions on the "bounding boxes" of each compound shape. If the bounding boxes are NOT overlapping then you can quit early and assume no collision because the compound shapes could not be colliding (see https://gamedevelopment.tutsplus.com/tutorials/collision-detection-using-the-separating-axis-theorem--gamedev-169)
If the bounding-box test cannot eliminate early, you will need to test each sub-shape in turn with algorithms most suitable to the shape (circle-circle, circle-rect etc.) leaving the most "expensive" tests to last - like polygon-polygon.
You might want to also look at this question How do I determine if two convex polygons intersect?

How to determine if two concave/convex shapes are at particular distance?

I have to determine whether two concave/convex shapes are at distance d from each other . I know Separating Axis theorem might come handy in determining the distance , but that runs in O(n2) time , and I am looking for O(n) or O(nlogn) algorithm for any shape . I want to implement that for any two SVGs in javascript
This is a broad and arduous problem.
To handle the most difficult cases (like ellipse/Bezier distance), you will need to somehow flatten the outlines so I recommend to flatten in all cases, and solve the problem for two polygons only.
Amazingly, you find little resources on the Web for the distance between two polygons.
Assuming that you are dealing with the inside of the shapes (and not just the outline), you will first have to check the polygons for void intersection (otherwise the distance is 0). I guess that this can be done in time O(N.Log(N)).
Then, if I am right, the closest distance between two polygons is the shortest of the closest distances of all vertices to the other polygon. If you construct the Voronoi diagram of both polygons (which is doable in time O(N.Log(N))), you get two planar subdivision, in which you can solve the point-location problem in time Log(N) per point.
All put together should lead to an O(N.Log(N)) solution. You will need a specialized Computational Geometry library to achieve this.

Best practice: Rendering volume (voxel) based data in WebGL

I´m searching for a (or more) best practice(s) for the following problem. I´ll try to describe it as abstract as possible, so the solution can be applied to scenarios i have not yet thought of.
Data available: Voxels (Volumetric Pixels), forming a cube, with coordinates x,y,z and a color attached.
Goal: Use OpenGL to display this data, as you move through it from different sides.
Question: Whats the best practice to render those voxels, depending on the viewpoint? How (which type of Object) can store the data?
Consider the following:
The cube of data can be considered as z layers of x y data. It should
be possible to view, in-between-layers, then the displayed color
should be interpolated from the closest matching voxels.
For my application, i have data sets of (x,y,z)=(512,512,128) and
more, containing medical data (scans of hearts, brains, ...).
What i´ve tried so far:
Evaluated different frameworks (PIXI.js, three.js) and worked through a few WebGL tutorials.
If something is not yet clear enough, please ask.
There are 2 major ways to represent / render 3D datasets. Rasterization and Ray-tracing.
One fair rasterization approach is a surface reconstruction technique by the use of algorithms such as Marching Cubes, Dual Contouring or Dual Marching Cubes.
Three.js have a Marching Cubes implementation in the examples section. You basically create polygons from your voxels for classical rasterization. It may be faster than it seems. Depending the level of detail you want to reach, the process can be fast enough to be done more than 60 times per second, for thousands of vertices.
Although, unless you want to simply represent cubes (I doubt) instead of a surface, you will also need more info associated to each of your voxels rather than only voxel positions and colors.
The other way is raycasting. Unless you find a really efficient raycasting algorithm, you will have serious performance hit with a naive implementation.
You can try to cast rays from your camera position through your data structure, find / stop marching through when you reach a surface and project your intersection point back to screen space with the desired color.
You may draw the resulting pixel in a texture buffer to map it on a full-screen quad with a simple shader.
In both cases, you need more information than just colors and cubes. For example, you need at least density values at each corners of your voxels for Marching cubes or intersection normals along voxels edges (hermite data) for Dual Contouring.
The same for ray-casting, you need at least some density information to figure out where the surface lies or not.
One of the keys is also in how you organize the data in your structure specially for out-of-core accesses.

Bounds for networks and forces with D3.js?

I need to use the algorithm of forces with a network, but that network is divided into parts.
For example, the vertices of the first part can not leave the part 1. The vertices of the part 2 need to be in part 2.
If there is a connection between a vertex from part 1 and a vertex from part 2, this connection will make these two vertices be near, however, will not let their parts.
This draft image illustrates the idea:
I need to do this for about 8 parts. Some parts are in the other, other parts are next to each other. And the network will be represented on these parts, each vertex in their respective part, however, the algorithm forces should try to pull the connected vertices themselves.
My solution was to create constraints using the "tick" function from d3.
To improve performance and avoid "locked" vertices on corners, I decided to use only circles.
For each node:
Make sure it is inside its region.
Make sure it is also not inside each of the other regions.
This ended up in lots of calculations for each node vs. each region. This is summed with the collision detection complexity. Yet, it handled networks with around a thousand nodes.
Details here:
Heberle, H., Carazzolle, M., Telles, G. et al. CellNetVis: a web tool for visualization of biological networks using force-directed layout constrained by cellular components. BMC Bioinformatics 18, 395 (2017). https://doi.org/10.1186/s12859-017-1787-5
Note for potential improvement: one of the most expensive calculations is the combo of checking over what elements a node is. For instance, if there was a native "browser's" function that giving a point x,y it returned the elements of an SVG that this point is over, it would make the visualization smoother and create "space" for more improvements. By the time I implemented it, I did not find such function.

how to "sort" polygons 3d?

I am still working on my "javascript 3d engine" (link inside stackoverflow).
at First, all my polygons were faces of cubes, so sorting them by average Z was working fine.
but now I've "evolved" and I want to draw my polygons (which may contain more than 4 vertices)
in the right order, namely, those who are close to the camera will be drawn last.
basically,
I know how to rotate them and "perspective"-ize them into 2D,
but don't know how to draw them in the right order.
just to clarify:
//my 3d shape = array of polygons
//polygon = array of vertices
//vertex = point with x,y,z
//rotation is around (0,0,0) and my view point is (0,0,something) I guess.
can anyone help?
p.s: some "catch phrases" I came up with, looking for the solution: z-buffering, ray casting (?!), plane equations, view vector, and so on - guess I need a simple to understand answer so that's why I asked this one. thanks.
p.s2: i don't mind too much about overlapping or intersecting polygons... so maybe the painter's algorthm indeed might be good. but: what is it exactly? how do I decide the distance of a polygon?? a polygon has many points.
The approach of sorting polygons and then drawing them bottom-to-top is called the "Painter's algorithm". Unfortunately the sorting step is in general an unsolvable problem, because it's possible for 3 polygons to overlap each other:
Thus there is not necessarily any polygon that is "on top". Alternate approaches such as using a Z buffer or BSP tree (which involves splitting polygons) don't suffer from this problem.
how do I decide the distance of a polygon?? a polygon has many points.
Painter's algorithm is the simplest to implement, but it works only in very simple cases because it assumes that there is only a single "distance" or z-value for each polygon (which you could approximate to be the average of z-values of all points in the polygon). Of course, this will produce wrong results if two polygons intersect each other.
In reality, there isn't a single distance value for a polygon -- each point on the surface of a polygon can be at a different distance from the viewer, so each point has its own "distance" or depth.
You already mentioned Z-buffering, and that is one way of doing this. I don't think you can implement this efficiently on a HTML canvas, but here's the general idea:
You need to maintain an additional canvas, the "z-buffer", where each pixel's colour represents the z-depth of the corresponding pixel on the main canvas.
To draw a polygon, you go through each point on its surface and draw only those points which are closer to the viewer than any previous objects, as indicated by the z-buffer.
I think you will have some ideas by investigating BSP tree ( binary spaces partition tree ), even if the algo will require to split some of your polygon in two.
Some example could be find here http://www.devmaster.net/articles/bsp-trees/ or by google for BSP tree. Posting some code as a reply is, in my opinion, not serious since is a complex topic.

Categories

Resources