TP-modelisation-geometrique/TP1/Assets/Scripts/Utils/InterpolateurDeSurface.cs
2023-06-21 20:37:15 +02:00

199 lines
5.2 KiB
C#

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System;
using UnityEngine.UI;
public class InterpolateurDeSurface : MonoBehaviour
{
public GameObject particle;
public float[] X;
public float[,] Y;
public float[] Z;
public bool autoGenerateGrid;
public float pas;
private List<List<Vector3>> ListePoints = new List<List<Vector3>>();
void Start()
{
if (true)
{
int n = 5;
X = new float[n];
Y = new float[n, n];
Z = new float[n];
for (int i = 0; i < n; i++)
{
X[i] = (float)i / (float)(n - 1);
Z[i] = (float)i / (float)(n - 1);
}
for (int i = 0; i < n; i++)
{
float XC2 = (X[i] - (1.0f / 2.0f)) * (X[i] - (1.0f / 2.0f));
for (int j = 0; j < n; j++)
{
float ZC2 = (Z[j] - (1.0f / 2.0f)) * (Z[j] - (1.0f / 2.0f));
Y[i, j] = (float)Math.Exp(-(XC2 + ZC2));
Instantiate(particle, new Vector3(X[i], Y[i, j], Z[j]), Quaternion.identity);
}
}
}
else
{
}
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Return))
{
List<float> T = new List<float>();
List<float> tToEval = new List<float>();
(T, tToEval) = buildParametrisationReguliere(X.Count(), pas);
applyLagrangeParametrisation(X, Y, Z, T, tToEval);
}
}
(List<float>, List<float>) buildParametrisationReguliere(int nbElem, float pas)
{
// Vecteur des pas temporels
List<float> T = new List<float>();
// Echantillonage des pas temporels
List<float> tToEval = new List<float>();
// Construction des pas temporels
for (int i = 0; i < nbElem; i++)
{
T.Add(i);
}
// Construction des échantillons
for (float t = 0; t < T.Last(); t += pas)
{
tToEval.Add(t);
}
return (T, tToEval);
}
void applyLagrangeParametrisation(float[] X, float[,] Y, float[] Z, List<float> T, List<float> tToEval)
{
ListePoints.Clear();
float[] newX = new float[tToEval.Count()];
float[,] newY_interm = new float[tToEval.Count(), Z.Count()];
float[,] newY = new float[tToEval.Count(), tToEval.Count()];
float[] newZ = new float[tToEval.Count()];
for (int i = 0; i < tToEval.Count(); i++)
{
float t = tToEval[i];
newX[i] = lagrange(t, T, X);
newZ[i] = lagrange(t, T, Z);
}
for (int k = 0; k < Z.Count(); k++)
{
float[] Yk = GetColumn(Y, k);
for (int i = 0; i < tToEval.Count(); i++)
{
float t = tToEval[i];
float val = lagrange(t, T, Yk);
newY[i, k * (int)(1 / pas)] = val;
newY_interm[i, k] = val;
}
}
// for (int k = 0; k < tToEval.Count(); k++)
// {
// float[] Yk = GetRow(newY_interm, k);
// for (int i = 0; i < tToEval.Count(); i++)
// {
// float t = tToEval[i];
// newY[k, i] = lagrange(t, T, Yk);
// }
// }
for (int i = 0; i < tToEval.Count(); i++)
{
List<Vector3> ListePoints_i = new List<Vector3>();
for (int j = 0; j < tToEval.Count(); j++)
{
ListePoints_i.Add(new Vector3(newX[i], newY[i, j], newZ[j]));
}
ListePoints.Add(ListePoints_i);
}
}
private float lagrange(float x, List<float> X, float[] Y)
{
float sum = 0;
for (int i = 0; i < X.Count; i++)
{
float xi = X[i];
float prod = 1;
for (int j = 0; j < X.Count; j++)
{
float xj = X[j];
if (xi != xj)
{
prod *= (x - xj) / (xi - xj);
}
}
sum += prod * Y[i];
}
return sum;
}
void OnDrawGizmosSelected()
{
Gizmos.color = Color.blue;
if (autoGenerateGrid)
{
for (int j = 0; j < ListePoints.Count; ++j)
{
for (int i = 0; i < ListePoints[j].Count - 1; ++i)
{
Gizmos.DrawLine(ListePoints[j][i], ListePoints[j][i + 1]);
}
}
}
}
public float[] GetColumn(float[,] matrix, int columnNumber)
{
return Enumerable.Range(0, matrix.GetLength(0))
.Select(x => matrix[x, columnNumber])
.ToArray();
}
public float[] GetRow(float[,] matrix, int rowNumber)
{
return Enumerable.Range(0, matrix.GetLength(1))
.Select(x => matrix[rowNumber, x])
.ToArray();
}
}