static void ac_update_curve_polygon(struct approximation_curve* ac)
{
  Grille_flottant* m;
  Grille_flottant* mt;
  Grille_flottant* mmt;

  Table_flottant* p;
  Table_flottant* a;
  Table_flottant* mp;

  Table_flottant* params;

  // Allocation de la table des points de contrôle de la courbe d'approximation
  if (ac->curve_polygon.nb != (ac->degree + 1))
  {
    free(ac->curve_polygon.table);

    ac->curve_polygon.nb = ac->degree + 1;
    ALLOUER(ac->curve_polygon.table, ac->curve_polygon.nb);
  }

  // Paramétrisation de la courbe d'approximation
  if (ac->use_uniform_parameterization)
    params = ac_uniform_parameterization(&ac->points);
  else
    params = ac_non_uniform_parameterization(&ac->points);

  // Construction de la matrice de Bernstein, de sa transposée et de leur produit
  m = matrix_create(ac->degree + 1, ac->points.nb);
  ac_bernstein_matrix(m, params);

  mt = matrix_transpose(m);
  mmt = matrix_product(m, mt);

  // Résolution des 3 systèmes d'équations (composantes x, y et z) des points de contrôle recherchés
  p = malloc_table_flottant(ac->points.nb);
  a = malloc_table_flottant(ac->degree + 1);
  mp = malloc_table_flottant(m->nb_lignes);

  // X
  get_triplets_x_values(&ac->points, p);
  matrix_vector_product(m, p, mp);
  if (resolution_systeme_lineaire(mmt, mp, a))
    EXIT;
  set_triplets_x_values(&ac->curve_polygon, a);

  // Y
  get_triplets_y_values(&ac->points, p);
  matrix_vector_product(m, p, mp);
  if (resolution_systeme_lineaire(mmt, mp, a))
    EXIT;
  set_triplets_y_values(&ac->curve_polygon, a);

  // Z
  get_triplets_z_values(&ac->points, p);
  matrix_vector_product(m, p, mp);
  if (resolution_systeme_lineaire(mmt, mp, a))
    EXIT;
  set_triplets_z_values(&ac->curve_polygon, a);

  // Libération des ressources
  matrix_delete(m);
  matrix_delete(mt);
  matrix_delete(mmt);

  free_table_flottant(a);
  free_table_flottant(p);
  free_table_flottant(mp);
  free_table_flottant(params);
}
Пример #2
0
Table_quadruplet least_squares_approximation(Table_triplet points, 
	Booleen uniformConf) {

	int i, j;

	Table_quadruplet res;
	res.nb = points.nb;
	ALLOUER(res.table, points.nb);

	Table_flottant steps = steps_computation(points, uniformConf);

	double ** B;
	ALLOUER(B, points.nb);
	for(i = 0; i < points.nb; i++)
		ALLOUER(B[i], points.nb);

	B[0][0] = B[points.nb - 1][points.nb - 1] = 1;
	for(i = 1; i < points.nb; i++)
		B[0][i] = 0;
	for(i = 0; i < points.nb; i++) { 
		for(j = 1; j < points.nb - 1; j++) {
			B[j][i] = bernsteinPolynomial(i, points.nb - 1, steps.table[j]);
		}
	}
	for(i = 0; i < points.nb - 1; i++)
		B[points.nb - 1][i] = 0;

	double ** BT = transposedMatrix(B, points.nb);

	Grille_flottant Aprime;
	Aprime.nb_lignes = Aprime.nb_colonnes = points.nb;
	Aprime.grille = matrix_matrix_mult(B, BT, points.nb);

	for(i = 0; i < points.nb; i++)
		free(BT[i]);
	free(BT);

	double * pointsX, * pointsY, * pointsZ;
	ALLOUER(pointsX, points.nb);
	ALLOUER(pointsY, points.nb);
	ALLOUER(pointsZ, points.nb);
	split_x_y_z(points, pointsX, pointsY, pointsZ);

	Table_flottant BprimeX, BprimeY, BprimeZ;
	BprimeX.nb = BprimeY.nb = BprimeZ.nb = points.nb;
	BprimeX.table = matrix_vector_mult(B, pointsX, points.nb);
	BprimeY.table = matrix_vector_mult(B, pointsY, points.nb);
	BprimeZ.table = matrix_vector_mult(B, pointsZ, points.nb);

	free(pointsX); free(pointsY); free(pointsZ);
	for(i = 0; i < points.nb; i++)
		free(B[i]);
	free(B);

	Table_flottant resX, resY, resZ;
	resX.nb = resY.nb = resZ.nb = points.nb;
	ALLOUER(resX.table, points.nb);
	ALLOUER(resY.table, points.nb);
	ALLOUER(resZ.table, points.nb);

	resolution_systeme_lineaire(&Aprime, &BprimeX, &resX);
	resolution_systeme_lineaire(&Aprime, &BprimeY, &resY);
	resolution_systeme_lineaire(&Aprime, &BprimeZ, &resZ);

	for(i = 0; i < points.nb; i++) {
		res.table[i].x = resX.table[i];
		res.table[i].y = resY.table[i];
		res.table[i].z = resZ.table[i];
		res.table[i].h = 1;
	}

	free(BprimeX.table); free(BprimeY.table); free(BprimeZ.table);
	free(resX.table); free(resY.table); free(resZ.table);
	for(i = 0; i < Aprime.nb_lignes; i++)
		free(Aprime.grille[i]);
	free(Aprime.grille);

	return res;
}