Как составить уравнения ввида на основе барицентрических координат.
f(x+dx)= f(x) + f'(x)*dx
И вместо условно функции, которую нужно считывать допустим для точек (0,0) и (0,1)
public static Vector3 interopatateColor (Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p, Vector3 c0, Vector3 c1, Vector3 c2)
{
float w0 = (p1.Y - p2.Y) * (p.X - p2.X) + (p2.X - p1.X) * (p.Y - p2.Y);
float w1 = (p2.Y - p0.Y) * (p.X - p2.X) + (p0.X - p2.X) * (p.Y - p2.Y);
float d = (p1.Y - p2.Y) * (p0.X - p2.X) + (p2.X - p1.X) * (p0.Y - p2.Y);
w0 /= d;
w1 /= d;
float w2 = 1f - w0 - w1;
return (c0 * w0 + c1 * w1 + c2 * w2); // из этого же уравнения можно легко найти производные по x,y,
}
Получить что-то вроде
public static Vector3 IncX( Vector3 color_f, Vector3 inc_color)
{
return color_f+ inc_color;
}
Что бы для Точек P(x,y) и P(x+1,y) не пересчитывать все уравнение а просто инкрементировать производную.
Допустим есть такая функция, в цикле проходит по всем точкам слева, например простая оптимизация для проверки попадания точки, а я перечитал 100 учебников и не где не нашел, ускоряет любые базовые реализации из учебников в разы.
var bar = new BarycentricInterpolateColor(p0,p1,p2,c0,c1,c2);
for (int y = 0; y < 650; y++)
{
bar .Setup(new Vector2(0, y) ); // решить уравнение от (0,y) найти начальный цвет
for (int x = 0; x < 750; x++)
{
Vector2 p = new Vector2(x, y);
if ( barC.IsInsideSafe) // проверить попадание точки,
{
var c = barC.color;
DrawPoint( p, bar.Value);
}
bar.IncX(); // инкрементировать к примеру реализовал для проверки стороны таким способом, а как цвет
интерполировать.
}
}
pubcliv struct BarycentricInterpolateColor{
BarycentricLinear bar;
//... похожая логика для цветов вершин
}
public struct BarycentricLinear
{
internal Vector3 aX;
internal Vector3 aY;
internal Vector3 b;
internal Vector3 c;
public Vector3 res=>b; // aX*x+bX*y+c;
public BarycentricLinear(Vector2 p0, Vector2 p1, Vector2 p2 )
{
// CheckSide разбираем это уравнение,
// bool isInTriangle= (q.Y - p1.Y) * (p2.X - p1.X) > (q.X - p1.X) * (p2.Y - p1.Y);
//выносит kx, ky, c = (- p1.Y) * (p2.X - p1.X) -(- p1.X) * (p2.Y - p1.Y);
aX = new Vector3(calcKx(p0, p1), calcKx(p1, p2), calcKx(p2, p0));
aY = new Vector3(calcKy(p0, p1), calcKy(p1, p2), calcKy(p2, p0));
c = new Vector3(calcC(p0, p1), calcC(p1, p2), calcC(p2, p0));
}
public void Setup(SKPoint leftTop)
{
b = aX * leftTop.X + aY * leftTop.Y + c;
}
public void IncX()
{
b += aX;
}
public void IncY()
{
b += aY;
}
public bool IsInsideUnsafe
{
get
{
unsafe
{
return (((((*(int*)Unsafe.AsPointer(ref b.X)) ^ (*(int*)Unsafe.AsPointer(ref b.Y))) | ((*(int*)Unsafe.AsPointer(ref b.Y)) ^ (*(int*)Unsafe.AsPointer(ref b.Z))))) > 0);
}
}
}
public bool IsInsideSafe
{
get
{
unsafe
{
return (b.X>0 == b.Y>0) && (b.Y > 0 == b.Z > 0);
}
}
}
private static float calcC(Vector2 p1, Vector2 p2)
{
return -p1.Y * (p2.X - p1.X) + p1.X * (p2.Y - p1.Y);
}
private static float calcKx(Vector2 p1,Vector2 p2)
{
return -(p2.Y - p1.Y);
}
private static float calcKy(Vector2 p1, Vector2 p2)
{
return (p2.X - p1.X);
}
}
https://codeplea.com/triangular-interpolation