in packages/maker.js/src/core/measure.ts [747:826]
export function boundingHexagon(modelToMeasure: IModel): IBoundingHex {
var clone = cloneObject(modelToMeasure) as IModel;
model.originate(clone);
var originalMeasure = modelExtents(clone);
var bounds: IAngledBoundary[] = [];
var scratch: IModel = { paths: {} };
model.center(clone);
function result(radius: number, origin: IPoint, notes: string): IBoundingHex {
return {
radius: radius,
paths: new models.Polygon(6, radius, 30).paths,
origin: point.add(origin, originalMeasure.center),
//models: { scratch: scratch },
notes: notes
};
}
var boundRotations = [[90, -90], [-60, -30], [-60, 30]];
while (boundRotations.length) {
var rotation = boundRotations.shift();
var bound = getAngledBounds(bounds.length, clone, rotation[0], rotation[1]);
var side = solvers.equilateralSide(bound.width / 2);
if (side >= bound.height) {
return result(side, bound.center, 'solved by bound ' + bounds.length);
}
bounds.push(bound);
}
//model.rotate(clone, 30);
//scratch.models = { clone: clone };
//check for a circular solution
if (isCircular(bounds)) {
return result(solvers.equilateralSide(bounds[0].width / 2), bounds[0].center, 'solved as circular');
}
var perimeters = bounds.map(b => b.top).concat(bounds.map(b => b.bottom));
perimeters.forEach((p, i) => {
scratch.paths[i] = p;
//converge alternate lines to form two triangles
path.converge(perimeters[loopIndex(6, i + 2)], p, true);
});
bounds.forEach((b, i) => {
scratch.paths['m' + i] = b.middle;
});
var boundCopy = bounds.slice();
var solution: IHexSolution;
//solve a hexagon for every tip, keeping the smallest one
for (var i = 0; i < 6; i++) {
//rotate the scratch area so that we always reference the tip at polar 0
if (i > 0) {
perimeters.push(perimeters.shift());
boundCopy.push(boundCopy.shift());
model.rotate(scratch, -60);
}
var s = hexSolution(perimeters, boundCopy);
if (s) {
if (!solution || s.radius < solution.radius) {
solution = s;
solution.index = i;
}
}
}
var p = point.rotate(solution.origin, solution.index * 60);
return result(solution.radius, p, 'solved by ' + solution.index + ' as ' + solution.type);
}