# data[].attributes.body
7002219 - Thomas Itel (Barycentric)

# data[].attributes.body
7002297 - Louis Giguet

# data[].attributes.attachment_link.readable_text
/** Datei: "assignment20221017.cpp"
 *  Autor: Louis Dorweiler
 *  Stand: "2022-10-17"
 */
#include <iostream>
#include <glm/vec2.hpp>

const float SCREEN_HEIGHT = 100.0f;
const float SCREEN_WIDTH = 100.0f;
// Image size 100 x 100
// -1 <- v0, v1, v2 <- 1: screen coordinates v0(-0.3, -0.6), v1(0, 0.7), v2(0.3, 0.6)
// Convert this screen coordinate to raster coordinates (via NDC) refer page 10
// Test inside / outside for p1, p2


glm::vec2 convert_from_screen_to_ndc(const glm::vec2 &p);
glm::vec2 convert_from_ndc_to_raster_space(const glm::vec2 &p);
bool left_or_right_from_edge(const glm::vec2 &a, const glm::vec2 &b, const glm::vec2 &p);
bool is_inside_triangle(const glm::vec2 &a, const glm::vec2 &b, const glm::vec2 &c, const glm::vec2 &p);

int main(int argc, char const *argv[])
{
    const glm::vec2 v0(-0.3f, -0.6f);
    const glm::vec2 v1(0.0f, -0.7f);
    const glm::vec2 v2(0.3f, 0.6f);
    const glm::vec2 v0_ndc = convert_from_screen_to_ndc(v0);
    const glm::vec2 v1_ndc = convert_from_screen_to_ndc(v1);
    const glm::vec2 v2_ndc = convert_from_screen_to_ndc(v2);

    const glm::vec2 v0_raster = convert_from_ndc_to_raster_space(v0_ndc);
    const glm::vec2 v1_raster = convert_from_ndc_to_raster_space(v1_ndc);
    const glm::vec2 v2_raster = convert_from_ndc_to_raster_space(v2_ndc);
    
    const glm::vec2 p1(50.0f, 50.0f);
    const glm::vec2 p2(90.0f, 50.0f);

    std::cout << is_inside_triangle(v0_raster, v1_raster, v2_raster, p1) << "\n";
    std::cout << is_inside_triangle(v0_raster, v1_raster, v2_raster, p2) << "\n";
}

glm::vec2 convert_from_screen_to_ndc(const glm::vec2 &p)
{
    glm::vec2 p_in_ndc((p.x + 1)/2.f, (1 - p.y)/2.f);
    return p_in_ndc;
}
glm::vec2 convert_from_ndc_to_raster_space(const glm::vec2 &p)
{
    glm::vec2 p_in_raster(p.x * SCREEN_WIDTH, p.y * SCREEN_HEIGHT);
    if ((int)(p_in_raster.x) == (int)(SCREEN_WIDTH))
        p_in_raster.x = SCREEN_WIDTH - 1.0f;
    if ((int)(p_in_raster.y) == (int)(SCREEN_HEIGHT))
        p_in_raster.y = SCREEN_HEIGHT - 1.0f;
    return p_in_raster;
}

bool left_or_right_from_edge(const glm::vec2 &a, const glm::vec2 &b, const glm::vec2 &p)
{
    return ((p.x - a.x) * (b.y - a.y) - 
        (p.y - a.y) * (b.x - a.x)) >= 0;
}
bool is_inside_triangle(const glm::vec2 &a, const glm::vec2 &b, 
    const glm::vec2 &c, const glm::vec2 &p)
{
    return left_or_right_from_edge(a, b, p) && 
        left_or_right_from_edge(b, c, p) && 
        left_or_right_from_edge(c, a, p);
}

# data[].attributes.headline
7002222 - Briag FROUX ROTRU (Barycentric)

# data[].attributes.subject
7002222 - Briag FROUX ROTRU (Barycentric)

# data[].attributes.body
little fix

# data[].attributes.headline
7002235 - Edouard S. (Barycentric) (fixed)

# data[].attributes.subject
7002235 - Edouard S. (Barycentric) (fixed)

# data[].attributes.headline
7002272 - Gabriel Medoukali (Barycentric)

# data[].attributes.subject
7002272 - Gabriel Medoukali (Barycentric)

# data[].attributes.attachment_link.readable_text
/** Datei: "assignment20221019.cpp"
 *  Autor: Louis Dorweiler
 *  Stand: "2022-10-19"
 */
#include <iostream>
#include <glm/vec3.hpp>
#define GLM_ENABLE_EXPERIMENTAL


const float SCREEN_HEIGHT = 100.0f;
const float SCREEN_WIDTH = 100.0f;

glm::vec3 convert_from_screen_to_ndc(const glm::vec3 &p);
glm::vec3 convert_from_ndc_to_raster_space(const glm::vec3 &p);

bool left_or_right_from_edge(const glm::vec3 &a, const glm::vec3 &b, const glm::vec3 &p);
bool is_inside_triangle(const glm::vec3 &a, const glm::vec3 &b, 
    const glm::vec3 &c, const glm::vec3 &p);

float get_area_triangle_times_2(const glm::vec3 &a, const glm::vec3 &b, const glm::vec3 &c);
float get_lambda(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3, 
    const glm::vec3 &a, const glm::vec3 &b, const glm::vec3 &c);
float z_of_point_in_triangle(const glm::vec3 &a, const glm::vec3 &b, 
    const glm::vec3 &c, const glm::vec3 &p);

int main(int argc, char const *argv[])
{
    // Screen Space
    const glm::vec3 v0(-0.3f, -0.6f, abs(-10.0f));
    const glm::vec3 v1(0.0f, 0.7f, abs(-2.0f));
    const glm::vec3 v2(0.3f, -0.6f, abs(-10.0f));
    // NDC
    const glm::vec3 v0_ndc = convert_from_screen_to_ndc(v0);
    const glm::vec3 v1_ndc = convert_from_screen_to_ndc(v1);
    const glm::vec3 v2_ndc = convert_from_screen_to_ndc(v2);

    // Raster
    const glm::vec3 v0_raster = convert_from_ndc_to_raster_space(v0_ndc);
    const glm::vec3 v1_raster = convert_from_ndc_to_raster_space(v1_ndc);
    const glm::vec3 v2_raster = convert_from_ndc_to_raster_space(v2_ndc);
    
    const glm::vec3 p1(50.0f, 50.0f, 0.0f);

    std::cout << "Value of p.z: " << z_of_point_in_triangle(v0_raster, v1_raster, v2_raster, p1) << "\n";
}

glm::vec3 convert_from_screen_to_ndc(const glm::vec3 &p)
{
    glm::vec3 p_in_ndc((p.x + 1)/2.0f, (1 - p.y)/2.0f, p.z);
    return p_in_ndc;
}
glm::vec3 convert_from_ndc_to_raster_space(const glm::vec3 &p)
{
    glm::vec3 p_in_raster(p.x * SCREEN_WIDTH, p.y * SCREEN_HEIGHT, p.z);
    if ((int)(p_in_raster.x) == (int)(SCREEN_WIDTH))
        p_in_raster.x = SCREEN_WIDTH - 1.0f;
    if ((int)(p_in_raster.y) == (int)(SCREEN_HEIGHT))
        p_in_raster.y = SCREEN_HEIGHT - 1.0f;
    return p_in_raster;
}

bool left_or_right_from_edge(const glm::vec3 &a, const glm::vec3 &b, const glm::vec3 &p)
{
    return ((p.x - a.x) * (b.y - a.y) - 
        (p.y - a.y) * (b.x - a.x)) >= 0;
}
bool is_inside_triangle(const glm::vec3 &a, const glm::vec3 &b, 
    const glm::vec3 &c, const glm::vec3 &p)
{
    return left_or_right_from_edge(a, b, p) && 
        left_or_right_from_edge(b, c, p) && 
        left_or_right_from_edge(c, a, p);
}

float get_area_triangle_times_2(const glm::vec3 &a, const glm::vec3 &b, const glm::vec3 &c) 
{
    return (c.x - a.x) * (b.y - a.y) - 
        (c.y - a.y) * (b.x - a.x);
}

float get_lambda(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3, 
    const glm::vec3 &a, const glm::vec3 &b, const glm::vec3 &c)
{
    return (get_area_triangle_times_2(v1, v2, v3) / get_area_triangle_times_2(a, c, b));
}

float z_of_point_in_triangle(const glm::vec3 &a, const glm::vec3 &b, 
    const glm::vec3 &c, const glm::vec3 &p)
{
    float z = 1/((get_lambda(a, p, b, a, b, c)) / (a.z) + 
              (get_lambda(b, p, c, a, b, c)) / (b.z) + 
              (get_lambda(c, p, a, a, b, c)) / (c.z));
    return z;
}

# data[].attributes.headline
7002263 - Allan DEBEVE (BARYCENTRIC FIX)

# data[].attributes.subject
7002263 - Allan DEBEVE (BARYCENTRIC FIX)

# data[].attributes.headline
7002222 - Briag FROUX ROTRU (barycentric - source code)

# data[].attributes.subject
7002222 - Briag FROUX ROTRU (barycentric - source code)

# data[].attributes.attachment_link.readable_text
#include <iostream>
#include <vector>
#include <glm/glm.hpp>
#include <glm/gtx/string_cast.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#define WIDTH 100
#define HEIGHT 100

float edge(const glm::vec2 &v0, const glm::vec2 &v1, const glm::vec2 &p) {
    return ((p.x - v0.x) * (v1.y - v0.y) - (p.y - v0.y) * (v1.x - v0.x));
}

bool is_in_triangle(const std::vector<glm::vec2> &triangle, const glm::vec2 &p) {
    return edge(triangle[0], triangle[2], p) &&
        edge(triangle[2], triangle[1], p) &&
        edge(triangle[1], triangle[0], p);
}

int main() {
    std::vector<glm::vec3> vectors = {
        glm::vec3(-0.3f, -0.6f, -10.0f),
        glm::vec3(0.0f, 0.7f, -2.0f),
        glm::vec3(0.3f, -0.6f, -10.0f)
    };
    std::vector<glm::vec3> ndc_vectors;
    std::vector<glm::vec3> raster_vectors;
    glm::vec3 p1(50.0f, 50.0f, 0.0f);
    std::vector<float> lambda;
    
    // Convert to NDC
    for (glm::vec3 &vec: vectors) {
        ndc_vectors.push_back(glm::vec3((vec.x / vec.z + 1) / 2, (1 - vec.y / vec.z) / 2, vec.z));
    }
    // Convert to raster
    for (glm::vec3 &vec : ndc_vectors) {
        glm::vec3 new_vec = glm::vec3(vec.x * WIDTH, vec.y * HEIGHT, -vec.z);
        
        if (new_vec.x == WIDTH)
            new_vec.x = WIDTH - 1;
        if (new_vec.y == HEIGHT)
            new_vec.y = HEIGHT - 1;
        raster_vectors.push_back(new_vec);
    }
    // Compute lambda
    lambda.push_back(edge(raster_vectors[0], raster_vectors[1], p1) / edge(raster_vectors[0], raster_vectors[1], raster_vectors[2]));
    lambda.push_back(edge(raster_vectors[1], raster_vectors[2], p1) / edge(raster_vectors[0], raster_vectors[1], raster_vectors[2]));
    lambda.push_back(edge(raster_vectors[2], raster_vectors[0], p1) / edge(raster_vectors[0], raster_vectors[1], raster_vectors[2]));
    
    p1.z = 1 / ((1 / raster_vectors[0].z) * lambda[0] + (1 / raster_vectors[1].z) * lambda[1] + (1 / raster_vectors[2].z) * lambda[2]);

    std::cout << "P1.z = " << p1.z << std::endl;

    return 0;
}

# data[].attributes.headline
7002219 - Thomas Itel (BARYCENTRIC FIXED)

# data[].attributes.subject
7002219 - Thomas Itel (BARYCENTRIC FIXED)

# data[].attributes.headline
7002222 - Briag FROUX ROTRU (barycentric fixed)

# data[].attributes.subject
7002222 - Briag FROUX ROTRU (barycentric fixed)

# data[].attributes.headline
7002235 - Edouard SENGEISSEN (Barycentric) (fixed)

# data[].attributes.subject
7002235 - Edouard SENGEISSEN (Barycentric) (fixed)

# data[].attributes.headline
7002272 - Gabriel Medoukali (Barycentric)

# data[].attributes.subject
7002272 - Gabriel Medoukali (Barycentric)

# data[].attributes.headline
7002297 - Louis GIGUET (Barycenter source code vFinal)

# data[].attributes.subject
7002297 - Louis GIGUET (Barycenter source code vFinal)

# data[].attributes.headline
7002230- Cedrick Kakou (Barycentric Fixed)

# data[].attributes.subject
7002230- Cedrick Kakou (Barycentric Fixed)