/* * 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; /** * Cette classe définit un élément de type "bézier" comme étant un dérivé de * "forme" en implementant les méthodes demandées par "forme". Un "bézier" se * compose de la coordonnée 'origine' donnant la point de début et de la * coordonnée 'dernier' donnant le bout du "bézier", ainsi que de deux "points * de contrôle" afin de créer la courbe. * @author The Wingate 2940 */ public class Bezier implements IShape, Cloneable { //Les points de coordonnées 'origine' et 'dernier'. java.awt.Point origin, last; //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; //Enfin voici les deux "points de contrôle" pour créer la courbe. ControlPoint c1 = null; ControlPoint c2 = null; private Thickness thickness = Thickness.Big; private boolean inSelection = false, firstInSelection = false; /** Crée un bézier */ public Bezier(){ //nothing } /** Crée un bézier en paramétrant tout. */ public Bezier(int originX1, int originY1, int controlX2, int controlY2, int controlX3, int controlY3, int lastX4, int lastY4){ origin = new java.awt.Point(originX1,originY1); c1 = new ControlPoint(controlX2, controlY2); c2 = new ControlPoint(controlX3,controlY3); last = new java.awt.Point(lastX4,lastY4); } /** Crée un bézier en paramétrant 'origine' et 'dernier', la méthode se * chargeant de configurer les "points de contrôle". */ public Bezier(int originX1, int originY1, int lastX4, int lastY4){ origin = new java.awt.Point(originX1,originY1); last = new java.awt.Point(lastX4,lastY4); int xdiff = (int)last.getX() - (int)origin.getX(); int ydiff = (int)last.getY() - (int)origin.getY(); int x1_3 = (int)origin.getX() + xdiff/3; int x2_3 = (int)origin.getX() + xdiff*2/3; int y1_3 = (int)origin.getY() + ydiff/3; int y2_3 = (int)origin.getY() + ydiff*2/3; c1 = new ControlPoint(x1_3, y1_3); c2 = new ControlPoint(x2_3,y2_3); } 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; } /** Donne la commande ASS spécifique à la "ligne". */ @Override public String getCommand() { return "b "+(int)c1.getOriginPoint().getX()+" "+(int)c1.getOriginPoint().getY()+ " "+(int)c2.getOriginPoint().getX()+" "+(int)c2.getOriginPoint().getY()+ " "+(int)last.getX()+" "+(int)last.getY(); } /** Définit le point de 'origine' */ @Override public void setOriginPoint(int x, int y) { origin = new java.awt.Point(x,y); } /** Obtient le point de 'origine' */ @Override public java.awt.Point getOriginPoint() { return origin; } /** Définit le point de 'dernier' */ @Override public void setLastPoint(int x, int y) { last = new java.awt.Point(x,y); } /** Obtient le point de 'dernier' */ @Override public java.awt.Point getLastPoint() { return last; } /** Définit le "point de contrôle" n°1 */ public void setControl1Point(int x1, int y1){ c1 = new ControlPoint(x1, y1); } /** Définit le "point de contrôle" n°2 */ public void setControl2Point(int x2, int y2){ c2 = new ControlPoint(x2, y2); } /** Retourne les coordonnées du "point de contrôle" n°1 */ public Point2D getControl1Point(){ return c1.getOriginPoint(); } /** Retourne les coordonnées du "point de contrôle" n°2 */ public Point2D getControl2Point(){ return c2.getOriginPoint(); } /** Marque l'élément "bézier" comme 'en train de changer. */ @Override public void setMarked(boolean b) { marked = b; } /** Obtient le status de changement de l'élément "bézier". */ @Override public boolean getMarked() { return marked; } /** Définit le "point de contrôle" n°1 */ public void setControl1(ControlPoint c1){ this.c1 = c1; } /** Obtient le "point de contrôle" n°1 */ public ControlPoint getControl1(){ return c1; } /** Définit le "point de contrôle" n°2 */ public void setControl2(ControlPoint c2){ this.c2 = c2; } /** Obtient le "point de contrôle" n°2 */ public ControlPoint getControl2(){ return c2; } /** 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;} return false; } /** Met à jour la position du point concerné. */ public void updatePointPosition(java.awt.Point p){ if(oChange==true){origin = p;} if(lChange==true){last = p;} } /** Retourne à la configuration par défaut. */ public void updatehasEnded(){ oChange=false; lChange=false; } @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; } /** * <p><b>Crée une courbe Bézier cubique à partir de points venant d'une * quadratique selon la formule :</b><br /> * <code>CP0 = QP0<br />CP3 = QP2<br /> * CP1 = QP0 + 2/3 *(QP1-QP0)<br /> * CP2 = QP2 + 2/3 *(QP1-QP2)</code><br /> * où CP signifie cubic point et QP signifie quad point.<br /> * Voir aussi : http://fontforge.org/bezier.html * </p> */ public static Bezier createCubicFromQuad(int QP0x, int QP0y, int QP1x, int QP1y, int QP2x, int QP2y){ int CP0x = QP0x; int CP0y = QP0y; int CP1x = QP0x + (int)(2f/3*(QP1x-QP0x)); int CP1y = QP0y + (int)(2f/3*(QP1y-QP0y)); int CP2x = QP2x + (int)(2f/3*(QP1x-QP2x)); int CP2y = QP2y + (int)(2f/3*(QP1y-QP2y)); int CP3x = QP2x; int CP3y = QP2y; return new Bezier(CP0x, CP0y, CP1x, CP1y, CP2x, CP2y, CP3x, CP3y); } @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; } }