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> ListePoints = new List>(); 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 T = new List(); List tToEval = new List(); (T, tToEval) = buildParametrisationReguliere(X.Count(), pas); applyLagrangeParametrisation(X, Y, Z, T, tToEval); } } (List, List) buildParametrisationReguliere(int nbElem, float pas) { // Vecteur des pas temporels List T = new List(); // Echantillonage des pas temporels List tToEval = new List(); // 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 T, List 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 ListePoints_i = new List(); 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 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(); } }