export function boundingHexagon()

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);
    }