/* Copyright 2006 Rene Grothmann, modified by Eric Hakenholz This file is part of C.a.R. software. C.a.R. is a 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, version 3 of the License. C.a.R. 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. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package rene.zirkel.constructors; import java.awt.event.MouseEvent; import eric.JZirkelCanvas; import rene.util.MyVector; import rene.util.xml.XmlTag; import rene.util.xml.XmlTree; import rene.gui.Global; import rene.zirkel.ZirkelCanvas; import rene.zirkel.construction.Construction; import rene.zirkel.construction.ConstructionException; import rene.zirkel.objects.CircleIntersectionObject; import rene.zirkel.objects.ConstructionObject; import rene.zirkel.objects.IntersectionObject; import rene.zirkel.objects.LineCircleIntersectionObject; import rene.zirkel.objects.LineIntersectionObject; import rene.zirkel.objects.LineQuadricIntersectionObject; import rene.zirkel.objects.PointObject; import rene.zirkel.objects.PointonObjectIntersectionObject; import rene.zirkel.objects.PrimitiveCircleObject; import rene.zirkel.objects.PrimitiveLineObject; import rene.zirkel.objects.QuadricObject; import rene.zirkel.objects.QuadricQuadricIntersectionObject; public class IntersectionConstructor extends ObjectConstructor { ConstructionObject P1=null, P2=null; boolean immediate = false; MouseEvent ev = null; @Override public void mousePressed(final MouseEvent e, final ZirkelCanvas zc) { if (!zc.Visual) { return; } ev = e; if (P1==null) { final MyVector v=zc.selectPointonObjects(e.getX(), e.getY()); if (v.size()==2) { P1=(ConstructionObject) v.elementAt(0); P2=(ConstructionObject) v.elementAt(1); if (P1.equals(P2)|| P2.equals(P1) || (P1.isFilled()&&P2.isFilled())) { P1=P2=null; } else { immediate=true; } } } ConstructionObject obj = null; if(P1==null || P2==null){ obj = select(e.getX(), e.getY(), zc); } setConstructionObject(obj, zc); } @Override public void setConstructionObject(ConstructionObject obj, ZirkelCanvas zc){ if (P1==null) { P1 = obj; if (P1!=null) { P1.setSelected(true); zc.repaint(); showStatus(zc); } } else if(P2==null) { P2 = obj; } if (P2!=null) { if (P2==P1) { P2=null; return; } final IntersectionObject o[]=construct(P1, P2, zc.getConstruction()); if (o!=null) { IntersectionObject oc=null; if (immediate&&o.length>1) { if (o[1].nearto(ev.getX(), ev.getY(), zc)) { o[0]=null; oc=o[1]; } else { o[1]=null; oc=o[0]; } } for (final IntersectionObject element : o) { if (element!=null) { element.setDefaults(); zc.addObject(element); element.validate(zc.x(ev.getX()), zc.y(ev.getY())); } } /** * See, if the other intersection is visible and already a * point of both objects. */ if (oc!=null) { oc.autoAway(); } } reset(zc); } } @Override public void mouseMoved(final MouseEvent e, final ZirkelCanvas zc, final boolean simple) { // System.out.println("inter : "+e.getX()+" "+e.getY()); zc.indicateIntersectedObjects(e.getX(), e.getY()); } public static IntersectionObject[] construct(final ConstructionObject P1, final ConstructionObject P2, final Construction c) { IntersectionObject o[]=null; if (P1 instanceof PrimitiveLineObject) { if (P2 instanceof PrimitiveLineObject) { o=new IntersectionObject[1]; o[0]=new LineIntersectionObject(c, (PrimitiveLineObject) P1, (PrimitiveLineObject) P2); } else if (P2 instanceof PrimitiveCircleObject) { o=new IntersectionObject[2]; o[0]=new LineCircleIntersectionObject(c, (PrimitiveLineObject) P1, (PrimitiveCircleObject) P2, true); o[1]=new LineCircleIntersectionObject(c, (PrimitiveLineObject) P1, (PrimitiveCircleObject) P2, false); } else if (P2 instanceof QuadricObject) { o=new IntersectionObject[2]; o[0]=new LineQuadricIntersectionObject(c, (PrimitiveLineObject) P1, (QuadricObject) P2, true); o[1]=new LineQuadricIntersectionObject(c, (PrimitiveLineObject) P1, (QuadricObject) P2, false); } else { return construct(P2, P1, c); } } else if (P1 instanceof QuadricObject) { if (P2 instanceof PrimitiveLineObject) { o=new IntersectionObject[2]; o[0]=new LineQuadricIntersectionObject(c, (PrimitiveLineObject) P2, (QuadricObject) P1, true); o[1]=new LineQuadricIntersectionObject(c, (PrimitiveLineObject) P2, (QuadricObject) P1, false); } else if (P2 instanceof QuadricObject) { if (((QuadricObject) P1).getP()[0].is3D()||((QuadricObject) P1).getP()[1].is3D()||((QuadricObject) P1).getP()[2].is3D()||((QuadricObject) P1).getP()[3].is3D()||((QuadricObject) P1).getP()[4].is3D()|| ((QuadricObject) P2).getP()[0].is3D()||((QuadricObject) P2).getP()[1].is3D()||((QuadricObject) P2).getP()[2].is3D()||((QuadricObject) P2).getP()[3].is3D()||((QuadricObject) P2).getP()[4].is3D()) {// Dibs : truc de givré pour régler un bug avec l'intersection de cercles 3D final PointObject p1=((QuadricObject) P1).getP()[1]; p1.setEX3D(p1.getEX3D().toString()+"+0.00001"); p1.setFixed("x(O)+("+p1.getEX3D()+")*(x(X)-x(O))+("+p1.getEY3D()+")*(x(Y)-x(O))+("+p1.getEZ3D()+")*(x(Z)-x(O))", "y(O)+("+p1.getEX3D()+")*(y(X)-y(O))+("+p1.getEY3D()+")*(y(Y)-y(O))+("+p1.getEZ3D()+")*(y(Z)-y(O))"); } o=new IntersectionObject[4]; o[0]=new QuadricQuadricIntersectionObject(c, (QuadricObject) P2, (QuadricObject) P1, 0); o[1]=new QuadricQuadricIntersectionObject(c, (QuadricObject) P2, (QuadricObject) P1, 1); o[2]=new QuadricQuadricIntersectionObject(c, (QuadricObject) P2, (QuadricObject) P1, 2); o[3]=new QuadricQuadricIntersectionObject(c, (QuadricObject) P2, (QuadricObject) P1, 3); } else { o=new PointonObjectIntersectionObject[1]; o[0]=new PointonObjectIntersectionObject(c, P1, P2); } } else if (P1 instanceof PrimitiveCircleObject) { if (P2 instanceof PrimitiveCircleObject) { if ((P1.isDPLineOrSegmentObject())&&(P2.isDPLineOrSegmentObject())) { o=new IntersectionObject[1]; o[0]=new CircleIntersectionObject(c, (PrimitiveCircleObject) P1, (PrimitiveCircleObject) P2, true); } else { o=new IntersectionObject[2]; o[0]=new CircleIntersectionObject(c, (PrimitiveCircleObject) P1, (PrimitiveCircleObject) P2, true); o[1]=new CircleIntersectionObject(c, (PrimitiveCircleObject) P1, (PrimitiveCircleObject) P2, false); } } else if (P2 instanceof PrimitiveLineObject) { o=new IntersectionObject[2]; o[0]=new LineCircleIntersectionObject(c, (PrimitiveLineObject) P2, (PrimitiveCircleObject) P1, true); o[1]=new LineCircleIntersectionObject(c, (PrimitiveLineObject) P2, (PrimitiveCircleObject) P1, false); } else { return construct(P2, P1, c); } } else { o=new PointonObjectIntersectionObject[1]; o[0]=new PointonObjectIntersectionObject(c, P1, P2); } return o; } public ConstructionObject select(final int x, final int y, final ZirkelCanvas zc) // select a line or circle at x,y { return zc.selectPointonObject(x, y, false); } @Override public void reset(final ZirkelCanvas zc) { // reset the tool super.reset(zc); if (zc.Visual) { P1=P2=null; showStatus(zc); } else { zc.setPrompt(Global.name("prompt.intersection")); } } @Override public void showStatus(final ZirkelCanvas zc) { if (P1==null) { zc.showStatus(Global.name("message.intersection.first", "Intersection: Select first object!")); } else { zc.showStatus(Global.name("message.intersection.second", "Intersection: Select second object!")); } } @Override public boolean construct(final XmlTree tree, final Construction c) throws ConstructionException { if (!testTree(tree, "Intersection")) { return constructOther(tree, c); } final XmlTag tag=tree.getTag(); if (!tag.hasParam("first")||!tag.hasParam("second")) { throw new ConstructionException("Intersection parameters missing!"); } try { final ConstructionObject o1=c.find(tag.getValue("first")); final ConstructionObject o2=c.find(tag.getValue("second")); final IntersectionObject o[]=construct(o1, o2, c); if (o==null) { throw new Exception(""); } String name="", nameOther=""; if (tag.hasParam("name")) { name=tag.getValue("name"); } if (tag.hasParam("other")) { nameOther=tag.getValue("other"); } if (o.length>1) { IntersectionObject oo=o[0]; if (tag.hasParam("which")) { if (tag.getValue("which").equals("first")) { oo=o[0]; } else if (tag.getValue("which").equals("second")) { oo=o[1]; } else if (tag.getValue("which").equals("0")) { oo=o[0]; } else if (tag.getValue("which").equals("1")) { oo=o[1]; } else if (tag.getValue("which").equals("2")) { oo=o[2]; } else if (tag.getValue("which").equals("3")) { oo=o[3]; } if (!name.equals("")) { oo.setName(name); } PointConstructor.setType(tag, oo); setName(tag, oo); set(tree, oo); c.add(oo); setConditionals(tree, c, oo); if (tag.hasParam("awayfrom")) { oo.setAway(tag.getValue("awayfrom"), true); } else if (tag.hasParam("closeto")) { oo.setAway(tag.getValue("closeto"), false); } if (tag.hasParam("valid")) { oo.setRestricted(false); } if (tag.hasParam("alternate")) { oo.setAlternate(true); } } else if (tag.hasParam("other")) { if (!name.equals("")) { o[0].setName(name); } if (!nameOther.equals("")) { o[1].setName(nameOther); } if (tag.hasParam("awayfrom")) { o[0].setAway(tag.getValue("awayfrom"), true); o[1].setAway(tag.getValue("awayfrom"), false); } else if (tag.hasParam("closeto")) { o[1].setAway(tag.getValue("awayfrom"), true); o[0].setAway(tag.getValue("awayfrom"), false); } for (final IntersectionObject element : o) { if (element==null) { continue; } PointConstructor.setType(tag, element); set(tree, element); c.add(element); setConditionals(tree, c, element); } } } else { if (!name.equals("")) { o[0].setName(name); } PointConstructor.setType(tag, o[0]); setName(tag, o[0]); set(tree, o[0]); c.add(o[0]); setConditionals(tree, c, o[0]); if (tag.hasParam("valid")) { o[0].setRestricted(false); } try { final double x=new Double(tag.getValue("x")).doubleValue(); final double y=new Double(tag.getValue("y")).doubleValue(); o[0].setXY(x, y); } catch (final Exception e) { } } } catch (final ConstructionException e) { throw e; } catch (final Exception e) { //e.printStackTrace(); throw new ConstructionException("Intersection parameters illegal!"); } return true; } public boolean constructOther(final XmlTree tree, final Construction c) throws ConstructionException { if (!testTree(tree, "OtherIntersection")) { return false; } final XmlTag tag=tree.getTag(); if (tag.hasParam("name")) { final ConstructionObject o=c.find(tag.getValue("name")); if (o==null||!(o instanceof IntersectionObject)) { throw new ConstructionException("OtherIntersection not found!"); } final IntersectionObject oo=(IntersectionObject) o; PointConstructor.setType(tag, oo); o.setDefaults(); set(tree, o); final ConstructionObject ol=c.lastButN(1); if (tag.hasParam("awayfrom")) { oo.setAway(tag.getValue("awayfrom"), true); if (ol!=null&&(ol instanceof IntersectionObject)) { ((IntersectionObject) ol).setAway(tag.getValue("awayfrom"), false); } } else if (tag.hasParam("closeto")) { oo.setAway(tag.getValue("closeto"), false); if (ol!=null&&(ol instanceof IntersectionObject)) { ((IntersectionObject) ol).setAway(tag.getValue("awayfrom"), true); } } if (tag.hasParam("valid")) { oo.setRestricted(false); } } else { throw new ConstructionException( "OtherIntersection must have a name!"); } return true; } @Override public String getTag() { return "Intersection"; } @Override public void construct(final Construction c, final String name, final String params[], final int nparams) throws ConstructionException { if (nparams!=2&&nparams!=3) { throw new ConstructionException(Global.name("exception.nparams")); } final ConstructionObject p1=c.find(params[0]); if (p1==null) { throw new ConstructionException(Global.name("exception.notfound")+" "+params[0]); } final ConstructionObject p2=c.find(params[1]); if (p2==null) { throw new ConstructionException(Global.name("exception.notfound")+" "+params[0]); } final IntersectionObject o[]=construct(p1, p2, c); if (o==null) { throw new ConstructionException(Global.name("exception.type")); } if (o.length==1) { c.add(o[0]); o[0].setDefaults(); if (!name.equals("")) { o[0].setName(name); } } else { if (name.equals("")) { for (final IntersectionObject element : o) { c.add(element); element.setDefaults(); } } else { final String names[]=new String[2]; int n; if ((n=name.indexOf(','))>=0) { names[0]=name.substring(n+1).trim(); names[1]=name.substring(0, n).trim(); } else { names[0]=name; names[1]=""; } for (int i=0; i