Back to index

wims  3.65+svn20090927
AreaObject.java
Go to the documentation of this file.
00001 package rene.zirkel.objects;
00002 
00003 // file: LineObject.java
00004 
00005 import java.awt.*;
00006 import java.util.*;
00007 
00008 import rene.gui.*;
00009 import rene.util.xml.*;
00010 import rene.zirkel.Zirkel;
00011 import rene.zirkel.ZirkelCanvas;
00012 import rene.zirkel.construction.Construction;
00013 import rene.zirkel.construction.ConstructionException;
00014 import rene.zirkel.construction.Count;
00015 import rene.zirkel.dialogs.EditConditionals;
00016 import rene.zirkel.dialogs.ObjectEditDialog;
00017 import rene.zirkel.expression.InvalidException;
00018 import rene.zirkel.graphics.MyGraphics;
00019 import rene.zirkel.graphics.MyGraphics13;
00020 
00021 class AreaObjectDialog extends ObjectEditDialog
00022 {      
00023        public AreaObjectDialog (Frame f, String title, ConstructionObject o)
00024        {      super(f, title, o);
00025        }
00026        public void addFirst (Panel P)
00027        {      AreaObject AO=(AreaObject)O;
00028               
00029               MyTextField A=new MyTextField(""+AO.area(),30);
00030               P.add(new MyLabel(Zirkel.name("edit.area.area"))); P.add(A);
00031               A.setEditable(false);
00032        }
00033        
00034        
00035 }
00036 
00037 public class AreaObject extends ConstructionObject
00038        implements InsideObject, PointonObject, MoveableObject
00039 {      static Count N=new Count();
00040        double x[]=new double[3],y[]=new double[3];
00041        double R,X,Y,A;
00042        Vector V;
00043 
00044        public AreaObject (Construction c, Vector v)
00045        {      super(c);
00046               V=v;
00047               validate();
00048               updateText();
00049               Global.getParameter("unit.area","");
00050        }
00051 
00052        public String getTag () { return "Polygon"; }
00053 
00054        public void updateText()
00055        {      String Text=Zirkel.name("text.area");
00056               Enumeration en=V.elements();
00057               boolean first=true;
00058               while (en.hasMoreElements())
00059               {      PointObject p=(PointObject)en.nextElement();
00060                      if (!first) Text=Text+", ";
00061                      else Text=Text+" ";
00062                      first=false;
00063                      Text=Text+p.getName();
00064               }
00065               setText(Text);
00066        }
00067        
00068        public void validate ()
00069        {      Enumeration e=V.elements();
00070               while (e.hasMoreElements())
00071               {      if (!((ConstructionObject)e.nextElement()).valid())
00072                      {      Valid=false; return;
00073                      }
00074               }
00075               if (V.size()<3)
00076               {      Valid=false;
00077                      return;
00078               }
00079               Enumeration en=V.elements();
00080               double x=0,y=0;
00081               while (en.hasMoreElements())
00082               {      PointObject p=(PointObject)en.nextElement();
00083                      x+=p.getX();
00084                      y+=p.getY();
00085               }
00086               X=x/V.size(); Y=y/V.size();
00087               A=area();
00088               Valid=true;
00089        }
00090 
00091        public void edit (ZirkelCanvas zc)
00092        {      ObjectEditDialog d=new AreaObjectDialog(zc.getFrame(),Zirkel.name("edit.area.title"),
00093                      this);
00094               d.setVisible(true);
00095               Global.setParameter("unit.area",Unit);
00096               zc.repaint();
00097               if (d.wantsMore())
00098               {      new EditConditionals(zc.getFrame(),this);
00099                      validate();
00100               }
00101        }
00102        
00103        public void paint (MyGraphics g, ZirkelCanvas zc)
00104        {      if (!Valid || mustHide(zc)) return;
00105               int n=V.size();
00106               if (x.length!=n)
00107               {      x=new double[n]; y=new double[n];
00108               }
00109               if (visible(zc))
00110               {      Enumeration e=V.elements();
00111                      int i=0;
00112                      while (e.hasMoreElements())
00113                      {      PointObject p=(PointObject)e.nextElement();
00114                             x[i]=zc.col(p.getX());
00115                             y[i]=zc.row(p.getY());
00116                             if (i>0)
00117                             {      if (isStrongSelected() && g instanceof MyGraphics13)
00118                                    {      ((MyGraphics13)g).drawMarkerLine(x[i-1],y[i-1],x[i],y[i]);
00119                                    }
00120                             }
00121                             i++;
00122                      }
00123                      if (i>1)
00124                      {      if (isStrongSelected() && g instanceof MyGraphics13)
00125                             {      ((MyGraphics13)g).drawMarkerLine(x[i-1],y[i-1],x[0],y[0]);
00126                             }
00127                      }      
00128                      g.fillPolygon(x,y,n,Indicated||Selected||getColorType()!=THIN,
00129                             getColorType()!=THICK,this);
00130               }
00131               String s=getDisplayText();
00132               if (!s.equals(""))
00133               {      if (getColorIndex()==0 && getColorType()==THICK)
00134                             g.setColor(Color.gray.brighter());
00135                      else g.setColor(Color.black);
00136                      DisplaysText=true;
00137                      TX1=zc.col(X+XcOffset);
00138                      TY1=zc.row(Y+YcOffset);
00139                      setFont(g);
00140                      drawLabel(g,s);
00141               }             
00142        }
00143 
00144        public String getDisplayValue ()
00145        {      return ""+round(Math.abs(A),ZirkelCanvas.LengthsFactor);
00146        }
00147        
00148        public void printArgs (XmlWriter xml)
00149        {      Enumeration e=V.elements();
00150               int n=1;
00151               while (e.hasMoreElements())
00152               {      ConstructionObject o=(ConstructionObject)e.nextElement();
00153                      xml.printArg("point"+n,o.getName());
00154                      n++;
00155               }
00156               super.printArgs(xml);
00157        }
00158 
00159        public Enumeration depending ()
00160        {      super.depending();
00161               Enumeration e=V.elements();
00162               while (e.hasMoreElements())
00163               {      ConstructionObject o=(ConstructionObject)e.nextElement();
00164                      DL.add(o);
00165               }
00166               return DL.elements();
00167        }
00168 
00169        public void translate ()
00170        {      Enumeration e=V.elements();
00171               Vector w=new Vector();
00172               while (e.hasMoreElements())
00173               {      ConstructionObject o=(ConstructionObject)e.nextElement();
00174                      w.addElement(o.getTranslation());
00175               }
00176               V=w;
00177        }
00178        
00179        public boolean nearto (int c, int r, ZirkelCanvas zc)
00180        {      if (!displays(zc)) return false;
00181               return contains(zc.x(c),zc.y(r));
00182        }
00183        
00184        public boolean nearto (int c, int r, boolean ignorefill, ZirkelCanvas zc)
00185        {      if (!displays(zc)) return false;
00186               if (contains(zc.x(c),zc.y(r),zc.dx(zc.selectionSize())))
00187               {      if (ignorefill) return OnBoundary;
00188                      else return true; 
00189               }
00190               return false;
00191        }
00192        
00193        boolean OnBoundary;
00194        
00195        public boolean contains (double x, double y, double eps)
00196        {      if (!Valid) return false;
00197               OnBoundary=false;
00198               PointObject First=(PointObject)V.elementAt(0);
00199               PointObject P=First;
00200               if (Math.max(Math.abs(P.getX()-x),Math.abs(P.getY()-y))<eps)
00201               {      OnBoundary=true;
00202                      return true;
00203               }
00204               Enumeration e=V.elements();
00205               double a=Math.atan2(P.getX()-x,P.getY()-y);
00206               double sum=0;
00207               PointObject Q;
00208               while (e.hasMoreElements())
00209               {      Q=(PointObject)e.nextElement();
00210                      if (Math.max(Math.abs(Q.getX()-x),Math.abs(Q.getY()-y))<eps)
00211                      {      OnBoundary=true;
00212                             return true;
00213                      }
00214                      double b=Math.atan2(Q.getX()-x,Q.getY()-y);
00215                      double d=b-a;
00216                      if (d>Math.PI) d=d-2*Math.PI;
00217                      else if (d<-Math.PI) d=d+2*Math.PI;
00218                      if (Math.abs(Math.abs(d)-Math.PI)<0.1)
00219                      {      OnBoundary=true;
00220                             return true;
00221                      }
00222                      a=b; P=Q;
00223                      sum+=d;
00224               }
00225               Q=First;
00226               double b=Math.atan2(Q.getX()-x,Q.getY()-y);
00227               double d=b-a;
00228               if (d>Math.PI) d=d-2*Math.PI;
00229               else if (d<-Math.PI) d=d+2*Math.PI;
00230               if (Math.abs(Math.abs(d)-Math.PI)<0.1)
00231               {      OnBoundary=true;
00232                      return true;
00233               }
00234               sum+=d;
00235               return Math.abs(sum)>=Math.PI/2;
00236        }
00237        
00238        public boolean contains (double x, double y)
00239        {      return contains(x,y,1e-4);
00240        }
00241 
00242        public double area ()
00243        {      if (!Valid) return -1;
00244               PointObject First=(PointObject)V.elementAt(0);
00245               PointObject P=First;
00246               Enumeration e=V.elements();
00247               double sum=0;
00248               PointObject Q;
00249               while (e.hasMoreElements())
00250               {      Q=(PointObject)e.nextElement();
00251                      sum+=(Q.getX()-X)*(P.getY()-Y)-(Q.getY()-Y)*(P.getX()-X);
00252                      P=Q;
00253               }
00254               Q=First;
00255               sum+=(Q.getX()-X)*(P.getY()-Y)-(Q.getY()-Y)*(P.getX()-X);
00256               return sum/2;
00257        }
00258 
00259        public boolean equals (ConstructionObject o)
00260        {      if (!(o instanceof AreaObject) || !o.valid()) return false;
00261               AreaObject a=(AreaObject)o;
00262               int n=V.size(),m=a.V.size();
00263               PointObject p[]=new PointObject[n];
00264               V.copyInto(p);
00265               PointObject pa[]=new PointObject[m];
00266               a.V.copyInto(pa);
00267               double x0=0,y0=0;
00268               for (int i=0; i<m; i++)
00269               {      boolean r=true;
00270                      int j=0,kj=0;
00271                      while (true)
00272                      {      int k=i+kj;
00273                             if (k>=m) k-=m;
00274                             if (!p[j].equals(pa[k]))
00275                             {      if (j==0 || !between(x0,y0,p[j].getX(),p[j].getY(),
00276                                           pa[k].getX(),pa[k].getY()))
00277                                    {      r=false; break;
00278                                    }
00279                             }
00280                             else
00281                             {      x0=p[j].getX(); y0=p[j].getY();
00282                                    j++;
00283                             }
00284                             kj++;
00285                             if (j>=n || kj>=m) break;
00286                      }
00287                      if (r && kj>=m) return true;
00288               }
00289               for (int i=0; i<m; i++)
00290               {      boolean r=true;
00291                      int j=0,kj=0;
00292                      while (true)
00293                      {      int k=i+kj;
00294                             if (k>=m) k-=m;
00295                             if (!p[n-j-1].equals(pa[k]))
00296                             {      if (j==0 || !between(x0,y0,p[n-j-1].getX(),p[n-j-1].getY(),
00297                                           pa[k].getX(),pa[k].getY()))
00298                                    {      r=false; break;
00299                                    }
00300                             }
00301                             else
00302                             {      x0=p[n-j-1].getX(); y0=p[n-j-1].getY();
00303                                    j++;
00304                             }
00305                             kj++;
00306                             if (j>=n || kj>=m) break;
00307                      }
00308                      if (r && kj>=m) return true;
00309               }
00310               return false;
00311        }
00312 
00313        public boolean between (double x0, double y0, double x1, double y1, 
00314               double x, double y)
00315        {      double lambda;
00316               if (Math.abs(x1-x0)>Math.abs(y1-y0))
00317                      lambda=(x-x0)/(x1-x0);
00318               else
00319                      lambda=(y-y0)/(y1-y0);
00320               return
00321                      Math.abs(x0+lambda*(x1-x0)-x)<1e-10 &&
00322                      Math.abs(y0+lambda*(y1-y0)-y)<1e-10;
00323        }
00324 
00325        public double getValue ()
00326               throws ConstructionException
00327        {      if (!Valid) throw new InvalidException("exception.invalid");
00328               else return A;
00329        }      
00330        
00331        public boolean maybeTransparent ()
00332        {      return true;
00333        }
00334        
00335        public boolean isFilled ()
00336        {      return true;
00337        }
00338 
00339        public boolean onlynearto (int x, int y, ZirkelCanvas zc)
00340        {      return false;
00341        }
00342 
00343        public void project (PointObject P) 
00344        {      double x=P.getX(),y=P.getY();
00345               Enumeration e=V.elements();
00346               PointObject p=(PointObject)e.nextElement();
00347               double x1=p.getX(),y1=p.getY();
00348               double xstart=x1,ystart=y1;
00349               int count=0;
00350               double xmin=x1,ymin=y1,dmin=1e20,hmin=0;
00351               while (e.hasMoreElements())
00352               {      p=(PointObject)e.nextElement();
00353                      double x2=p.getX(),y2=p.getY();
00354                      double dx=x2-x1,dy=y2-y1;
00355                      double r=dx*dx+dy*dy;
00356                      if (r>1e-5)
00357                      {      double h=dx*(x-x1)/r+dy*(y-y1)/r;
00358                             if (h>1) h=1;
00359                             else if (h<0) h=0;
00360                             double xh=x1+h*dx,yh=y1+h*dy;
00361                             double dist=Math.sqrt((x-xh)*(x-xh)+(y-yh)*(y-yh));
00362                             if (dist<dmin)
00363                             {      dmin=dist;
00364                                    xmin=xh; ymin=yh;
00365                                    hmin=count+h;
00366                             }
00367                      }
00368                      count++;
00369                      x1=x2; y1=y2;
00370               }
00371               double x2=xstart,y2=ystart;
00372               double dx=x2-x1,dy=y2-y1;
00373               double r=dx*dx+dy*dy;
00374               if (r>1e-5)
00375               {      double h=dx*(x-x1)/r+dy*(y-y1)/r;
00376                      if (h>1) h=1;
00377                      else if (h<0) h=0;
00378                      double xh=x1+h*dx,yh=y1+h*dy;
00379                      double dist=Math.sqrt((x-xh)*(x-xh)+(y-yh)*(y-yh));
00380                      if (dist<dmin)
00381                      {      dmin=dist;
00382                             xmin=xh; ymin=yh;
00383                             hmin=count+h;
00384                      }
00385               }
00386               P.move(xmin,ymin);
00387               P.setA(hmin);
00388        }
00389 
00390        public void project (PointObject P, double alpha) 
00391        {      int i=(int)Math.floor(alpha);
00392               double h=alpha-i;
00393               if (i<0 || i>=V.size())
00394               {      project(P); return;
00395               }
00396               PointObject P1=(PointObject)V.elementAt(i);
00397               PointObject P2;
00398               if (i==V.size()-1) P2=(PointObject)V.elementAt(0);
00399               else P2=(PointObject)V.elementAt(i+1);
00400               P.setXY(P1.getX()+h*(P2.getX()-P1.getX()),P1.getY()+h*(P2.getY()-P1.getY()));
00401        }
00402        
00403        public double containsInside(PointObject P) 
00404        {      boolean inside=contains(P.getX(),P.getY());
00405               if (inside && OnBoundary) return 0.5;
00406               else if (inside) return 1;
00407               return 0;
00408        }
00409 
00410        public boolean keepInside (PointObject P) 
00411        {      if (containsInside(P)>0) return true;
00412               project(P);
00413               return false;
00414        }
00415 
00416        public void dragTo (double x, double y) 
00417        {      Enumeration e=V.elements();
00418               int i=0;
00419               while (e.hasMoreElements())
00420               {      PointObject p=(PointObject)e.nextElement();
00421                      p.move(xd[i]+(x-x1),yd[i]+(y-y1));
00422                      i++;
00423               }
00424        }
00425 
00426        public void move (double x, double y) 
00427        {
00428        }
00429 
00430        public boolean moveable () 
00431        {      if (V==null) return false;
00432               Enumeration e=V.elements();
00433               while (e.hasMoreElements())
00434               {      if (!((PointObject)e.nextElement()).moveable())
00435                             return false;
00436               }
00437               return true;
00438        }
00439        
00440        double xd[],yd[],x1,y1;
00441 
00442        public void startDrag (double x, double y) 
00443        {      if (xd==null || xd.length!=V.size())
00444               {      xd=new double[V.size()];
00445                      yd=new double[V.size()];
00446               }
00447               Enumeration e=V.elements();
00448               int i=0;
00449               while (e.hasMoreElements())
00450               {      PointObject p=(PointObject)e.nextElement();
00451                      xd[i]=p.getX(); yd[i]=p.getY();
00452                      i++;
00453               }
00454               x1=x; y1=y;
00455        }
00456 
00457        public void snap (ZirkelCanvas zc)
00458        {      if (moveable())
00459               {      Enumeration e=V.elements();
00460                      while (e.hasMoreElements())
00461                      {      PointObject p=(PointObject)e.nextElement();
00462                             p.snap(zc);
00463                      }
00464               }
00465        }
00466 
00467        public boolean canInteresectWith (ConstructionObject o) 
00468        {      if (o instanceof PointonObject)
00469               {      ConstructionObject line=(ConstructionObject)o;
00470                      Enumeration e=V.elements();
00471                      {      PointObject P=(PointObject)e.nextElement();
00472                             if (line.contains(P)) return false;
00473                      }
00474               }
00475               return true;
00476        }
00477 
00478 }