TP-modelisation-geometrique/TP2/Assets/Scripts/DeCasteljauSubdivision.cs
2023-06-21 20:37:15 +02:00

147 lines
5.7 KiB
C#
Executable file

using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//////////////////////////////////////////////////////////////////////////
///////////////// Classe qui gère la subdivision via DCJ /////////////////
//////////////////////////////////////////////////////////////////////////
public class DeCasteljauSubdivision : MonoBehaviour
{
// Pas d'échantillonage pour affichage
public float pas = 1 / 100;
// Nombre de subdivision dans l'algo de DCJ
public int NombreDeSubdivision = 10;
// Liste des points composant la courbe
private List<Vector3> ListePoints = new List<Vector3>();
// Donnees i.e. points cliqués
public GameObject Donnees;
// Coordonnees des points composant le polygone de controle
private List<float> PolygoneControleX = new List<float>();
private List<float> PolygoneControleY = new List<float>();
//////////////////////////////////////////////////////////////////////////
// fonction : DeCasteljauSub //
// semantique : renvoie la liste des points composant la courbe //
// approximante selon un nombre de subdivision données //
// params : - List<float> X : abscisses des point de controle //
// - List<float> Y : odronnees des point de controle //
// - int nombreDeSubdivision : nombre de subdivision //
// sortie : //
// - (List<float>, List<float>) : liste des abscisses et liste //
// des ordonnées des points composant la courbe //
//////////////////////////////////////////////////////////////////////////
(List<float>, List<float>) DeCasteljauSub(List<float> X, List<float> Y, int nombreDeSubdivision)
{
if (nombreDeSubdivision == 0)
{ // condition de terminaison
return (X, Y);
}
else
{ // récurrence
List<float> x_gauche = new List<float>();
List<float> y_gauche = new List<float>();
List<float> x_droite = new List<float>();
List<float> y_droite = new List<float>();
// copie de X et Y pour la subdivision
int n = X.Count;
List<float> nevX = new List<float>(X);
List<float> nevY = new List<float>(Y);
// ajout des premiers points
x_gauche.Add(X[0]);
y_gauche.Add(Y[0]);
for (int i = n - 1; i > 0; i--)
{
for (int j = 0; j < i; j++)
{
nevX[j] = 0.5f * nevX[j] + 0.5f * nevX[j + 1];
nevY[j] = 0.5f * nevY[j] + 0.5f * nevY[j + 1];
}
// ajouts de la subdiv de gauche
x_gauche.Add(nevX[0]);
y_gauche.Add(nevY[0]);
}
// ajout de la subdiv de droite
for (int i = 0; i < n; i++)
{
x_droite.Add(nevX[i]);
y_droite.Add(nevY[i]);
}
// déclaration des nouvelles listes de points
List<float> x_new_gauche = new List<float>();
List<float> y_new_gauche = new List<float>();
List<float> x_new_droite = new List<float>();
List<float> y_new_droite = new List<float>();
// appels récurrents
(x_new_gauche, y_new_gauche) = DeCasteljauSub(x_gauche, y_gauche, nombreDeSubdivision - 1);
(x_new_droite, y_new_droite) = DeCasteljauSub(x_droite, y_droite, nombreDeSubdivision - 1);
// on enlève le point en commun dans une des deux listes
x_new_droite.RemoveAt(0);
y_new_droite.RemoveAt(0);
return (x_new_gauche.Concat(x_new_droite).ToList(), y_new_gauche.Concat(y_new_droite).ToList());
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////// NE PAS TOUCHER //////////////////////////////
//////////////////////////////////////////////////////////////////////////
void Start()
{
}
void Update()
{
// if (Input.GetKeyDown(KeyCode.Return))
// {
PolygoneControleX.Clear();
PolygoneControleY.Clear();
ListePoints.Clear();
var ListePointsCliques = GameObject.Find("Donnees").GetComponent<Points>();
if (ListePointsCliques.X.Count > 0)
{
for (int i = 0; i < ListePointsCliques.X.Count; ++i)
{
PolygoneControleX.Add(ListePointsCliques.X[i]);
PolygoneControleY.Add(ListePointsCliques.Y[i]);
}
List<float> XSubdivision = new List<float>();
List<float> YSubdivision = new List<float>();
(XSubdivision, YSubdivision) = DeCasteljauSub(ListePointsCliques.X, ListePointsCliques.Y, NombreDeSubdivision);
for (int i = 0; i < XSubdivision.Count; ++i)
{
ListePoints.Add(new Vector3(XSubdivision[i], -4.0f, YSubdivision[i]));
}
}
// }
}
void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
for (int i = 0; i < PolygoneControleX.Count - 1; ++i)
{
Gizmos.DrawLine(new Vector3(PolygoneControleX[i], -4.0f, PolygoneControleY[i]), new Vector3(PolygoneControleX[i + 1], -4.0f, PolygoneControleY[i + 1]));
}
Gizmos.color = Color.blue;
for (int i = 0; i < ListePoints.Count - 1; ++i)
{
Gizmos.DrawLine(ListePoints[i], ListePoints[i + 1]);
}
}
}