Polygon Tools - Winding Rules
http://www.glprogramming.com/red/chapter11.html
by timknip
HTML
<script src="https://fpcdn.s3.amazonaws.com/apps/polygon-tools/0.4.0/polygon-tools.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.5.1/pixi.min.js"></script>
<a href="#" onclick="set1(this)">POLYGON SET 1</a>
<a href="#" onclick="set2(this)">polygon set 2</a>
<a href="#" onclick="set3(this)">polygon set 3</a>
<pre>see http://www.glprogramming.com/red/chapter11.html</pre>
<img src="https://content.screencast.com/users/TimKnip/folders/Jing/media/dfad1aee-5b03-4cb2-bdce-9a4f4ef12234/2017-04-26_1920.png" />
<hr />
<a href="#" onclick="odd(this)">ODD</a>
<a href="#" onclick="nonzero(this)">nonzero</a>
<a href="#" onclick="positive(this)">positive</a>
<a href="#" onclick="negative(this)">negative</a>
<a href="#" onclick="abs_geq_two(this)">abs_geq_two</a>
<hr />
JavaScript
/**
* The winding rule classifies a region as inside if its winding number
* belongs to the chosen category (odd, nonzero, positive, negative,
* or "absolute value of greater than or equal to two").
* The odd and nonzero rules are common ways to define the interior.
* The positive, negative, and "absolute value>=2" winding rules have
* some limited use for polygon CSG (computational solid geometry) operations.
*/
var stage = new PIXI.Container();
var renderer = new PIXI.WebGLRenderer(500, 500);
document.body.appendChild(renderer.view);
const POLY_A = [
[0, 0],
[400, 0],
[400, 400],
[0, 400]
];
const POLY_B = [
[100, 100],
[300, 100],
[300, 300],
[100, 300]
];
const POLY_B_REV = [
[100, 300],
[300, 300],
[300, 100],
[100, 100]
];
const POLY_C = [
[150, 150],
[250, 150],
[250, 250],
[150, 250]
];
const POLY_C_REV = [
[150, 250],
[250, 250],
[250, 150],
[150, 150]
];
const POLY_D = [
[100, 100],
[300, 100],
[300, 350],
[100, 350]
];
const POLY_E = [
[50, 200],
[350, 200],
[350, 250],
[50, 250]
];
const POLY_F = [
[200, 400],
[160, 150],
[240, 150]
];
let options = {
polygons: [POLY_A, POLY_B, POLY_C],
holes: [],
windingRule: PolygonTools.tesselator.GLU_TESS_WINDING_ODD,
boundaryOnly: false,
normal: null,
autoWinding: false
};
function randomColor () {
let r = Math.round(Math.random() * 0xff),
g = Math.round(Math.random() * 0xff),
b = Math.round(Math.random() * 0xff);
return r << 16 | g << 8 | b;
}
clearStage = function () {
for (var i = stage.children.length - 1; i >= 0; i--) {
stage.removeChild(stage.children[i]);
};
renderer.render(stage);
}
run = function () {
let result = PolygonTools.tesselator.run(options);
clearStage();
result.forEach(triangles => {
var paths = triangles.map(triangle => {
return triangle.reduce((p, pt) => {
return p.concat(pt.map(p => p));
}, []);
});
var g = new...