Back to index

wims  3.65+svn20090927
TrackObject.java
Go to the documentation of this file.
00001 package rene.zirkel.objects;
00002 
00003 // file: TrackObject.java
00004 
00005 import java.awt.Checkbox;
00006 import java.awt.Panel;
00007 import java.util.Enumeration;
00008 import java.util.Vector;
00009 
00010 import rene.gui.*;
00011 import rene.util.xml.XmlWriter;
00012 import rene.zirkel.*;
00013 import rene.zirkel.construction.*;
00014 import rene.zirkel.dialogs.*;
00015 import rene.zirkel.graphics.*;
00016 import rene.zirkel.structures.*;
00017 
00018 class TrackEditDialog extends ObjectEditDialog
00019 {      IconBar IC,TypeIB;
00020        Checkbox Fixed,Discrete;
00021        MyTextField DMin;
00022 
00023        public TrackEditDialog (ZirkelCanvas zc, TrackObject o)
00024        {      super(zc.getFrame(),Zirkel.name("edit.function.title"),o,"function");
00025        }
00026        
00027        public void addFirst (Panel P)
00028        {      Fixed=new Checkbox("");
00029               Fixed.setState(O.isFixed());
00030               P.add(new MyLabel(Zirkel.name("edit.fixed"))); P.add(Fixed);
00031               DMin=new MyTextField(""+((TrackObject)O).getDMin());
00032               P.add(new MyLabel(Zirkel.name("edit.track.dmin"))); P.add(DMin);
00033        }
00034        
00035        public void addSecond (Panel P)
00036        {      TrackObject T=(TrackObject)O;
00037               
00038               IC=new IconBar(F);
00039               IC.setIconBarListener(this);
00040               IC.addOnOffLeft("filled");
00041               IC.setState("filled",T.isFilled());
00042               IC.setIconBarListener(this);
00043               P.add(new MyLabel(""));
00044               P.add(IC);
00045               
00046               TypeIB=new IconBar(F);
00047               TypeIB.addToggleGroupLeft("type",6);
00048               TypeIB.toggle("type",T.getType());
00049               P.add(new MyLabel("")); P.add(TypeIB);
00050               
00051               P.add(new MyLabel(Zirkel.name("edit.discrete"))); P.add(Discrete=new Checkbox());
00052               Discrete.setState(T.isDiscrete());
00053               
00054        }
00055        
00056        public void iconPressed (String o)
00057        {      if (o.equals("filled"))
00058               {      if (IC.getState("filled"))
00059                      {      IB.setState("isback",true);
00060                             ThicknessIB.setEnabled("solid",true);
00061                      }
00062                      else
00063                      {      IB.setState("isback",false);
00064                             ThicknessIB.setState("solid",false);
00065                             ThicknessIB.setEnabled("solid",false);
00066                      }
00067               }
00068               super.iconPressed(o);
00069        }
00070 
00071        public void setAction ()
00072        {      TrackObject f=(TrackObject)O;
00073               f.setFixed(Fixed.getState());
00074               f.setFilled(IC.getState("filled"));
00075               try
00076               {      f.setDMin(new Double(DMin.getText()).doubleValue());
00077               }
00078               catch (Exception e) {}
00079               f.setType(TypeIB.getToggleState("type"));
00080               f.setDiscrete(Discrete.getState());
00081        }
00082 
00083 }
00084 
00091 public class TrackObject extends ConstructionObject
00092        implements PointonObject
00093 {      static Count N=new Count();
00094        PointObject PM;
00095        ConstructionObject O,P;
00096        int PMax=16,PN;
00097        ConstructionObject PO[]=new ConstructionObject[PMax];
00098        boolean Filled=false;
00099        boolean Discrete=false;
00100        int Type=0;
00101        
00102        public void setFilled (boolean flag)
00103        {      Filled=flag;
00104        }
00105 
00106        public boolean isFilled ()
00107        {      return Filled;
00108        }      
00109 
00110        public TrackObject (Construction c,
00111               ConstructionObject p, ConstructionObject po[], int pn,
00112               ConstructionObject o, PointObject pm)
00113        {      super(c);
00114               P=p; PN=pn;
00115               for (int i=0; i<PN; i++) PO[i]=po[i];
00116               O=o; PM=pm;
00117               validate();
00118               updateText();
00119        }
00120        
00121        public String getTag () { return "Track"; }
00122        public int getN () { return N.next(); }
00123        
00124        public void updateText ()
00125        {      if (PM!=null) setText(text3(Zirkel.name("text.track"),
00126                      P.getName(),PM.getName(),O.getName()));
00127               else setText(text2(Zirkel.name("text.trackof"),
00128                      P.getName(),O.getName()));
00129        }
00130        
00131        // Update only from ZirkelCanvas, when needed.
00132        public void validate ()
00133        {}
00134        
00135        PolygonFiller PF=null;
00136        
00137        // Paint the track
00138        public void paint (MyGraphics g, ZirkelCanvas zc)
00139        {      if (!Valid  || mustHide(zc)) return;
00140               Coordinates C;
00141               Enumeration e=V.elements();
00142               double c0,r0,c,r;
00143               if (!Discrete && isStrongSelected() && g instanceof MyGraphics13)
00144               {      PolygonDrawer pm=new PolygonDrawer(g,this);
00145                      pm.useAsMarker();
00146                      if (e.hasMoreElements())
00147                      {      C=(Coordinates)e.nextElement();
00148                             c0=zc.col(C.X); r0=zc.row(C.Y);
00149                             while (e.hasMoreElements())
00150                             {      C=(Coordinates)e.nextElement();
00151                                    c=zc.col(C.X); r=zc.row(C.Y);
00152                                    if (Math.abs(c0-c)<100 && Math.abs(r0-r)<100) 
00153                                    {      pm.drawTo(c,r);
00154                                    }
00155                                    else
00156                                    {      if (isFilled()) PF.finishPolygon();
00157                                           pm.finishPolygon();
00158                                    }
00159                                    c0=c; r0=r;
00160                             }
00161                             pm.finishPolygon();
00162                      }
00163               }
00164               e=V.elements();
00165               if (indicated())
00166               {      boolean sel=P.indicated();
00167                      P.setIndicated(true);
00168                      g.setColor(P);
00169                      P.setIndicated(sel);
00170               }
00171               else g.setColor(this);
00172               if (Discrete)
00173               {      int col=getColorIndex();
00174                      int th=getColorType();
00175                      if (e.hasMoreElements())
00176                      {      C=(Coordinates)e.nextElement();
00177                             c0=zc.col(C.X); r0=zc.row(C.Y);
00178                             while (e.hasMoreElements())
00179                             {      C=(Coordinates)e.nextElement();
00180                                    c=zc.col(C.X); r=zc.row(C.Y);
00181                                    if (Math.abs(c0-c)<100 && Math.abs(r0-r)<100) 
00182                                    {      if (isFilled()) PF.drawTo(c,r);
00183                                    }
00184                                    else
00185                                    {      if (isFilled()) PF.finishPolygon();
00186                                    }
00187                                    if (C.Color>=0) setColor(C.Color);
00188                                    if (C.Thickness>=0) setColorType(C.Thickness);
00189                                    PointObject.drawPoint(g,zc,this,C.X,C.Y,Type);
00190                                    setColor(col);
00191                                    setColorType(th);
00192                                    c0=c; r0=r;
00193                             }
00194                             if (isFilled()) PF.finishPolygon();
00195                      }
00196                      for (int i=0; i<PN; i++)
00197                      {      e=VO[i].elements();
00198                             g.setColor(PO[i]);
00199                             if (e.hasMoreElements())
00200                             {      C=(Coordinates)e.nextElement();
00201                                    while (e.hasMoreElements())
00202                                    {      C=(Coordinates)e.nextElement();
00203                                           if (C.Color>=0) setColor(C.Color);
00204                                           if (C.Thickness>=0) setColorType(C.Thickness);
00205                                           PointObject.drawPoint(g,zc,this,C.X,C.Y,Type);
00206                                           setColor(col);
00207                                           setColorType(th);
00208                                    }
00209                             }
00210                      }
00211               }
00212               else
00213               {      PolygonDrawer pd=new PolygonDrawer(g,this);
00214                      if (isFilled())
00215                      {      if (PF==null) PF=new PolygonFiller(g,this);
00216                             PF.start();
00217                             PF.setGraphics(g);
00218                      }
00219                      if (e.hasMoreElements())
00220                      {      C=(Coordinates)e.nextElement();
00221                             c0=zc.col(C.X); r0=zc.row(C.Y);
00222                             while (e.hasMoreElements())
00223                             {      C=(Coordinates)e.nextElement();
00224                                    c=zc.col(C.X); r=zc.row(C.Y);
00225                                    if (Math.abs(c0-c)<100 && Math.abs(r0-r)<100) 
00226                                    {      if (isFilled()) PF.drawTo(c,r);
00227                                           pd.drawTo(c,r);
00228                                    }
00229                                    else
00230                                    {      if (isFilled()) PF.finishPolygon();
00231                                           pd.finishPolygon();
00232                                    }
00233                                    c0=c; r0=r;
00234                             }
00235                             if (isFilled()) PF.finishPolygon();
00236                             pd.finishPolygon();
00237                      }
00238                      for (int i=0; i<PN; i++)
00239                      {      e=VO[i].elements();
00240                             g.setColor(PO[i]);
00241                             pd=new PolygonDrawer(g,PO[i]);
00242                             if (e.hasMoreElements())
00243                             {      C=(Coordinates)e.nextElement();
00244                                    c0=zc.col(C.X); r0=zc.row(C.Y);
00245                                    while (e.hasMoreElements())
00246                                    {      C=(Coordinates)e.nextElement();
00247                                           c=zc.col(C.X); r=zc.row(C.Y);
00248                                           if (Math.abs(c0-c)<100 && Math.abs(r0-r)<100) 
00249                                                  pd.drawTo(c,r);
00250                                           else
00251                                                  pd.finishPolygon();
00252                                           c0=c; r0=r;
00253                                    }
00254                             }
00255                             pd.finishPolygon();
00256                      }
00257               }
00258        }
00259        
00260        public double getSum (double x, double y)
00261               throws ConstructionException
00262        {      if (!Valid) throw new ConstructionException("");
00263               double sum=0;
00264               boolean started=false;
00265               double x0=0,y0=0;
00266               Enumeration e=V.elements();
00267               while (e.hasMoreElements())
00268               {      Coordinates C=(Coordinates)e.nextElement();
00269                      if (started)
00270                      {      sum+=(-(C.X-x)*(y0-y)+(C.Y-y)*(x0-x))/2;
00271                      }
00272                      x0=C.X; y0=C.Y; started=true;
00273               }
00274               return sum;
00275        }
00276 
00277        public double getSum ()
00278               throws ConstructionException
00279        {      if (!Valid) throw new ConstructionException("");
00280               double sum=0;
00281               boolean started=false;
00282               double x0=0,y0=0,x=0,y=0;
00283               Enumeration e=V.elements();
00284               while (e.hasMoreElements())
00285               {      Coordinates C=(Coordinates)e.nextElement();
00286                      if (started)
00287                      {      sum+=(-(C.X-x)*(y0-y)+(C.Y-y)*(x0-x))/2;
00288                      }
00289                      else
00290                      {      x=C.X; y=C.Y;
00291                      }
00292                      x0=C.X; y0=C.Y; started=true;
00293               }
00294               return sum;
00295        }
00296 
00297        public double getLength ()
00298        throws ConstructionException
00299 {      if (!Valid) throw new ConstructionException("");
00300        double sum=0;
00301        boolean started=false;
00302        double x0=0,y0=0;
00303        Enumeration e=V.elements();
00304        while (e.hasMoreElements())
00305        {      Coordinates C=(Coordinates)e.nextElement();
00306               if (started)
00307               {      sum+=Math.sqrt((C.X-x0)*(C.X-x0)+(C.Y-y0)*(C.Y-y0));
00308               }
00309               x0=C.X; y0=C.Y; started=true;
00310        }
00311        return sum;
00312 }
00313 
00314        public void printArgs (XmlWriter xml)
00315        {      super.printArgs(xml);
00316               if (PM!=null) xml.printArg("point",PM.getName());
00317               xml.printArg("on",O.getName());
00318               xml.printArg("track",P.getName());
00319               xml.printArg("dmin",""+DMin);
00320               for (int i=0; i<PN; i++)    
00321               {      xml.printArg("track"+i,PO[i].getName());
00322               }
00323               if (Filled) xml.printArg("filled","true");
00324               if (Fixed) xml.printArg("fixed","true");
00325               if (Discrete) xml.printArg("discrete","true");
00326               printType(xml);
00327        }      
00328        
00329        public void printType (XmlWriter xml)
00330        {      if (Type!=0)
00331               {      switch (Type)
00332                      {      case PointObject.DIAMOND : xml.printArg("shape","diamond"); break;
00333                             case PointObject.CIRCLE : xml.printArg("shape","circle"); break;
00334                             case PointObject.DOT : xml.printArg("shape","dot"); break;
00335                             case PointObject.CROSS : xml.printArg("shape","cross"); break;
00336                             case PointObject.DCROSS : xml.printArg("shape","dcross"); break;
00337                      }
00338               }
00339 
00340        }
00341        
00342 
00343        public Enumeration depending ()
00344        {      super.depending();
00345               if (PM!=null) DL.add(PM);
00346               DL.add(O);
00347               DL.add(P);
00348               for (int i=0; i<PN; i++)    
00349               {      DL.add(PO[i]);
00350               }
00351               return DL.elements();
00352        }
00353 
00354        public boolean equals (ConstructionObject o)
00355        {      return false;
00356        }
00357 
00358        public void translate ()
00359        {      if (PM!=null) PM=(PointObject)PM.getTranslation();
00360               O=O.getTranslation();
00361               P=P.getTranslation();
00362        }
00363 
00364        public boolean maybeTransparent ()
00365        {      return false;
00366        }      
00367 
00368        Vector V=new Vector();
00369        Vector VO[]=new Vector[PMax];
00370 
00371        // Mainly to select the track for delete
00372        public boolean nearto (int x, int y, ZirkelCanvas zc)
00373        {      if (!displays(zc)) return false;
00374               int size=(int)zc.selectionSize();
00375               Enumeration e=V.elements();
00376               while (e.hasMoreElements())
00377               {      Coordinates c=(Coordinates)e.nextElement();
00378                      double col=zc.col(c.X),row=zc.row(c.Y);
00379                      if (Math.max(Math.abs(col-x),Math.abs(row-y))<size)
00380                             return true;
00381               }
00382               return false;
00383        }
00384 
00385        public boolean onlynearto (int c, int r, ZirkelCanvas zc)
00386        {      return false;
00387        }
00388        
00389        double da=0;
00390        double oldx,oldy;
00391        double X,Y,DX,DY;
00392        double XO[]=new double[PMax],YO[]=new double[PMax],
00393               DXO[]=new double[PMax],DYO[]=new double[PMax];
00394        int Omit=1;
00395 
00396        double mod (double x)
00397        {      if (x>=Math.PI) return x-2*Math.PI;
00398               if (x<-Math.PI) return x+2*Math.PI;
00399               return x;
00400        }
00401        
00402        boolean DontProject=false;
00403        double DMin=0.001;
00404 
00419        public synchronized void docompute (ZirkelCanvas zc)
00420        {      V=new Vector();
00421               for (int i=0; i<PN; i++) VO[i]=new Vector();
00422               // Running on a circle:
00423               if (O instanceof PrimitiveCircleObject)
00424               {      zc.getConstruction().shouldSwitch(false);
00425                      PrimitiveCircleObject c=(PrimitiveCircleObject)O;
00426                      double x=c.getX(),y=c.getY(),r=c.getR();
00427                      PM.project(c);
00428                      double amin=0,amax=0,astart=0,anull=0;
00429                      double dmax=0.5;
00430                      boolean range=false;
00431                      if (c.hasRange())
00432                      {      range=true;
00433                             double a1=c.getA1();
00434                             double a2=c.getA2();
00435                             double d=a2-a1;
00436                             while (d<0) d+=2*Math.PI;
00437                             while (d>=2*Math.PI) d-=2*Math.PI;
00438                             amin=astart=-d/2;
00439                             amax=d/2;
00440                             anull=(a1+a2)/2;
00441                      }
00442                      else
00443                      {      amin=astart=-Math.PI*0.9999;
00444                             amax=Math.PI*0.9999;
00445                      }
00446                      double a=astart;
00447                      PM.move(x+r*Math.cos(anull+a),y+r*Math.sin(anull+a));
00448                      PM.project(c);
00449                      zc.getConstruction().validate(this,PM);
00450                      zc.resetSum();
00451                      double x1=0,y1=0;
00452                      boolean started=false;
00453                      if (P.valid())
00454                      {      zc.getConstruction().shouldSwitch(true);
00455                             if (P instanceof PointObject)
00456                             {      PointObject p=(PointObject)P;
00457                                    x1=p.getX(); y1=p.getY();
00458                                    addCoordinates(V,P,x1,y1);
00459                                    started=true;
00460                             }
00461                             else if (P instanceof PrimitiveLineObject)
00462                             {      PrimitiveLineObject L=(PrimitiveLineObject)P;
00463                                    X=L.getX(); Y=L.getY(); DX=L.getDX(); DY=L.getDY();
00464                                    started=true; 
00465                             }
00466                      }
00467                      boolean startedO[]=new boolean[PMax];
00468                      for (int i=0; i<PN; i++) startedO[i]=false;
00469                      long time=System.currentTimeMillis();
00470                      addSecondary(startedO);
00471                      double dmin=DMin;
00472                      if (da<1e-10 || da>zc.dx(1)) da=zc.dx(1)/10;
00473                      double aold=a;
00474                      while (true)
00475                      {      a=a+da;
00476                             boolean Break=false;
00477                             if ((!started || range) && a>=amax)
00478                             {      a=amax; 
00479                                    Break=true;
00480                             }
00481                             else if ((!started || range) && a<=amin)
00482                             {      a=amin;
00483                                    Break=true;
00484                             }
00485                             else if (started && da>0)
00486                             {      if ((mod(aold-astart)<0 && mod(a-astart)>=0) &&
00487                                           !zc.getConstruction().haveSwitched())
00488                                    {      Break=true;
00489                                           a=astart;
00490                                    }
00491                             }
00492                             aold=a;
00493                             PM.move(x+r*Math.cos(anull+a),y+r*Math.sin(anull+a));
00494                             PM.project(c);
00495                             zc.getConstruction().validate(this,PM);
00496                             if (P.valid())
00497                             {      if (!started)
00498                                    {      zc.getConstruction().shouldSwitch(true);
00499                                           astart=a;
00500                                    }
00501                                    double x2=0,y2=0;
00502                                    boolean valid=false;
00503                                    if (P instanceof PointObject)
00504                                    {      PointObject p=(PointObject)P;
00505                                           x2=p.getX(); y2=p.getY();
00506                                           valid=true;
00507                                    }
00508                                    else if (P instanceof PrimitiveLineObject)
00509                                    {      PrimitiveLineObject L=(PrimitiveLineObject)P;
00510                                           if (!started)
00511                                           {      X=L.getX(); Y=L.getY(); DX=L.getDX(); DY=L.getDY();
00512                                           }
00513                                           else
00514                                           {      double xx,yy,dx,dy;
00515                                                  xx=L.getX(); yy=L.getY(); dx=L.getDX(); dy=L.getDY();
00516                                                  double det=dx*DY-dy*DX;
00517                                                  if (Math.sqrt(Math.abs(det))>1e-9)
00518                                                  {      double h=(-(X-xx)*DY+DX*(Y-yy))/(-det);
00519                                                         x2=xx+h*dx; y2=yy+h*dy;
00520                                                         valid=true;
00521                                                  }
00522                                                  X=xx; Y=yy; DX=dx; DY=dy;
00523                                           }                                  
00524                                    }
00525                                    double dist=zc.dCenter(x2,y2);
00526                                    boolean different=((int)zc.col(x1)!=(int)zc.col(x2) || 
00527                                           (int)zc.row(y1)!=(int)zc.row(y2));
00528                                    if (valid && different)
00529                                    {      addCoordinates(V,P,x2,y2);
00530                                    }
00531                                    double dp=Math.abs(x2-x1)+Math.abs(y2-y1);
00532                                    da=updateDA(da,valid,dist,dp,dmin,dmax,zc);
00533                                    x1=x2; y1=y2;
00534                                    started=true;
00535                             }
00536                             else if (started)
00537                             {      da=-da;
00538                             }
00539                             addSecondary(startedO);
00540                             if (Break || System.currentTimeMillis()-time>1000) break;
00541                      }
00542                      // System.out.println("Points "+V.size()+" Time "+(System.currentTimeMillis()-time));
00543               }
00544               // Running on a line:
00545               else if (O instanceof PrimitiveLineObject)
00546               {      zc.getConstruction().shouldSwitch(false);
00547                      PrimitiveLineObject l=(PrimitiveLineObject)O;
00548                      PM.project(l);
00549                      double lx=l.getX(),ly=l.getY(),ldx=l.getDX(),ldy=l.getDY();
00550                      double amin=0,amax=0,astart=0;
00551                      double dmax=0.5;
00552                      boolean range=false;
00553                      if (l instanceof RayObject)
00554                      {      amin=astart=0;
00555                             amax=Math.PI*0.9999;
00556                             range=true;
00557                      }
00558                      else if (l instanceof SegmentObject)
00559                      {      amin=astart=0; 
00560                             double r=((SegmentObject)l).getLength();
00561                             dmax=r/20;
00562                             amax=Math.atan(r)*2;
00563                             range=true;
00564                      }
00565                      else
00566                      {      amin=astart=-Math.PI*0.99999;
00567                             amax=Math.PI*0.9999;
00568                      }                           
00569                      double a=astart;
00570                      double hd=Math.tan(mod(a)/2);
00571                      PM.move(lx+hd*ldx,ly+hd*ldy);
00572                      PM.project(l);
00573                      zc.getConstruction().validate(this,PM);
00574                      zc.resetSum();
00575                      double x1=0,y1=0;
00576                      boolean started=false;
00577                      if (P.valid())
00578                      {      zc.getConstruction().shouldSwitch(true);
00579                             if (P instanceof PointObject)
00580                             {      PointObject p=(PointObject)P;
00581                                    x1=p.getX(); y1=p.getY();
00582                                    addCoordinates(V,P,x1,y1);
00583                                    started=true;
00584                             }
00585                             else if (P instanceof PrimitiveLineObject)
00586                             {      PrimitiveLineObject L=(PrimitiveLineObject)P;
00587                                    X=L.getX(); Y=L.getY(); DX=L.getDX(); DY=L.getDY();
00588                                    started=true; 
00589                             }
00590                      }
00591                      boolean startedO[]=new boolean[PMax];
00592                      for (int i=0; i<PN; i++) startedO[i]=false;
00593                      long time=System.currentTimeMillis();
00594                      addSecondary(startedO);
00595                      double dmin=DMin;
00596                      if (da<1e-10 || da>zc.dx(1)) da=zc.dx(1)/10;
00597                      double aold=a;
00598                      while (true)
00599                      {      a=a+da;
00600                             boolean Break=false;
00601                             if ((!started || range) && a>=amax)
00602                             {      a=amax; 
00603                                    Break=true;
00604                             }
00605                             else if ((!started || range) && a<=amin)
00606                             {      a=amin;
00607                                    Break=true;
00608                             }
00609                             else if (started && da>0)
00610                             {      if ((mod(aold-astart)<0 && mod(a-astart)>=0) &&
00611                                           !zc.getConstruction().haveSwitched())
00612                                    {      Break=true;
00613                                           a=astart;
00614                                    }
00615                             }
00616                             aold=a;
00617                             hd=Math.tan(mod(a)/2);
00618                             PM.move(lx+hd*ldx,ly+hd*ldy);
00619                             PM.project(l);
00620                             zc.getConstruction().validate(this,PM);
00621                             if (P.valid())
00622                             {      if (!started)
00623                                    {      zc.getConstruction().shouldSwitch(true);
00624                                           astart=a;
00625                                    }
00626                                    double x2=0,y2=0;
00627                                    boolean valid=false;
00628                                    if (P instanceof PointObject)
00629                                    {      PointObject p=(PointObject)P;
00630                                           x2=p.getX(); y2=p.getY();
00631                                           valid=true;
00632                                    }
00633                                    else if (P instanceof PrimitiveLineObject)
00634                                    {      PrimitiveLineObject L=(PrimitiveLineObject)P;
00635                                           if (!started)
00636                                           {      X=L.getX(); Y=L.getY(); DX=L.getDX(); DY=L.getDY();
00637                                           }
00638                                           else
00639                                           {      double xx,yy,dx,dy;
00640                                                  xx=L.getX(); yy=L.getY(); dx=L.getDX(); dy=L.getDY();
00641                                                  double det=dx*DY-dy*DX;
00642                                                  if (Math.sqrt(Math.abs(det))>1e-9)
00643                                                  {      double h=(-(X-xx)*DY+DX*(Y-yy))/(-det);
00644                                                         x2=xx+h*dx; y2=yy+h*dy;
00645                                                         valid=true;
00646                                                  }
00647                                                  X=xx; Y=yy; DX=dx; DY=dy;
00648                                           }                                  
00649                                    }
00650                                    double dist=zc.dCenter(x2,y2);
00651                                    boolean different=((int)zc.col(x1)!=(int)zc.col(x2) || 
00652                                           (int)zc.row(y1)!=(int)zc.row(y2));
00653                                    if (valid && different)
00654                                    {      addCoordinates(V,P,x2,y2);
00655                                    }
00656                                    double dp=Math.abs(x2-x1)+Math.abs(y2-y1);
00657                                    da=updateDA(da,valid,dist,dp,dmin,dmax,zc);
00658                                    x1=x2; y1=y2;
00659                                    started=true;
00660                             }
00661                             else if (started)
00662                             {      da=-da;
00663                             }
00664                             addSecondary(startedO);
00665                             if (Break || System.currentTimeMillis()-time>1000) break;
00666                      }
00667               }
00668               // Running an expression slider:
00669               else if (O instanceof ExpressionObject)
00670               {      zc.getConstruction().shouldSwitch(false);
00671                      ExpressionObject eo=(ExpressionObject)O;
00672                      if (!eo.isSlider()) return;
00673                      double amin=0,amax=0,astart=0;
00674                      double dmax=0.5;
00675                      boolean range=false;
00676                      amin=astart=0; 
00677                      double r=1;
00678                      dmax=r/20;
00679                      amax=r;
00680                      range=true;
00681                      double a=astart;
00682                      double hd=a;
00683                      eo.setSliderPosition(0);
00684                      zc.getConstruction().validate(P,null);
00685                      zc.resetSum();
00686                      double x1=0,y1=0;
00687                      boolean started=false;
00688                      if (P.valid())
00689                      {      zc.getConstruction().shouldSwitch(true);
00690                             if (P instanceof PointObject)
00691                             {      PointObject p=(PointObject)P;
00692                                    x1=p.getX(); y1=p.getY();
00693                                    addCoordinates(V,P,x1,y1);
00694                                    started=true;
00695                             }
00696                             else if (P instanceof PrimitiveLineObject)
00697                             {      PrimitiveLineObject L=(PrimitiveLineObject)P;
00698                                    X=L.getX(); Y=L.getY(); DX=L.getDX(); DY=L.getDY();
00699                                    started=true; 
00700                             }
00701                      }
00702                      boolean startedO[]=new boolean[PMax];
00703                      for (int i=0; i<PN; i++) startedO[i]=false;
00704                      long time=System.currentTimeMillis();
00705                      addSecondary(startedO);
00706                      double dmin=DMin;
00707                      if (da<1e-10 || da>zc.dx(1)) da=zc.dx(1)/10;
00708                      double aold=a;
00709                      double x2=0,y2=0;
00710                      while (true)
00711                      {      a=a+da;
00712                             boolean Break=false;
00713                             if ((!started || range) && a>=amax)
00714                             {      a=amax; 
00715                                    Break=true;
00716                             }
00717                             else if ((!started || range) && a<=amin)
00718                             {      a=amin;
00719                                    Break=true;
00720                             }
00721                             else if (started && da>0)
00722                             {      if ((mod(aold-astart)<0 && mod(a-astart)>=0) &&
00723                                           !zc.getConstruction().haveSwitched())
00724                                    {      Break=true;
00725                                           a=astart;
00726                                    }
00727                             }
00728                             aold=a;
00729                             hd=a;
00730                             eo.setSliderPosition(hd);
00731                             zc.getConstruction().validate(P,null);
00732                             if (P.valid())
00733                             {      if (!started)
00734                                    {      zc.getConstruction().shouldSwitch(true);
00735                                           astart=a;
00736                                    }
00737                                    boolean valid=false;
00738                                    if (P instanceof PointObject)
00739                                    {      PointObject p=(PointObject)P;
00740                                           x2=p.getX(); y2=p.getY();
00741                                           valid=true;
00742                                    }
00743                                    else if (P instanceof PrimitiveLineObject)
00744                                    {      PrimitiveLineObject L=(PrimitiveLineObject)P;
00745                                           if (!started)
00746                                           {      X=L.getX(); Y=L.getY(); DX=L.getDX(); DY=L.getDY();
00747                                           }
00748                                           else
00749                                           {      double xx,yy,dx,dy;
00750                                                  xx=L.getX(); yy=L.getY(); dx=L.getDX(); dy=L.getDY();
00751                                                  double det=dx*DY-dy*DX;
00752                                                  if (Math.sqrt(Math.abs(det))>1e-9)
00753                                                  {      double h=(-(X-xx)*DY+DX*(Y-yy))/(-det);
00754                                                         x2=xx+h*dx; y2=yy+h*dy;
00755                                                         valid=true;
00756                                                  }
00757                                                  X=xx; Y=yy; DX=dx; DY=dy;
00758                                           }                                  
00759                                    }
00760                                    double dist=zc.dCenter(x2,y2);
00761                                    boolean different=((int)zc.col(x1)!=(int)zc.col(x2) || 
00762                                           (int)zc.row(y1)!=(int)zc.row(y2));
00763                                    if (valid && different)
00764                                    {      addCoordinates(V,P,x2,y2);
00765                                    }
00766                                    double dp=Math.abs(x2-x1)+Math.abs(y2-y1);
00767                                    da=updateDA(da,valid,dist,dp,dmin,dmax,zc);
00768                                    x1=x2; y1=y2;
00769                                    started=true;
00770                             }
00771                             else if (started)
00772                             {      addCoordinates(V,P,x2,y2);
00773                                    da=-da;
00774                             }
00775                             addSecondary(startedO);
00776                             if (Break || System.currentTimeMillis()-time>1000) break;
00777                      }
00778               }
00779        }
00780 
00781        
00782        // This is the update function. It is a time consuming moving of
00783        // the point P on the object O. The function is a copy from the
00784        // same function in ObjectTracker.
00785        public synchronized void compute (ZirkelCanvas zc)
00786        {      if (Fixed && !StartFix) return;
00787               StartFix=false;
00788               double x=0,y=0;
00789               if (PM!=null)
00790               {      x=PM.getX(); y=PM.getY();
00791               }
00792               else if (O instanceof ExpressionObject && ((ExpressionObject)O).isSlider())
00793               {      x=((ExpressionObject)O).getSliderPosition();
00794               }
00795               zc.getConstruction().clearSwitches();
00796               zc.getConstruction().shouldSwitch(true);
00797               DontProject=true;
00798               docompute(zc);
00799               DontProject=false;
00800               zc.getConstruction().shouldSwitch(false);
00801               zc.getConstruction().clearSwitches();
00802               if (PM!=null)
00803               {      PM.move(x,y);
00804               }
00805               else if (O instanceof ExpressionObject && ((ExpressionObject)O).isSlider())
00806               {      ((ExpressionObject)O).setSliderPosition(x);
00807               }
00808               Enumeration e=V.elements();
00809               if (e.hasMoreElements())
00810               {      Coordinates c=(Coordinates)e.nextElement();
00811                      x=c.X; y=c.Y;
00812                      double col1=zc.col(c.X); 
00813                      double row1=zc.row(c.Y);
00814                      while (e.hasMoreElements())
00815                      {      c=(Coordinates)e.nextElement();
00816                             double col2=zc.col(c.X); 
00817                             double row2=zc.row(c.Y);
00818                             c.flag=Math.abs(col2-col1)<100 && Math.abs(row2-row1)<100;
00819                             row1=row2; col1=col2;
00820                      }
00821               }
00822               zc.dovalidate();
00823        }
00824               
00825        public void addSecondary (boolean startedO[])
00826        {      for (int i=0; i<PN; i++)
00827               {      if (!PO[i].valid()) continue;
00828                      if (PO[i] instanceof PointObject)
00829                      {      PointObject p=(PointObject)PO[i];
00830                             addCoordinates(VO[i],p,p.getX(),p.getY());
00831                             VO[i].addElement(new Coordinates(p.getX(),p.getY()));
00832                      }
00833                      else if (PO[i] instanceof PrimitiveLineObject)
00834                      {      PrimitiveLineObject L=(PrimitiveLineObject)PO[i];
00835                             if (!startedO[i])
00836                             {      XO[i]=L.getX(); YO[i]=L.getY(); 
00837                                    DXO[i]=L.getDX(); DYO[i]=L.getDY();
00838                                    startedO[i]=true;
00839                             }
00840                             else
00841                             {      double xx,yy,dx,dy;
00842                                    xx=L.getX(); yy=L.getY();
00843                                    dx=L.getDX(); dy=L.getDY();
00844                                    double det=dx*DYO[i]-dy*DXO[i];
00845                                    if (Math.sqrt(Math.abs(det))>1e-9)
00846                                    {      double h=(-(XO[i]-xx)*DYO[i]+
00847                                                  DXO[i]*(YO[i]-yy))/(-det);
00848                                           XO[i]=xx; YO[i]=yy; DXO[i]=dx; DYO[i]=dy;
00849                                           addCoordinates(VO[i],PO[i],xx+h*dx,yy+h*dy);
00850                                    }
00851                             }
00852                      }
00853               }
00854        }
00855        
00856        public void addCoordinates (Vector v, ConstructionObject p, double x, double y)
00857        {      Coordinates C=new Coordinates(x,y);
00858               if (Discrete && p instanceof PointObject)
00859               {      C.Color=p.getColorIndex();
00860                      C.Thickness=p.getColorType();
00861               }
00862               v.addElement(C);
00863        }
00864        
00865        public double StepSize=5;
00866        
00867        public double updateDA (double da, boolean valid, double dist, double dp, 
00868                      double dmin, double dmax,
00869                      ZirkelCanvas zc)
00870        {      if (V.size()>0 && valid)
00871               {      if (dist<1.2)
00872                      {      if (dp>zc.dx(StepSize)) da/=2;
00873                             else if (dp<zc.dx(StepSize/2)) da*=2;
00874                             if (da>0 && da<dmin) da=dmin;
00875                             else if (da<0 && da>-dmin) da=-dmin;
00876                             if (da>dmax) da=dmax;
00877                             else if (da<-dmax) da=-dmax;
00878                      }
00879                      else
00880                      {      if (dp>zc.dx(StepSize*10)) da/=2;
00881                             else if (dp<zc.dx(StepSize*5)) da*=2;
00882                             if (da>0 && da<dmin) da=dmin;
00883                             else if (da<0 && da>-dmin) da=-dmin;
00884                             if (da>dmax) da=dmax;
00885                             else if (da<-dmax) da=-dmax;
00886                      }
00887               }
00888               return da;
00889        }
00890        
00891        public boolean hasUnit ()
00892        {      return false;
00893        }
00894 
00898        public synchronized void project (PointObject P) 
00899        {      if (DontProject) return;
00900               Enumeration e=V.elements();
00901               double x=0,y=0,x0=0,y0=0,dmin=0;
00902               boolean started=false;
00903               while (e.hasMoreElements())
00904               {      Coordinates c=(Coordinates)e.nextElement();
00905                      double x1=c.X;
00906                      double y1=c.Y;
00907                      if (!started)
00908                      {      dmin=Math.sqrt((P.getX()-x1)*(P.getX()-x1)+
00909                                           (P.getY()-y1)*(P.getY()-y1));
00910                             x0=x=x1; y0=y=y1;
00911                             started=true;
00912                      }
00913                      else
00914                      {      if (c.flag)
00915                             {      double h=(x1-x0)*(x1-x0)+(y1-y0)*(y1-y0);
00916                                    if (h<1e-10) h=1e-10;
00917                                    double g=(P.getX()-x0)*(x1-x0)+(P.getY()-y0)*(y1-y0);
00918                                    if (g<0) g=0;
00919                                    if (g>h) g=h;
00920                                    double x2=x0+g/h*(x1-x0),y2=y0+g/h*(y1-y0);
00921                                    double d=Math.sqrt((P.getX()-x2)*(P.getX()-x2)+
00922                                           (P.getY()-y2)*(P.getY()-y2));
00923                                    if (d<dmin)
00924                                    {      dmin=d;
00925                                           x=x2; y=y2;
00926                                    }
00927                             }
00928                             x0=x1; y0=y1;
00929                      }
00930               }
00931               if (started)
00932               {      P.setXY(x,y);
00933                      P.Valid=true;
00934               }
00935               else
00936               {      P.Valid=false;
00937               }
00938        }
00939 
00940        public String getDisplayValue ()
00941        {      try
00942               {      return ""+getSum();
00943               }
00944               catch (Exception e) { return "???"; }
00945        }
00946 
00947        public void project 
00948        (PointObject P, double alpha) 
00949        {      project(P);
00950        }
00951 
00952        public void edit (ZirkelCanvas zc)
00953        {      ObjectEditDialog d=new TrackEditDialog(zc,this);
00954               d.setVisible(true);
00955               zc.repaint();
00956               validate();
00957               if (d.wantsMore())
00958               {      new EditConditionals(zc.getFrame(),this);
00959                      validate();
00960               }             
00961        }
00962 
00963        public boolean canDisplayName ()
00964        {      return false;
00965        }
00966        
00967        boolean Fixed=false,StartFix;
00968 
00969        public boolean isFixed ()
00970        {      return Fixed;
00971        }
00972        
00973        public void setFixed (boolean f)
00974        {      Fixed=f;
00975               if (Fixed) StartFix=true;
00976        }
00977 
00978        public void setDMin (double dmin)
00979        {      DMin=dmin;
00980        }
00981        
00982        public double getDMin ()
00983        {      return DMin;
00984        }
00985 
00986        public int getType ()
00987        {      return Type;
00988        }
00989        
00990        public void setType (int type)
00991        {      Type=type;
00992        }
00993 
00994        public boolean isDiscrete() {
00995               return Discrete;
00996        }
00997 
00998        public void setDiscrete(boolean discrete) {
00999               Discrete = discrete;
01000        }
01001 
01002        public boolean canInteresectWith(ConstructionObject o) 
01003        {      return true;
01004        }
01005 }
01006 
01007