mirror of
https://github.com/liabru/matter-js.git
synced 2024-11-27 09:50:52 -05:00
added Vertices.chamfer (for rounding corners)
This commit is contained in:
parent
f1db9df854
commit
120157d6fd
2 changed files with 95 additions and 0 deletions
|
@ -30,6 +30,13 @@ var Bodies = {};
|
|||
vertices: Vertices.fromPath('L 0 0 L ' + width + ' 0 L ' + width + ' ' + height + ' L 0 ' + height)
|
||||
};
|
||||
|
||||
if (options.chamfer) {
|
||||
var chamfer = options.chamfer;
|
||||
rectangle.vertices = Vertices.chamfer(rectangle.vertices, chamfer.radius,
|
||||
chamfer.quality, chamfer.qualityMin, chamfer.qualityMax);
|
||||
delete options.chamfer;
|
||||
}
|
||||
|
||||
return Body.create(Common.extend({}, rectangle, options));
|
||||
};
|
||||
|
||||
|
@ -60,6 +67,13 @@ var Bodies = {};
|
|||
vertices: Vertices.fromPath('L 0 0 L ' + x1 + ' ' + (-height) + ' L ' + x2 + ' ' + (-height) + ' L ' + x3 + ' 0')
|
||||
};
|
||||
|
||||
if (options.chamfer) {
|
||||
var chamfer = options.chamfer;
|
||||
trapezoid.vertices = Vertices.chamfer(trapezoid.vertices, chamfer.radius,
|
||||
chamfer.quality, chamfer.qualityMin, chamfer.qualityMax);
|
||||
delete options.chamfer;
|
||||
}
|
||||
|
||||
return Body.create(Common.extend({}, trapezoid, options));
|
||||
};
|
||||
|
||||
|
@ -126,6 +140,13 @@ var Bodies = {};
|
|||
vertices: Vertices.fromPath(path)
|
||||
};
|
||||
|
||||
if (options.chamfer) {
|
||||
var chamfer = options.chamfer;
|
||||
polygon.vertices = Vertices.chamfer(polygon.vertices, chamfer.radius,
|
||||
chamfer.quality, chamfer.qualityMin, chamfer.qualityMax);
|
||||
delete options.chamfer;
|
||||
}
|
||||
|
||||
return Body.create(Common.extend({}, polygon, options));
|
||||
};
|
||||
|
||||
|
|
|
@ -204,4 +204,78 @@ var Vertices = {};
|
|||
return vertices;
|
||||
};
|
||||
|
||||
/**
|
||||
* Chamfers a set of vertices by giving them rounded corners, returns a new set of vertices.
|
||||
* The radius parameter is a single number or an array to specify the radius for each vertex.
|
||||
* @method chamfer
|
||||
* @param {vertices} vertices
|
||||
* @param {number[]} radius
|
||||
* @param {number} quality
|
||||
* @param {number} qualityMin
|
||||
* @param {number} qualityMax
|
||||
*/
|
||||
Vertices.chamfer = function(vertices, radius, quality, qualityMin, qualityMax) {
|
||||
radius = radius || [8];
|
||||
|
||||
if (!radius.length)
|
||||
radius = [radius];
|
||||
|
||||
// quality defaults to -1, which is auto
|
||||
quality = (typeof quality !== 'undefined') ? quality : -1;
|
||||
qualityMin = qualityMin || 2;
|
||||
qualityMax = qualityMax || 14;
|
||||
|
||||
var centre = Vertices.centre(vertices),
|
||||
newVertices = [];
|
||||
|
||||
for (var i = 0; i < vertices.length; i++) {
|
||||
var prevVertex = vertices[i - 1 >= 0 ? i - 1 : vertices.length - 1],
|
||||
vertex = vertices[i],
|
||||
nextVertex = vertices[(i + 1) % vertices.length],
|
||||
currentRadius = radius[i < radius.length ? i : radius.length - 1];
|
||||
|
||||
if (currentRadius === 0) {
|
||||
newVertices.push(vertex);
|
||||
continue;
|
||||
}
|
||||
|
||||
var prevNormal = Vector.normalise({
|
||||
x: vertex.y - prevVertex.y,
|
||||
y: prevVertex.x - vertex.x
|
||||
});
|
||||
|
||||
var nextNormal = Vector.normalise({
|
||||
x: nextVertex.y - vertex.y,
|
||||
y: vertex.x - nextVertex.x
|
||||
});
|
||||
|
||||
var diagonalRadius = Math.sqrt(2 * Math.pow(currentRadius, 2)),
|
||||
radiusVector = Vector.mult(Common.clone(prevNormal), currentRadius),
|
||||
midNormal = Vector.normalise(Vector.mult(Vector.add(prevNormal, nextNormal), 0.5)),
|
||||
scaledVertex = Vector.sub(vertex, Vector.mult(midNormal, diagonalRadius));
|
||||
|
||||
var precision = quality;
|
||||
|
||||
if (quality === -1) {
|
||||
// automatically decide precision
|
||||
precision = Math.pow(currentRadius, 0.32) * 1.75;
|
||||
}
|
||||
|
||||
precision = Common.clamp(precision, qualityMin, qualityMax);
|
||||
|
||||
// use an even value for precision, more likely to reduce axes by using symmetry
|
||||
if (precision % 2 === 1)
|
||||
precision += 1;
|
||||
|
||||
var alpha = Math.acos(Vector.dot(prevNormal, nextNormal)),
|
||||
theta = alpha / precision;
|
||||
|
||||
for (var j = 0; j < precision; j++) {
|
||||
newVertices.push(Vector.add(Vector.rotate(radiusVector, theta * j), scaledVertex));
|
||||
}
|
||||
}
|
||||
|
||||
return newVertices;
|
||||
};
|
||||
|
||||
})();
|
Loading…
Reference in a new issue