All Downloads are FREE. Search and download functionalities are using the official Maven repository.

one.empty3.library.core.nurbs.NurbsSurface Maven / Gradle / Ivy

There is a newer version: 2024.5.10
Show newest version
/*
 * Copyright (c) 2023. Manuel Daniel Dahmen
 *
 *
 *    Copyright 2012-2023 Manuel Daniel Dahmen
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/*__
 * *
 * Global license : * Microsoft Public Licence
 * 

* author Manuel Dahmen [email protected]_ *

* * */ package one.empty3.library.core.nurbs; import one.empty3.library.*; /*__ * @author Manuel Dahmen [email protected]_ */ public class NurbsSurface extends ParametricSurface { public static final int type_coordU = 0; public static final int type_coordV = 1; /*__ * * * degreeU degré de la fonction de base B_spline pour U */ private int degreeU; /*__ * * * degreeV degré de la fonction de base B_spline pour V */ private int degreeV; private Point3D[][] points; private double[][] poids; private double[][] T; private Intervalle intervalle; private Point3DPoids forme; public NurbsSurface() { } /* @Override public Point3D coordPoint3D(int x, int y) { return calculerNurbs(1.0 * x / getMaxX(), 1.0 * y / getMaxY()); } */ @Override public Point3D calculerPoint3D(double u, double v) { return calculerNurbs(u, v); } @Override public Point3D calculerVitesse3D(double u, double v) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } public void creerNurbs() { if (points != null && T != null && poids != null) { intervalle = new Intervalle(T[0], T[1]); forme = new Point3DPoids(points, poids); for (int i = 0; i < forme.m; i++) { for (int j = 0; j < forme.n; j++) { forme.set(i, j, points[i][j], poids[i][j]); } } } } public double f0sur0egal0(double t1, double t2) { if (t2 == 0 && t1 == 0) { return 0; } else { return t1 / t2; } } /*__ * * * Méthode non utilisée */ public int coefficients(int type_coord, double t) { if (t <= intervalle.get(type_coord, 0)) { return 0; } for (int i = 0; i < (type_coord == 0 ? intervalle.m : intervalle.n); i++) { if ((t >= intervalle.get(type_coord, i)) && (t < intervalle.get(type_coord, i + 1))) { return i; } } return 1; } public boolean estDansLIntervalle(int type_coord, double t, int borneInf) { if (borneInf < 0) return false; if (borneInf >= (type_coord == 0 ? intervalle.m : intervalle.n) - 1) return false; for (int i = 0; i < (type_coord == 0 ? intervalle.m : intervalle.n) - 1; i++) { if (intervalle.get(type_coord, i) >= t && intervalle.get(type_coord, i + 1) <= t) return true; } return false; } public void setMaillage(Point3D[][] points, double[][] poids) { this.points = points; this.poids = poids; } /*__ * @param T Ligne 0: intervalle u Ligne 1: intervalle v */ public void setReseauFonction(double[][] T) { this.T = T; } public double N(int type_coord, int i, int deg, double t) { if (!estDansLIntervalle(type_coord, t, i)) { return 0; } if (deg <= 0) { return 1; } return N(type_coord, i, deg - 1, t) * f0sur0egal0(t - intervalle.get(type_coord, i), intervalle.get(type_coord, i + deg) - intervalle.get(type_coord, i)) + N(type_coord, i + 1, deg - 1, t) * f0sur0egal0(intervalle.get(type_coord, i + deg + 1) - t, intervalle.get(type_coord, i + deg + 1) - intervalle.get(type_coord, i + 1)); } public long C(int i, int n) { return factorielle(n) / factorielle(i) / factorielle(n - i); } protected long factorielle(int n) { long sum = 1; for (int i = 1; i <= n; i++) { sum *= i; } return sum; } public void setDegreU(int deg) { this.degreeU = deg; } public void setDegreV(int deg) { this.degreeV = deg; } public Point3D calculerNurbs(double u, double v) { double sum = 0; Point3D ret = Point3D.O0; for (int i = 0; i < forme.m; i++) { for (int j = 0; j < forme.n; j++) { double sumP = (double) (C(i, forme.m) * C(j, forme.n)) * N(type_coordU, i, degreeU, u) * N(type_coordV, j, degreeV, v); ret = ret.plus(forme.getPoint3D(i, j).mult(sumP)); sum += sumP; } } return ret.mult(1 / sum); } @Override public String toString() { String s = "nurbs ( \n"; for (int i = 0; i < 2; i++) { for (int j = 0; j < (i == 0 ? intervalle.m : intervalle.n); j++) { s += "knot [" + i + "][" + j + "] = " + intervalle.get(i, j) + "; \n\t"; } } for (int i = 0; i < forme.m; i++) { for (int j = 0; j < forme.n; j++) { s += "point[" + i + "][" + j + "] = " + forme.getPoint3D(i, j) + "; w[" + i + "][" + j + "] = " + forme.getPoids(i, j) + ";\n\t"; } } return s + "\n\n)"; } /*__ * * * "Knots" */ class Intervalle { /*__ * Data : tableau à 2 lignes longueur de la première ligne degreeU + 1 : * premiers nombres égaux à a (en particulier a==0) r points croissant * de a à b degreeU + 1 : derniers nombres égaux à b (en particulier * b==1) deuxième ligne: degreeV + 1 : premiers nombres égaux à c (en * particulier c==0) r points croissant de c à d degreeV + 1 : derniers * nombres égaux à d (en particulier d==1) */ private final double[][] Data; private final int m, n; private Intervalle(double[] Tu, double[] Tv) { this.Data = new double[][]{Tu, Tv}; m = Data[0].length; n = Data[1].length; } public double get(int i, int j) { return this.Data[i][j]; } public void set(int i, int j, double v) { this.Data[i][j] = v; } } /*__ * * * Point3D Weight associated */ class Point3DPoids { final int m, n; private final Point3D[][] points; private final double[][] poids; public Point3DPoids(Point3D[][] poins, double[][] poids) { this.points = poins; this.poids = poids; m = points.length; n = points[0].length; } private double getPoids(int i, int j) { return poids[i][j]; } public Point3D getPoint3D(int i, int j) { return points[i][j]; } public void set(int i, int j, Point3D p, double w) { if (i >= 0 && i < m && j >= 0 && j < n) { points[i][j] = p; poids[i][j] = w; } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy