/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package feuille.drawing.lib; import java.awt.Rectangle; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.List; import feuille.drawing.bspline.BSplineCurve; import feuille.drawing.bspline.BezierCurve; /** * * @author The Wingate 2940 */ public class BSpline implements IShape, Cloneable { //Les points de coordonnées 'origine' et 'dernier'. java.awt.Point origin, last, nc, next; //marked sert à signalé un changement de position de façon globale. boolean marked = false; //Les variables suivantes avertissent d'une chagement de position en cours //sur le point 'origine' (ochange) ou le point dernier (lchange). boolean oChange = false; boolean lChange = false; boolean cpChange = false; boolean nextChange; //Enfin voici les "points de contrôle" pour créer la courbe. List<ControlPoint> lcp = new ArrayList<ControlPoint>(); private Thickness thickness = Thickness.Big; BSplineCurve bsc; ControlPoint uc = null; int ucChanged = 0; boolean isClosed = false; boolean isNextExist = false; private boolean inSelection = false, firstInSelection = false; public BSpline(){ } /** Crée un objet b-spline en paramétrant le premier point. */ public BSpline(int x0, int y0){ origin = new java.awt.Point(x0, y0); bsc = new BSplineCurve(new java.awt.Point(x0, y0)); lcp.add(new ControlPoint(x0, y0)); } /** Crée une b-spline en paramétrant tout (n=x). */ public BSpline(List<ControlPoint> list){ lcp = list; origin = new java.awt.Point((int)lcp.get(0).getOriginPoint().getX(), (int)lcp.get(0).getOriginPoint().getY()); last = new java.awt.Point((int)lcp.get(lcp.size()-1).getOriginPoint().getX(), (int)lcp.get(lcp.size()-1).getOriginPoint().getY()); } public void addPoint(int x, int y){ lcp.add(new ControlPoint(x, y)); bsc.addControlPoint(new java.awt.Point(x,y)); origin = new java.awt.Point((int)lcp.get(0).getOriginPoint().getX(), (int)lcp.get(0).getOriginPoint().getY()); last = new java.awt.Point((int)lcp.get(lcp.size()-1).getOriginPoint().getX(), (int)lcp.get(lcp.size()-1).getOriginPoint().getY()); } public void updatePoint(int x, int y){ lcp.set(ucChanged, new ControlPoint(x, y)); List<Point2D> lsp = new ArrayList<Point2D>(); for(ControlPoint cp : lcp){ Point2D p2d = new Point2D.Double(cp.getOriginPoint().getX(),cp.getOriginPoint().getY()); lsp.add(p2d); } bsc.setControlPoints(lsp); origin = new java.awt.Point((int)lcp.get(0).getOriginPoint().getX(), (int)lcp.get(0).getOriginPoint().getY()); last = new java.awt.Point((int)lcp.get(lcp.size()-1).getOriginPoint().getX(), (int)lcp.get(lcp.size()-1).getOriginPoint().getY()); } public enum Thickness{ Big(10),Large(8),Medium(6),Small(4); private int thick; Thickness(int thick){ this.thick = thick; } public int getThickness(){ return thick; } } public void updateThickness(Thickness thickness){ this.thickness = thickness; } @Override public String getCommand() { String line = "s"; for(int i=0;i<lcp.size();i++){ ControlPoint c = lcp.get(i); line = line+" "+(int)c.getOriginPoint().getX()+" "+(int)c.getOriginPoint().getY(); } return line; } @Override public void setOriginPoint(int x, int y) { ControlPoint c1 = new ControlPoint(x, y); if(lcp.isEmpty()==false){ lcp.set(0, c1); }else{ lcp.add(c1); } } @Override public java.awt.Point getOriginPoint() { if(lcp.isEmpty()==false){ return lcp.get(0).getOriginPoint(); }else{ return null; } } @Override public void setLastPoint(int x, int y) { ControlPoint c1 = new ControlPoint(x, y); if(lcp.isEmpty()==false && lcp.size()>3){ lcp.set(lcp.size()-1, c1); } } @Override public java.awt.Point getLastPoint() { if(lcp.isEmpty()==false){ return lcp.get(lcp.size()-1).getLastPoint(); }else{ return null; } } @Override public void setMarked(boolean b) { marked = b; } @Override public boolean getMarked() { return marked; } public java.awt.Point getLastUsedControlPoint() { return nc; } /** Renvoie <b>true</b> si une extrémité de la "ligne" est concernée par * un changement et définit lequel dans l'élément "ligne". */ public boolean isPointisNear(java.awt.Point p){ int xp = (int)p.getX(); int yp = (int)p.getY(); Rectangle rect = new Rectangle( xp-thickness.getThickness()/2, yp-thickness.getThickness()/2, thickness.getThickness(), thickness.getThickness()); // if(rect.contains(origin)){oChange=true; return true;} // if(rect.contains(last)){lChange=true; return true;} try{ if(rect.contains(next)){nextChange=true;}else{nextChange=false;} }catch(NullPointerException npe){} int index = 0; for(ControlPoint cp : this.getControlPoints()){ uc = cp; ucChanged = index; if(rect.contains(cp.getOriginPoint())){cpChange=true; return true;} index += 1; } return false; } /** Met à jour la position du point concerné. */ public void updatePointPosition(java.awt.Point p){ if(nextChange==true){next = p;} if(oChange==true){origin = p;} if(lChange==true){last = p;} if(cpChange==true){nc = p;} } /** Retourne à la configuration par défaut. */ public void updatehasEnded(){ nextChange=false; oChange=false; lChange=false; cpChange=false; } public boolean isNear(java.awt.Point o, java.awt.Point t){ Rectangle rect = new Rectangle( (int)o.getX()-thickness.getThickness()/2, (int)o.getY()-thickness.getThickness()/2, thickness.getThickness(), thickness.getThickness()); if(rect.contains(t)){return true;} return false; } public void updateLastUsedControlPoint(){ for(ControlPoint cp : lcp){ if(uc.equals(cp)){ cp.setOriginPoint((int)nc.getX(), (int)nc.getY()); } } updatePoint((int)nc.getX(), (int)nc.getY()); } public BSplineCurve getBSplineCurve(){ return bsc; } public List<ControlPoint> getControlPoints(){ return lcp; } public List<Bezier> getAllBeziers(){ List<BezierCurve> lbc = bsc.extractAllBezierCurves(); List<Bezier> lb = new ArrayList<Bezier>(); for(BezierCurve bc : lbc){ Bezier b = new Bezier(); List<Point2D> p = bc.getControlPoints(); b.setOriginPoint((int)p.get(0).getX(), (int)p.get(0).getY()); b.setControl1Point((int)p.get(1).getX(), (int)p.get(1).getY()); b.setControl2Point((int)p.get(2).getX(), (int)p.get(2).getY()); b.setLastPoint((int)p.get(3).getX(), (int)p.get(3).getY()); lb.add(b); } return lb; } public boolean isClosed(){ return isClosed; } public void setClosed(boolean b){ isClosed = b; } public void setNextPoint(int x, int y){ next = new java.awt.Point(x,y); setNextExist(true); } public java.awt.Point getNextPoint() { return next; } public boolean isNextExist(){ return isNextExist; } public void setNextExist(boolean b){ isNextExist = b; } @Override public Object clone() { Object o = null; try { // On récupère l'instance à renvoyer par l'appel de la // méthode super.clone() o = super.clone(); } catch(CloneNotSupportedException cnse) { // Ne devrait jamais arriver car nous implémentons // l'interface Cloneable cnse.printStackTrace(System.err); } // on renvoie le clone return o; } @Override public void setInSelection(boolean b){ inSelection = b; } @Override public boolean isInSelection(){ return inSelection; } @Override public void setFirstInSelection(boolean b){ firstInSelection = b; } @Override public boolean isFirstInSelection(){ return firstInSelection; } public void setupBSplineCurve(int x0, int y0){ origin = new java.awt.Point(x0, y0); bsc = new BSplineCurve(new java.awt.Point(x0, y0)); lcp.add(new ControlPoint(x0, y0)); last = new java.awt.Point((int)lcp.get(lcp.size()-1).getOriginPoint().getX(), (int)lcp.get(lcp.size()-1).getOriginPoint().getY()); } public boolean isBSplineCurveExists(){ if(bsc!=null){ return true; } return false; } //Fonction crée afin de corriger le bug du point en plus de la rotation public void removePointAt(int index){ ControlPoint cp = lcp.get(index); bsc.removeControlPoint(cp.getOriginPoint()); lcp.remove(index); } }