Skip to content

File bench_bounding_box.cpp

File List > benchmark > metrics > implementations > bench_bounding_box.cpp

Go to the documentation of this file

#include "bench_bounding_box.h"

#include <iostream>
#include <ostream>

namespace Argos {

    BoundingBox BoundingBoxComputer::compute(const std::vector<Vector3D<double>>& points) {
        BoundingBox box;

        if (points.empty()) {
            box.min = { 0,0,0 };
            box.max = { 0,0,0 };
            return box;
        }

        double minX = std::numeric_limits<double>::max();
        double minY = std::numeric_limits<double>::max();
        double minZ = std::numeric_limits<double>::max();

        double maxX = -std::numeric_limits<double>::max();
        double maxY = -std::numeric_limits<double>::max();
        double maxZ = -std::numeric_limits<double>::max();

        for (const auto& p : points) {
            if (p.x < minX) minX = p.x;
            if (p.y < minY) minY = p.y;
            if (p.z < minZ) minZ = p.z;

            if (p.x > maxX) maxX = p.x;
            if (p.y > maxY) maxY = p.y;
            if (p.z > maxZ) maxZ = p.z;
        }

        box.min = { minX, minY, minZ };
        box.max = { maxX, maxY, maxZ };

        return box;
    }

    Vector3D<double> BoundingBox::size() const {
        return max - min;
    }

    double BoundingBox::volume() const {
        auto s = size();
        return s.x * s.y * s.z;
    }

    double BoundingBox::diagonal() const {
        return (max - min).norm();
    }

    Vector3D<double> BoundingBox::center() const {
        return (min + max) / 2.0;
    }

    double centerDistance(const BoundingBox& a, const BoundingBox& b) {
        return (a.center() - b.center()).norm();
    }

    double normalizedCenterDistance(const BoundingBox& a, const BoundingBox& b) {
        double diag = (a.diagonal() + b.diagonal()) / 2.0; // moyenne des diagonales (taille) des deux bounding box

        if (diag == 0.0)
            return 0.0;

        return centerDistance(a, b) / diag;
    }


    void BoundingBoxMetric::compute(const Mesh& original, const Mesh& reconstructed, benchmark::State& state) const {

        const std::string prefix = getName();


        // Extraction des points
        const auto& originalPoints = original.getVertices();
        if (originalPoints.empty()) {
            std::cout << prefix << " - ERREUR - Aucun points de la mesh d'origine retrouvé." << std::endl;
            return;
        }
        const auto& reconstructedPoints = reconstructed.getVertices();

        // Calcul des bounding boxes
        const BoundingBox boxA = BoundingBoxComputer::compute(originalPoints);
        const BoundingBox boxB = BoundingBoxComputer::compute(reconstructedPoints);

        // Dimensions
        //const auto sizeA = boxA.size();
        //const auto sizeB = boxB.size();

        // Volumes
        //state.counters[prefix + ".VolumeA"] = boxA.volume();
        //state.counters[prefix + ".VolumeB"] = boxB.volume();

        // Difference de volume
        double volumeA = boxA.volume();
        double volumeB = boxB.volume();

        double relativeError = std::abs(volumeA - volumeB) / volumeA;

        state.counters[prefix + ".VolumeDiffPct"] = relativeError * 100.0;

        // Diagonales
        //state.counters[prefix + ".DiagA"] = boxA.diagonal();
        //state.counters[prefix + ".DiagB"] = boxB.diagonal();

        // Taille (reconstructed)
        //state.counters[prefix + ".SizeX"] = sizeB.x;
        //state.counters[prefix + ".SizeY"] = sizeB.y;
        //state.counters[prefix + ".SizeZ"] = sizeB.z;

        // Distance entre centres
        state.counters[prefix + ".CenterDist"] = centerDistance(boxA, boxB);

        // Distance normalisee
        //state.counters[prefix + ".CenterDistNorm"] = normalizedCenterDistance(boxA, boxB);
    }
}