Back to index

wims  3.65+svn20090927
PrimitiveLineObject.java
Go to the documentation of this file.
00001 package rene.zirkel.objects;
00002 
00003 // file: PrimitiveLineObject.java
00004 
00005 import java.awt.Checkbox;
00006 import java.awt.Frame;
00007 import java.awt.Panel;
00008 import java.awt.TextField;
00009 import java.awt.event.FocusEvent;
00010 import java.util.Enumeration;
00011 
00012 import rene.gui.Global;
00013 import rene.gui.IconBar;
00014 import rene.gui.MyLabel;
00015 import rene.gui.TextFieldAction;
00016 import rene.util.xml.XmlWriter;
00017 import rene.zirkel.Zirkel;
00018 import rene.zirkel.ZirkelCanvas;
00019 import rene.zirkel.construction.Construction;
00020 import rene.zirkel.dialogs.EditConditionals;
00021 import rene.zirkel.dialogs.ObjectEditDialog;
00022 import rene.zirkel.graphics.MyGraphics;
00023 import rene.zirkel.graphics.MyGraphics13;
00024 import rene.zirkel.structures.Coordinates;
00025 
00026 class LineEditDialog extends ObjectEditDialog
00027 {      TextField Length;
00028        Checkbox Fixed,Restricted;
00029        IconBar IC;
00030        
00031        public LineEditDialog (Frame f, PrimitiveLineObject o)
00032        {      super(f,Zirkel.name("edit.line.title"),o);
00033        }
00034        
00035        public void addFirst (Panel P)
00036        {      PrimitiveLineObject l=(PrimitiveLineObject)O;
00037 
00038               if (l instanceof SegmentObject)
00039               {      Length=new TextFieldAction(this,"Length",((SegmentObject)l).getStringLength(),30);
00040                      if (((SegmentObject)l).canFix())
00041                      {      Fixed=new Checkbox("");     
00042                             Fixed.setState(((SegmentObject)l).fixed());
00043                      }
00044                      else Length.setEditable(false);
00045               }
00046 
00047               if ((l instanceof PlumbObject) &&
00048                      ((PlumbObject)l).canRestrict())
00049               {      Restricted=new Checkbox("");
00050                      Restricted.setState(((PlumbObject)l).isRestricted());
00051               }
00052 
00053               if (Length!=null)
00054               {      P.add(new MyLabel(Zirkel.name("edit.segment.length"))); P.add(Length);
00055               }
00056               if (Fixed!=null)
00057               {      P.add(new MyLabel(Zirkel.name("edit.fixed"))); P.add(Fixed);
00058               }
00059 
00060               if (Restricted!=null)
00061               {      P.add(new MyLabel(Zirkel.name("edit.plumb.restricted")));
00062                      P.add(Restricted);
00063               }
00064               
00065        }
00066 
00067        public void addSecond (Panel P)
00068        {      PrimitiveLineObject l=(PrimitiveLineObject)O;
00069               IC=new IconBar(F);
00070               IC.setIconBarListener(this);
00071               if (!(l instanceof SegmentObject))
00072               {      IC.addToggleLeft("plines");
00073                      IC.setState("plines",l.isPartial());
00074               }
00075               if (l instanceof SegmentObject)
00076               {      IC.addToggleLeft("arrow");
00077                      IC.setState("arrow",((SegmentObject)l).isArrow());
00078               }
00079               P.add(new MyLabel(""));
00080               P.add(IC);
00081        }
00082        
00083        public boolean showsValue ()
00084        {      return Length!=null;
00085        }
00086 
00087        public void doAction (String o)
00088        {      if (o.equals("Length") && Fixed!=null)
00089               {      Fixed.setState(true);
00090                      super.doAction("OK");
00091               }
00092               else super.doAction(o);
00093        }
00094        
00095        public void setAction ()
00096        {      if (Fixed!=null)
00097               {      try
00098                      {      ((SegmentObject)O).setFixed(Fixed.getState(),Length.getText());
00099                      }
00100                      catch (Exception e) {}
00101               }
00102               if (Restricted!=null)
00103               {      ((PlumbObject)O).setRestricted(Restricted.getState());
00104               }
00105               if (!(O instanceof SegmentObject))
00106               {      ((PrimitiveLineObject)O).setPartial(IC.getState("plines"));
00107               }
00108               else if (O instanceof SegmentObject)
00109               {      ((SegmentObject)O).setArrow(IC.getState("arrow"));
00110                      Global.setParameter("unit.length",Unit.getText());
00111               }
00112        }
00113        
00114        public void focusGained (FocusEvent e)
00115        {      if (Fixed!=null && Fixed.getState()) Length.requestFocus();
00116               else super.focusGained(e);
00117        }
00118 }
00119 
00120 public class PrimitiveLineObject extends ConstructionObject
00121        implements PointonObject
00122 {      protected double X1,Y1,DX,DY;
00123        protected PointObject P1;
00124        PointObject Dep[];
00125        int NDep;
00126        boolean Partial=false;
00127 
00128        public PrimitiveLineObject (Construction c)
00129        {      super(c);
00130               setColor(ColorIndex);
00131        }
00132 
00133        public String getTag () { return "Line"; }
00134        
00135        double k1,k2;
00136        boolean k12valid=false;
00137 
00138        public void paint (MyGraphics g, ZirkelCanvas zc)
00139        {      if (!Valid || mustHide(zc)) return;
00140               //compute middle of the screen:
00141               double xm=(zc.minX()+zc.maxX())/2,ym=(zc.minY()+zc.maxY())/2;
00142               // compute distance from middle to line:
00143               double d=(xm-X1)*DY-(ym-Y1)*DX;
00144               // compute point with minimal distance
00145               double x=xm-d*DY,y=ym+d*DX;
00146               // compute size of the screen
00147               double a=Math.max(zc.maxX()-zc.minX(),zc.maxY()-zc.minY());
00148               if (Math.abs(d)>a) return;
00149               // compute distance from closest point to source
00150               double b=(x-X1)*DX+(y-Y1)*DY;
00151               // compute the two visible endpoints
00152               k1=b-a; k2=b+a; k12valid=true;
00153               if (Partial && Dep!=null && !zc.showHidden())
00154               {      double dd=(zc.maxX()-zc.minX())/20;
00155                      double dmin=-dd,dmax=+dd;
00156                      if (Dep!=null)
00157                      {      for (int i=0; i<NDep; i++)
00158                             {      if (!Dep[i].valid() || Dep[i].mustHide(zc)) continue;
00159                                    double s=project(Dep[i].getX(),Dep[i].getY());
00160                                    if (s-dd<dmin) dmin=s-dd;
00161                                    else if (s+dd>dmax) dmax=s+dd;
00162                             }
00163                      }
00164                      if (k1<dmin) k1=dmin;
00165                      if (k2>dmax) k2=dmax;
00166               }
00167               double c1=zc.col(X1+k1*DX),c2=zc.col(X1+k2*DX),
00168                      r1=zc.row(Y1+k1*DY),r2=zc.row(Y1+k2*DY);
00169               // paint:
00170               if (isStrongSelected() && g instanceof MyGraphics13)
00171               {      ((MyGraphics13)g).drawMarkerLine(c1,r1,c2,r2);
00172               }
00173               g.setColor(this);
00174               g.drawLine(c1,r1,c2,r2,this);
00175               String s=getDisplayText();
00176               if (!s.equals(""))
00177               {      g.setLabelColor(this);
00178                      setFont(g);
00179                      DisplaysText=true;
00180                      if (KeepClose)
00181                      {      double side=(YcOffset<0)?1:-1;
00182                             drawLabel(g,s,zc,X1+XcOffset*DX,Y1+XcOffset*DY,
00183                                    side*DX,side*DY,0,0);
00184                      }
00185                      else
00186                             drawLabel(g,s,zc,x+a/5*DX,y+a/5*DY,DX,DY,XcOffset,YcOffset);
00187               }             
00188        }
00189        
00190        public boolean canKeepClose ()
00191        {      return true;
00192        }
00193        
00194        public void setKeepClose (double x, double y)
00195        {      KeepClose=true;
00196               XcOffset=(x-X1)*DX+(y-Y1)*DY;
00197               YcOffset=(x-X1)*DY-(y-Y1)*DX;
00198        }
00199 
00200        public boolean nearto (int c, int r, ZirkelCanvas zc)
00201        {      if (!displays(zc)) return false;
00202               //compute point at c,r
00203               double x=zc.x(c),y=zc.y(r);
00204               // compute distance from x,y
00205               double d=(x-X1)*DY-(y-Y1)*DX;
00206               // scale in screen coordinates
00207               Value=Math.abs(zc.col(zc.minX()+d)-zc.col(zc.minX()));
00208               return Value<zc.selectionSize()*2;
00209        }
00210        
00211        public boolean onlynearto (int c, int r, ZirkelCanvas zc)
00212        {      return false;
00213        }
00214 
00215        public static Coordinates intersect 
00216               (PrimitiveLineObject l1, PrimitiveLineObject l2)
00217        // compute the intersection coordinates of two lines
00218        {      double det=-l1.DX*l2.DY+l1.DY*l2.DX;
00219               if (Math.abs(det)<1e-10) return null;
00220               double a=(-(l2.X1-l1.X1)*l2.DY+(l2.Y1-l1.Y1)*l2.DX)/det;
00221               return new Coordinates(l1.X1+a*l1.DX,l1.Y1+a*l1.DY);
00222        }
00223 
00224        public static Coordinates intersect
00225               (PrimitiveLineObject l, PrimitiveCircleObject c)
00226        // compute the intersection coordinates of a line with a circle
00227        {      double x=c.getX(),y=c.getY(),r=c.getR();
00228               double d=(x-l.X1)*l.DY-(y-l.Y1)*l.DX;
00229               if (Math.abs(d)>r+1e-10) return null;
00230               x-=d*l.DY; y+=d*l.DX;
00231               double h=r*r-d*d;
00232               if (h>0) h=Math.sqrt(h);
00233               else h=0;
00234               return new Coordinates(x+h*l.DX,y+h*l.DY,x-h*l.DX,y-h*l.DY);
00235        }
00236 
00237        public double getDX () { return DX; }
00238        public double getDY () { return DY; }
00239        public double getX () { return X1; }
00240        public double getY () { return Y1; }
00241 
00242        public void edit (ZirkelCanvas zc)
00243        {      ObjectEditDialog d=new LineEditDialog(zc.getFrame(),this);
00244               d.setVisible(true);
00245               zc.getConstruction().updateCircleDep(); 
00246               zc.repaint();
00247               if (d.wantsMore())
00248               {      new EditConditionals(zc.getFrame(),this);
00249                      validate();
00250               }
00251        }
00252        
00253        public String getEquation ()
00254        {      double y=DX,x=-DY;
00255               double c=y*Y1+x*X1;
00256               if (c<0)
00257               {      c=-c; x=-x; y=-y;
00258               }
00259               if (Math.abs(x)<1e-10 && y<0)
00260               {      c=-c; x=-x; y=-y;
00261               }
00262               else if  (Math.abs(y)<1e-10 && x<0)
00263               {      c=-c; x=-x; y=-y;
00264               }
00265               String s=helpDisplayValue(true,x,"x");
00266               return s+
00267                      helpDisplayValue(s.equals(""),y,"y")+"="+
00268                      ((Math.abs(c)<1e-10)?"0":helpDisplayNumber(true,c));
00269        }
00270        
00275        public boolean contains (double x, double y)
00276        {      return true;
00277        }
00278        
00279        public void printArgs (XmlWriter xml)
00280        {      if (Partial) xml.printArg("partial","true");
00281        }
00282        
00283        public double project (double x, double y)
00284        {      return (x-X1)*DX+(y-Y1)*DY;
00285        }
00286        
00287        public boolean equals (ConstructionObject o)
00288        {      if (!(o instanceof PrimitiveLineObject) || !o.valid()) return false;
00289               PrimitiveLineObject l=(PrimitiveLineObject)o;
00290               return equals(DX*l.DY-DY*l.DX,0) &&
00291                      equals((X1-l.X1)*DY-(Y1-l.Y1)*DX,0);
00292        }
00293 
00294        public PointObject getP1 ()
00295        {      return P1;
00296        }
00297        
00298        public Enumeration points ()
00299        {      return depending();
00300        }
00301        
00302        public boolean locallyLike (ConstructionObject o)
00303        {      if (!(o instanceof PrimitiveLineObject)) return false;
00304               return (equals(DX,((PrimitiveLineObject)o).DX) &&
00305                      equals(DY,((PrimitiveLineObject)o).DY)) ||
00306                             (equals(-DX,((PrimitiveLineObject)o).DX) &&
00307                      equals(-DY,((PrimitiveLineObject)o).DY));
00308        }
00309 
00310        public boolean isPartial () { return Partial; }
00311        
00312        public void setPartial (boolean partial)
00313        {      if (Partial==partial) return;
00314               Partial=partial; 
00315               if (partial)
00316               {      Dep=new PointObject[16];
00317                      NDep=0;
00318               }
00319               else Dep=null;
00320        }
00321 
00322        public void addDep (PointObject p)
00323        {      if (!Partial || Dep==null || NDep>=Dep.length) return;
00324               Dep[NDep++]=p;
00325        } 
00326        
00327        public void clearCircleDep ()
00328        {      NDep=0;
00329        }
00330 
00331        public void project (PointObject P) 
00332        {      double h=project(P.getX(),P.getY());
00333               P.setXY(getX()+h*getDX(),getY()+h*getDY());
00334               P.setA(h);
00335        }
00336 
00337        public void project(PointObject P, double alpha)
00338        {      P.setXY(getX()+alpha*getDX(),getY()+alpha*getDY());
00339        }
00340 
00341        public boolean canInteresectWith (ConstructionObject o) 
00342        {      return true;
00343        }
00344 }