5

I'm drawing polygons on a canvas with an underlying grid

enter image description here

I want to split this polygon into multiple polygons now (based on the grid)

enter image description here

So instead of 1 polygon, I get the coordinates for 4 polygons.

Is there an easy solution for this I'm not thinking about?

This is the code for my test canvas (codepen)

<script>
var bw = 200;
var bh = 200;
var p = 0;
var cw = bw + (p*2) + 1;
var ch = bh + (p*2) + 1;

var grid = 50;

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

function drawBoard(){

 context.beginPath();
 for (var x = 0; x <= bw; x += grid){
    context.moveTo(0.5 + x + p, p);
    context.lineTo(0.5 + x + p, bh + p);
 }
 for (var x = 0; x <= bh; x += grid) {
    context.moveTo(p, 0.5 + x + p);
    context.lineTo(bw + p, 0.5 + x + p);
 }
 context.lineWidth = 1;
 context.strokeStyle = "black";
 context.stroke();

}
drawBoard();

// Polygon
context.fillStyle = '#f00';
context.beginPath();
context.moveTo(0, 0);
context.lineTo(100,50);
context.lineTo(50, 100);
context.lineTo(0, 90);
context.closePath();
context.fill();
</script>
kruczy
  • 791
  • 4
  • 8
user2719160
  • 123
  • 6
  • @KenFyrstenberg Any ideas on this one? I can visualize a solution dividing the polygon into grid cells using drawImage clipping. Then do marching squares outline detection on each of those sub-polygon cells. And finally do some path simplification to reduce each path to (hopefully) just the vertices of the sub-polygon. But this seems messy. What I haven't been able to do is visualize a math solution--maybe finding the line segments inside an individual cell and somehow creating a closed path with those line segments. I just think there's a simple solution & it bugs me not to know it :-) – markE Mar 11 '15 at 05:12
  • 1
    @markE (hm, @'s doesn't seem to work if user isn't in the list, good to know). I would do something similar as what Matt Ko is outlining. Find intersecting points within each square and rebuild polygon based on that (checking side and limit grid region to original polygon size). –  Mar 11 '15 at 05:51
  • you can split the polygon with every grid line, it will be slow and probably not the best solution, how to split was already discussed here: http://stackoverflow.com/questions/3623703/how-can-i-split-a-polygon-by-a-line – kruczy Mar 11 '15 at 10:39

2 Answers2

1

You can quite easily calculate this:
You start by taking all points from your grid (all intersections), then all you have to do is for each point to check whether it is inside your polygon or not.

  • If it is a corner of your polygon, you can ignore it.
  • If it is outside your polygon, you can ignore it.
  • If it is inside your polygon, you have trivial 4 polygons to each side of the point. It then depends how you want to handle the case where multiple grid-points are inside your polygon.

To see whether a point is inside a polygon, there are plenty of methods, here is just one of them from SO: Check a point location in a particular area on html canvas

By the way: you don't need to consider trivial gridpoints outside of your polygon (those with x-coordinates higher or smaller than the max/min x-coordinates of your polygon and those with y-coordinates higher or smaller than the max/min y-coordiantes of your polygon).

EDIT: I made this image:
enter image description here

What you do is you check all points on the grid.
The black and blue points are ignored because they are outside or on the borders of your grid.
Only the green point is interesting.
From there, you simply follow the grid in all directions until you hit an intersection with the polygon borders.
This is either a border point - blue - or an intersection - orange.
It's easy to find the intersection of a line and borders of a polygon, so I won't go into the detail here.
Then that's it, you have all the points which will define the inner polygons.

Here, you can also immediately spot the problem when you have multiple grid points (green points) inside the polygon because you'll have to choose which polygons inside the big polygon you want.
That's quite complicated to solve and I think it's out of scope for this question.

Community
  • 1
  • 1
Matt Ko
  • 969
  • 7
  • 14
  • I'm not following your idea...could you do a demo? – markE Mar 10 '15 at 22:12
  • this will only work for this very simple case, this problem is much more complicated than that, see: http://codepen.io/anon/pen/OPBXjX – kruczy Mar 11 '15 at 10:35
  • in this case, I'm not sure how you actually want to split your polygon. For concave polygons, your question doesn't really make sense to me... – Matt Ko Mar 11 '15 at 10:42
  • 1
    And if you want to do polygon clipping (like so: http://en.wikipedia.org/wiki/Weiler%E2%80%93Atherton_clipping_algorithm), then I believe it's going to be very inefficient in javascript. It looks like there are a few libraries out there which might help you: http://polyk.ivank.net/?p=demos, http://sourceforge.net/projects/jsclipper/ – Matt Ko Mar 11 '15 at 11:00
0

To solve this you can treat every grid cell as a separate polygon and intersect them with your polygon one by one, the algorithm to do the intersection is described here

remember that for each grid cell you could get any number of new polygons see this case:

case

kruczy
  • 791
  • 4
  • 8