/* * File : EditableCubicCurve2D.java * Created : 25-feb-2002 11:47 * By : allastar * * JClic - Authoring and playing system for educational activities * * Copyright (C) 2000 - 2005 Francesc Busquets & Departament * d'Educacio de la Generalitat de Catalunya * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details (see the LICENSE file). */ package edu.xtec.jclic.shapers; import java.awt.geom.*; import java.awt.*; /** * * @author allastar * @version 1.0 */ public class EditableCubicCurve2D extends CubicCurve2D.Double implements EditableShape { private boolean selected=false; private int border=-1; private int selectedBorder=-1; /** Creates new EditableCubicCurve2D */ public EditableCubicCurve2D(CubicCurve2D curve){ super(); setCurve(curve); } public EditableCubicCurve2D(double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2, double ctrly2, double x2, double y2) { super(x1,y1,ctrlx1,ctrly1,ctrlx2,ctrly2,x2,y2); } public boolean isSelected() { return selected; } public boolean isInto(java.awt.geom.Rectangle2D r) { return (r.contains(getP1())||r.contains(getP2())||r.contains(getCtrlP1())||r.contains(getCtrlP2())); } public void drawBorders(java.awt.Graphics g) { if (getP1().getX()!=-1) g.drawRect((int)getP1().getX()-(EditableShapeConstants.selectLength/2),(int)getP1().getY()-(EditableShapeConstants.selectLength/2),EditableShapeConstants.selectLength,EditableShapeConstants.selectLength); if (getP2().getX()!=-1) g.drawRect((int)getP2().getX()-(EditableShapeConstants.selectLength/2),(int)getP2().getY()-(EditableShapeConstants.selectLength/2),EditableShapeConstants.selectLength,EditableShapeConstants.selectLength); if (getCtrlP1().getX()!=-1) g.fillRect((int)getCtrlP1().getX()-(EditableShapeConstants.selectLength/2),(int)getCtrlP1().getY()-(EditableShapeConstants.selectLength/2),EditableShapeConstants.selectLength,EditableShapeConstants.selectLength); if (getCtrlP2().getX()!=-1) g.fillRect((int)getCtrlP2().getX()-(EditableShapeConstants.selectLength/2),(int)getCtrlP2().getY()-(EditableShapeConstants.selectLength/2),EditableShapeConstants.selectLength,EditableShapeConstants.selectLength); g.setColor(EditableShapeConstants.SELECTED_BORDER_COLOR); if (selectedBorder==1){ g.fillRect((int)getP1().getX()-(EditableShapeConstants.selectLength/2),(int)getP1().getY()-(EditableShapeConstants.selectLength/2),EditableShapeConstants.selectLength,EditableShapeConstants.selectLength); } else if (selectedBorder==2){ g.fillRect((int)getP2().getX()-(EditableShapeConstants.selectLength/2),(int)getP2().getY()-(EditableShapeConstants.selectLength/2),EditableShapeConstants.selectLength,EditableShapeConstants.selectLength); } } public boolean hasClickedBorder(double x, double y, boolean needSelected) { boolean hasClicked=false; if (!needSelected || selected){ Rectangle r1=new Rectangle((int)getP1().getX()-(EditableShapeConstants.selectLength/2),(int)getP1().getY()-(EditableShapeConstants.selectLength/2),EditableShapeConstants.selectLength,EditableShapeConstants.selectLength); Rectangle r2=new Rectangle((int)getP2().getX()-(EditableShapeConstants.selectLength/2),(int)getP2().getY()-(EditableShapeConstants.selectLength/2),EditableShapeConstants.selectLength,EditableShapeConstants.selectLength); Rectangle r3=new Rectangle((int)getCtrlP1().getX()-(EditableShapeConstants.selectLength/2),(int)getCtrlP1().getY()-(EditableShapeConstants.selectLength/2),EditableShapeConstants.selectLength,EditableShapeConstants.selectLength); Rectangle r4=new Rectangle((int)getCtrlP2().getX()-(EditableShapeConstants.selectLength/2),(int)getCtrlP2().getY()-(EditableShapeConstants.selectLength/2),EditableShapeConstants.selectLength,EditableShapeConstants.selectLength); if (r1.contains(x,y)){ border=1; hasClicked=true; } else if (r2.contains(x,y)){ border=2; hasClicked=true; } else if (r3.contains(x,y)){ border=3; hasClicked=true; } else if (r4.contains(x,y)){ border=4; hasClicked=true; } } return hasClicked; } public void aproximateNearestBorder(double x, double y) { //getNearestBorder(x,y).setLocation(x,y); if (hasClickedBorder(x,y,false)) changeBorder(x,y); } public java.awt.geom.Point2D getNearestBorder(double x, double y) { Point2D p1,p2; double d1=getP1().distance(x,y); double d2=getP2().distance(x,y); double d3=getCtrlP1().distance(x,y); double d4=getCtrlP2().distance(x,y); if (d1<d2) p1=getP1(); else p1=getP2(); if (d3<d4) p2=getCtrlP1(); else p2=getCtrlP2(); if (p1.distance(x,y)<p2.distance(x,y)) return p1; else return p2; } public void setSelected(boolean b) { selected=b; } public void changeBorder(double x, double y) { Point2D p=new Point2D.Double(x,y); if (border==1){ setCurve(p,getCtrlP1(),getCtrlP2(),getP2()); } else if (border==2){ setCurve(getP1(),getCtrlP1(),getCtrlP2(),p); } else if (border==3){ setCurve(getP1(),p,getCtrlP2(),getP2()); } else{ //border==4 setCurve(getP1(),getCtrlP1(),p,getP2()); } } public double distanceTo(double x, double y) { /*double d1=getNearestBorder(x,y).distance(x,y); double d2=d1; Rectangle2D r=new Rectangle2D.Double(x-2,y-2,4,4); if (intersects(r)) d2=0; return Math.min(d1,d2);*/ double d1=getNearestBorder(x,y).distance(x,y); double d2=(new Line2D.Double(getP1(),getP2())).ptSegDist(x,y); return Math.min(d1,d2); } public void paintWithColor(java.awt.Graphics g, int drawingMode, java.awt.Color c) { g.setColor(EditableShapeConstants.BORDER_COLOR); drawBorders(g); if (selected){ paintSelection(g); } else if (drawingMode==PolygonDrawPanel.NEW_POINT){ g.setColor(Color.red); drawBorders(g); g.setColor(c); } else g.setColor(c); ((Graphics2D)g).draw(this); } public void paint(java.awt.Graphics g, int drawingMode) { paintWithColor(g,drawingMode,EditableShapeConstants.defaultColor); } public void paintSelection(java.awt.Graphics g) { g.setColor(Color.black); drawBorders(g); g.setColor(EditableShapeConstants.selectedColor); } public void move(double incX, double incY) { setCurve(getP1().getX()+incX,getP1().getY()+incY,getCtrlX1()+incX,getCtrlY1()+incY,getCtrlX2()+incX,getCtrlY2()+incY, getP2().getX()+incX,getP2().getY()+incY); } public void transform(java.awt.geom.AffineTransform aTransf) { Point2D p1=getP1(); Point2D p2=getCtrlP1(); Point2D p3=getCtrlP2(); Point2D p4=getP2(); aTransf.transform(p1,p1); aTransf.transform(p2,p2); aTransf.transform(p3,p3); aTransf.transform(p4,p4); setCurve(p1,p2,p3,p4); } public EditableShape[] divide(double x, double y) { EditableShape[] newShapes=new EditableShape[2]; CubicCurve2D left=new CubicCurve2D.Double(); CubicCurve2D right=new CubicCurve2D.Double(); subdivide(left,right); newShapes[0]=new EditableCubicCurve2D(right); newShapes[1]=new EditableCubicCurve2D(left); //setCurve(left); return newShapes; } public boolean isAdjacentTo(java.awt.geom.Point2D p) { if (getP1().equals(p)) return true; else if (getP2().equals(p)){ setCurve(getP2(),getCtrlP2(),getCtrlP1(),getP1()); return true; } else return false; } public java.awt.geom.Point2D getEndPoint() { return getP2(); } public java.awt.geom.Point2D getInitialPoint() { return getP1(); } public Object clone(){ return new EditableCubicCurve2D(this); } public java.awt.geom.Point2D[] getBorders() { return new Point2D[]{getP1(),getP2(),getCtrlP1(),getCtrlP2()}; } public void selectBorder(double x, double y) { Point2D p=new Point2D.Double(x,y); if (getP1().equals(p)) selectedBorder=1; else if (getP2().equals(p)) selectedBorder=2; else selectedBorder=-1; } public void deselectBorder(){ selectedBorder=-1; } public boolean hasSelectedBorder(){ return (selectedBorder!=-1); } public java.awt.geom.Point2D getNotSelectedBorder(){ if (selectedBorder==1) return getP2(); else return getP1(); } }