#pragma once

#include <math.h>

class point {
public:
    __inline point();
    __inline point(float x, float y, float z);

    __inline void operator=(const point &other);
    __inline void operator=(const float *vect);

    __inline operator const float *() const;

    __inline void eq(float x, float y, float z);
    __inline void eq(const point &p, float len);

    __inline void sub(const point &p0, const point &p1);

    __inline void add(const point &p0, const point &p1);
    __inline void add(const point &p0, float scale);

    __inline float dot(const point &p) const;

    __inline void copyto(float *vect) const;

    __inline float normalize();
    __inline float length() const;
    __inline void zero();

    float x, y, z;
};

point::point() {

}

point::point(float x, float y, float z) {
    this->x = x;
    this->y = y;
    this->z = z;
}

void point::operator=(const point &other) {
    x = other.x;
    y = other.y;
    z = other.z;
}

void point::operator=(const float *vect) {
    x = vect[0];
    y = vect[1];
    z = vect[2];
}

point::operator const float *() const {
    return (float *)this;
}

void point::eq(float x, float y, float z) {
    this->x = x;
    this->y = y;
    this->z = z;
}

void point::copyto(float *vect) const {
    vect[0] = x;
    vect[1] = y;
    vect[2] = z;
}

void point::sub(const point &p0, const point &p1) {
    x = p0.x - p1.x;
    y = p0.y - p1.y;
    z = p0.z - p1.z;
}

float point::normalize() {
    float len = float(sqrt(x * x + y * y + z * z));
    if (len > 0.0001) {
        x /= len;
        y /= len;
        z /= len;
    }

    return len;
}

float point::length() const {
    return float(sqrt(x * x + y * y + z * z));
}

float point::dot(const point &p) const {
    return p.x * x + p.y * y + p.z * z;
}

void point::add(const point &p0, const point &p1) {
    x = p0.x + p1.x;
    y = p0.y + p1.y;
    z = p0.z + p1.z;
}

void point::add(const point &p0, float scale) {
    x += p0.x * scale;
    y += p0.y * scale;
    z += p0.z * scale;
}

void point::eq(const point &p, float len) {
    x = p.x * len;
    y = p.y * len;
    z = p.z * len;
}

void point::zero() {
    x = y = z = 0.0f;
}

