# Barycentric

## Description

This is a simple helper struct to handle barycentric coordinates. It has a similar structure as the Vector3 struct as it also consists of 3 float values. However it provides a constructor that allows the calculation based on the 3 corners of a triangle and a reference point. It also provides a property to do an inside / outside test as well as an Interpolate method to easily use the coordinates to interpolate Vector 2 / 3 / 4 or Color values.

## Usage / Examples

```    // calculate from triangle and reference point
var coord = new Barycentric(v0, v1, v2, point);
var normal = coord.Interpolate(n1, n2, n3);
if (coord.IsInside)
{
// point is inside the triangle (v0, v1, v2)
}

// directly just set u, v and w directly
var coord = new Barycentric(u, v, w);```

"normal" would be the interpolated normal at "point" on the triangle

## Usage UnityScript (JavaScript)

To use this struct from UnityScript you need to place the "Barycentric.cs" file inside a folder called "plugins" or "Standard Assets". The actual usage is actually the same as in C#

## Barycentric.cs

```using UnityEngine;

public struct Barycentric
{
public float u;
public float v;
public float w;
public Barycentric(float aU, float aV, float aW)
{
u = aU;
v = aV;
w = aW;
}
public Barycentric(Vector2 aV1, Vector2 aV2, Vector2 aV3, Vector2 aP)
{
Vector2 a = aV2 - aV3, b = aV1 - aV3, c = aP - aV3;
float aLen = a.x * a.x + a.y * a.y;
float bLen = b.x * b.x + b.y * b.y;
float ab = a.x * b.x + a.y * b.y;
float ac = a.x * c.x + a.y * c.y;
float bc = b.x * c.x + b.y * c.y;
float d = aLen * bLen - ab * ab;
u = (aLen * bc - ab * ac) / d;
v = (bLen * ac - ab * bc) / d;
w = 1.0f - u - v;
}

public Barycentric(Vector3 aV1, Vector3 aV2, Vector3 aV3, Vector3 aP)
{
Vector3 a = aV2 - aV3, b = aV1 - aV3, c = aP - aV3;
float aLen = a.x * a.x + a.y * a.y + a.z * a.z;
float bLen = b.x * b.x + b.y * b.y + b.z * b.z;
float ab = a.x * b.x + a.y * b.y + a.z * b.z;
float ac = a.x * c.x + a.y * c.y + a.z * c.z;
float bc = b.x * c.x + b.y * c.y + b.z * c.z;
float d = aLen * bLen - ab * ab;
u = (aLen * bc - ab * ac) / d;
v = (bLen * ac - ab * bc) / d;
w = 1.0f - u - v;
}
public Barycentric(Vector4 aV1, Vector4 aV2, Vector4 aV3, Vector4 aP)
{
Vector4 a = aV2 - aV3, b = aV1 - aV3, c = aP - aV3;
float aLen = a.x * a.x + a.y * a.y + a.z * a.z + a.w * a.w;
float bLen = b.x * b.x + b.y * b.y + b.z * b.z + b.w * b.w;
float ab = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
float ac = a.x * c.x + a.y * c.y + a.z * c.z + a.w * c.w;
float bc = b.x * c.x + b.y * c.y + b.z * c.z + b.w * c.w;
float d = aLen * bLen - ab * ab;
u = (aLen * bc - ab * ac) / d;
v = (bLen * ac - ab * bc) / d;
w = 1.0f - u - v;
}
public Barycentric(Color aV1, Color aV2, Color aV3, Color aP)
{
Color a = aV2 - aV3, b = aV1 - aV3, c = aP - aV3;
float aLen = a.r * a.r + a.g * a.g + a.b * a.b;
float bLen = b.r * b.r + b.g * b.g + b.b * b.b;
float ab = a.r * b.r + a.g * b.g + a.b * b.b;
float ac = a.r * c.r + a.g * c.g + a.b * c.b;
float bc = b.r * c.r + b.g * c.g + b.b * c.b;
float d = aLen * bLen - ab * ab;
u = (aLen * bc - ab * ac) / d;
v = (bLen * ac - ab * bc) / d;
w = 1.0f - u - v;
}

public bool IsInside
{
get
{
return (u >= 0.0f) && (u <= 1.0f) && (v >= 0.0f) && (v <= 1.0f) && (w >= 0.0f); //(w <= 1.0f)
}
}
public Vector2 Interpolate(Vector2 v1, Vector2 v2, Vector2 v3)
{
return v1 * u + v2 * v + v3 * w;
}
public Vector3 Interpolate(Vector3 v1, Vector3 v2, Vector3 v3)
{
return v1 * u + v2 * v + v3 * w;
}
public Vector4 Interpolate(Vector4 v1, Vector4 v2, Vector4 v3)
{
return v1 * u + v2 * v + v3 * w;
}
public Color Interpolate(Color v1, Color v2, Color v3)
{
return v1 * u + v2 * v + v3 * w;
}
}```