<commit_before>
#include "image.h"
#include "pnm.h"
#include "ifs.h"
#include "vec3.h"
#include "camera.h"
#include "quaternion.h"

#include <vector>
#include <string>

#include <cmath>

#include <boost/program_options.hpp>
namespace po = boost::program_options;

typedef IFS::IFS< Vec3d > myIFS;

typedef MathVector<unsigned char,3> RGB;    // RGB color value
#define PI 3.141592653589793238462643




// Image Projection allows to rayintersect with an 
// (panoramic) image taken from a known pose
class ImageProjection
{
public:
    virtual Vec3d getPosition() = 0;
    virtual RGB   getColorProjection(const Vec3d &pos) const = 0;
};


class SphericalPanoramaImageProjection : public ImageProjection
{
private:
    Camera<double> camera;
    Image pano;

public:
    Vec2d azimuthRange;
    Vec2d elevationRange;

    SphericalPanoramaImageProjection() 
        : azimuthRange(0, 2 * PI), elevationRange(-PI/2,PI/2)
    {
    }

    inline void setPanoramicImage(const Image &pi) { pano = pi; }
    inline void setCenter(const Vec3d &center)     { camera.setPosition(center); }
    inline void setPose(const Vec3d &right, const Vec3d &up, const Vec3d &front) 
    { 
        camera.setOrientation(right, up, front);
    }

    inline const Image & img()  { return pano; }

    inline bool isValid() const { return pano.isValid(); }
    inline Vec3d getPosition()  { return camera.getPosition(); }

    inline bool applyRotation(Quaterniond &quat)
    {
        camera.applyRotation(quat);
        return true;
    }


    RGB   getColorProjection(const Vec3d &pos) const
    {
        // get vector from camera center to position
        Vec3d rayWorld = pos - camera.getPosition();

        // transform to camera orientation
        Vec3d ray = camera.world2cam() * rayWorld;

        // normalize vector to get the intersection on the unit sphere
        ray.normalize();

        // pano-x = azimuth   = phi   = atan2(y,x) normalized to [0,1]
        // pano-y = elevation = theta = arccos(z/sqrt(x^2+y^2+z^2)) normalized to [-1,1], norm can be neglected 
        //                                         since (x,y,z) is already normalized
        // physical notation, theta=inclination/elevation=pano-x ,phi = azimuth = pano-y
        Vec3d spherical = cart2spher(ray);

        // get relative value to  bounds
        const double tx = (spherical[0] - azimuthRange[0]) / (azimuthRange[1] - azimuthRange[0]);
        const double ty = (spherical[1] - elevationRange[0]) / (elevationRange[1] - elevationRange[0]);

        // pano lookup, nearest neighbor for now.. TODO: interpolation
        RGB pixel(0,0,0);
        if (tx >= 0.0 && tx <= 1.0 && ty >= 0.0 && ty <= 1.0)
        {
            pixel[0] = pano(tx*pano.width(), ty*pano.height(), 0);
            pixel[1] = pano(tx*pano.width(), ty*pano.height(), 1);
            pixel[2] = pano(tx*pano.width(), ty*pano.height(), 2);
        }
        return pixel;
    }

    // COORDINATE SYSTEM CONVERSIONS

    // cartesian coordinates: Vec3 [ x, y, z ]
    // spherical coordinates: Vec3 [ azimuth , inclination , radius ]
    Vec3d spher2cart(const Vec3d &spc) const
    {    
        return Vec3d(
            spc[2] * sin(spc[1]) * cos(spc[0]),
            spc[2] * sin(spc[1]) * sin(spc[0]),
            spc[2] * cos(spc[1])
        );
    }

    // cartesian to spherical coordinates
    Vec3d cart2spher(const Vec3d &cart) const
    {
        double radius    = cart.length();
        double inclination = acos(cart[2] / radius);
        double azimuth   = atan2(cart[1], cart[0]);
        if (azimuth < 0) azimuth += 2.0*PI;

        assert(inclination >= 0.0 && inclination <= PI);
        assert(azimuth >= 0.0 && azimuth <= 2.0*PI);

        return Vec3d(azimuth, inclination, radius);

    }
    
    // export to textured sphere
    myIFS exportToIFS(const double r = 1.0, const double numpts = 10)
    {
        myIFS result;
        result.useTextureCoordinates = true;

        const double inclinationStep = (PI / numpts);
        const double azimuthStep = (2.0*PI / numpts);

        const Vec3d delta1(azimuthStep, 0, 0);
        const Vec3d delta2(azimuthStep, inclinationStep, 0);
        const Vec3d delta3(0, inclinationStep, 0);

        const Vec2f txd1(azimuthStep, 0);<commit_msg>fixes<commit_after>
#include "image.h"
#include "pnm.h"
#include "ifs.h"
#include "vec3.h"
#include "camera.h"
#include "quaternion.h"

#include <vector>
#include <string>

#include <cmath>

#include <boost/program_options.hpp>
namespace po = boost::program_options;

typedef IFS::IFS< Vec3d > myIFS;

typedef MathVector<unsigned char,3> RGB;    // RGB color value
#define PI 3.141592653589793238462643




// Image Projection allows to rayintersect with an 
// (panoramic) image taken from a known pose
class ImageProjection
{
public:
    virtual Vec3d getPosition() = 0;
    virtual RGB   getColorProjection(const Vec3d &pos) const = 0;
};


class SphericalPanoramaImageProjection : public ImageProjection
{
private:
    Camera<double> camera;
    Image pano;

public:
    Vec2d azimuthRange;
    Vec2d elevationRange;

    SphericalPanoramaImageProjection() 
        : azimuthRange(0, 2 * PI), elevationRange(-PI/2,PI/2)
    {
    }

    inline void setPanoramicImage(const Image &pi) { pano = pi; }
    inline void setCenter(const Vec3d &center)     { camera.setPosition(center); }
    inline void setPose(const Vec3d &right, const Vec3d &up, const Vec3d &front) 
    { 
        camera.setOrientation(right, up, front);
    }

    inline const Image & img()  { return pano; }

    inline bool isValid() const { return pano.isValid(); }
    inline Vec3d getPosition()  { return camera.getPosition(); }

    inline bool applyRotation(Quaterniond &quat)
    {
        camera.applyRotation(quat);
        return true;
    }


    RGB   getColorProjection(const Vec3d &pos) const
    {
        // get vector from camera center to position
        Vec3d rayWorld = pos - camera.getPosition();

        // transform to camera orientation
        Vec3d ray = camera.world2cam() * rayWorld;

        // normalize vector to get the intersection on the unit sphere
        ray.normalize();

        // pano-x = azimuth   = phi   = atan2(y,x) normalized to [0,1]
        // pano-y = elevation = theta = arccos(z/sqrt(x^2+y^2+z^2)) normalized to [-1,1], norm can be neglected 
        //                                         since (x,y,z) is already normalized
        // physical notation, theta=inclination/elevation=pano-x ,phi = azimuth = pano-y
        Vec3d spherical = cart2spher(ray);

        // get relative value to  bounds
        const double tx = (spherical[0] - azimuthRange[0]) / (azimuthRange[1] - azimuthRange[0]);
        const double ty = (spherical[1] - elevationRange[0]) / (elevationRange[1] - elevationRange[0]);

        // pano lookup, nearest neighbor for now.. TODO: interpolation
        RGB pixel(0,0,0);
        if (tx >= 0.0 && tx <= 1.0 && ty >= 0.0 && ty <= 1.0)
        {
            pixel[0] = pano(tx*pano.width(), ty*pano.height(), 0);
            pixel[1] = pano(tx*pano.width(), ty*pano.height(), 1);
            pixel[2] = pano(tx*pano.width(), ty*pano.height(), 2);
        }
        return pixel;
    }

    // COORDINATE SYSTEM CONVERSIONS

    // cartesian coordinates: Vec3 [ x, y, z ]
    // spherical coordinates: Vec3 [ azimuth , inclination , radius ]
    Vec3d spher2cart(const Vec3d &spc) const
    {    
        return Vec3d(
            spc[2] * sin(spc[1]) * cos(spc[0]),
            spc[2] * sin(spc[1]) * sin(spc[0]),
            -spc[2] * cos(spc[1])
        );
    }

    // cartesian to spherical coordinates
    Vec3d cart2spher(const Vec3d &cart) const
    {
        double radius    = cart.length();
        double inclination = acos(cart[2] / radius);
        double azimuth   = atan2(cart[1], cart[0]);
        if (azimuth < 0) azimuth += 2.0*PI;

        assert(inclination >= 0.0 && inclination <= PI);
        assert(azimuth >= 0.0 && azimuth <= 2.0*PI);

        return Vec3d(azimuth, inclination, radius);

    }
    
    // export to textured sphere
    myIFS exportToIFS(const double r = 1.0, const double numpts = 100)
    {
        myIFS result;
        result.useTextureCoordinates = true;

        const double inclinationStep = (PI / numpts);
        const double azimuthStep = (2.0*PI / numpts);

        const Vec3d delta1(azimuthStep, 0, 0);
        const Vec3d delta2(azimuthStep, inclinationStep, 0);
        const Vec3d delta3(0, inclinationStep, 0);

        const Vec2f txd1(azimuthStep, 0);
{'fraction_non_alphanumeric': 0.12391762227942897, 'fraction_numerical': 0.03124268663702317, 'mean_word_length': 2.4772172497965825, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5164095', 'n_tokens_mistral': 3006, 'n_tokens_neox': 2748, 'n_words': 735}