Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/xerox/VTM/glyphs/VEllipse.java


1   /*   FILE: VEllipse.java
2    *   DATE OF CREATION:   Oct 14 2001
3    *   AUTHOR :            Emmanuel Pietriga (emmanuel.pietriga@xrce.xerox.com)
4    *   MODIF:              Thu Jul 10 16:38:52 2003 by Emmanuel Pietriga (emmanuel@w3.org, emmanuel@claribole.net)
5    *   Copyright (c) Xerox Corporation, XRCE/Contextual Computing, 2002. All Rights Reserved
6    *
7    * This library is free software; you can redistribute it and/or
8    * modify it under the terms of the GNU Lesser General Public
9    * License as published by the Free Software Foundation; either
10   * version 2.1 of the License, or (at your option) any later version.
11   * 
12   * This library is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   * Lesser General Public License for more details.
16   *
17   * For full terms see the file COPYING.
18   */
19  
20  package com.xerox.VTM.glyphs;
21  
22  import java.lang.Math;
23  import java.awt.Color;
24  import java.awt.Graphics2D;
25  import java.awt.Font;
26  import java.awt.Shape;
27  import java.awt.Stroke;
28  import java.awt.geom.*;
29  import java.util.Vector;
30  import com.xerox.VTM.engine.*;
31  
32    /**
33     * Ellipse - cannot be reoriented
34     * @author Emmanuel Pietriga
35     */
36  
37  public class VEllipse extends Glyph implements RectangularShape,Cloneable {
38  
39      /**half width and height in virtual space*/
40      long vw,vh;
41      /**aspect ratio (width divided by height)*/
42      float ar;
43  
44      /**array of projected coordinates - index of camera in virtual space is equal to index of projected coords in this array*/
45      ProjEllipse[] pc;
46  
47      /**
48       *creates a new default white ellipse
49       */
50      public VEllipse(){
51    vx=0;
52    vy=0;
53    vz=0;
54    vw=10;
55    vh=10;
56    setColor(Color.white);
57    setBorderColor(Color.black);
58    computeSize();
59      }
60  
61      /**
62       *@param x coordinate in virtual space
63       *@param y coordinate in virtual space
64       *@param z altitude in virtual space
65       *@param sx horizontal axis radius in virtual space
66       *@param sy vertical axis radius in virtual space
67       *@param c main shape's color
68       */
69      public VEllipse(long x,long y,float z,long sx,long sy,Color c){
70    vx=x;
71    vy=y;
72    vz=z;
73    vw=sx;
74    vh=sy;
75    orient=0;
76    setColor(c);
77    setBorderColor(Color.black);
78    computeSize();
79      }
80  
81      /**called when glyph is created in order to create the initial set of projected coordinates wrt the number of cameras in the space
82       *@param nbCam current number of cameras in the virtual space
83       */
84      public void initCams(int nbCam){
85    pc=new ProjEllipse[nbCam];
86    for (int i=0;i<nbCam;i++){
87        pc[i]=new ProjEllipse();
88    }
89      }
90  
91      /**used internally to create new projected coordinates to use with the new camera
92       *@param verifIndex camera index, just to be sure that the number of projected coordinates is consistent with the number of cameras
93       */
94      public void addCamera(int verifIndex){
95    if (pc!=null){
96        if (verifIndex==pc.length){
97      ProjEllipse[] ta=pc;
98      pc=new ProjEllipse[ta.length+1];
99      for (int i=0;i<ta.length;i++){
100         pc[i]=ta[i];
101     }
102     pc[pc.length-1]=new ProjEllipse();
103       }
104       else {System.err.println("VEllipse:Error while adding camera "+verifIndex);}
105   }
106   else {
107       if (verifIndex==0){
108     pc=new ProjEllipse[1];
109     pc[0]=new ProjEllipse();
110       }
111       else {System.err.println("VEllipse:Error while adding camera "+verifIndex);}
112   }
113     }
114 
115     /**if a camera is removed from the virtual space, we should delete the corresponding projected coordinates, but do not modify the array it self because we do not want to change other cameras' index - just point to null*/
116     public void removeCamera(int index){
117   pc[index]=null;
118     }
119 
120     /**reset prevMouseIn for projected coordinates nb i*/
121     public void resetMouseIn(int i){
122   if (pc[i]!=null){pc[i].prevMouseIn=false;}
123     }
124 
125     /**orientation is disabled*/
126     public float getOrient(){return 0;}
127 
128     /**orientation is disabled*/
129     public void orientTo(float angle){}
130 
131     /**orientation is disabled*/
132 //     public void orientToNS(float angle){}
133 
134     /**size is bounding circle radius*/
135     void computeSize(){
136   size=Math.max(vw,vh);
137   ar=(float)vw/(float)vh;
138     }
139 
140     /**size is disabled*/
141     public float getSize(){return size;}
142 
143     /**size is disabled*/
144     public void sizeTo(float radius){
145   size=radius;
146   if (vw>=vh){vw=(long)size;vh=(long)(vw/ar);}
147   else {vh=(long)size;vw=(long)(vh*ar);}
148   try{vsm.repaintNow();}catch(NullPointerException e){/*System.err.println("VSM null in Glyph "+e);*/}
149 //   vsm.constMgr.suggestAValue(this.ID,"sz",size);
150     }
151 
152     /**set absolute half width*/
153     public void setWidth(long w){ 
154   vw=w;
155   computeSize();
156   try{vsm.repaintNow();}catch(NullPointerException e){/*System.err.println("VSM null in Glyph "+e);*/}
157 //   vsm.constMgr.suggestAValue(this.ID,"sz",size);
158     }
159 
160     /**set absolute half height*/
161     public void setHeight(long h){
162   vh=h;
163   computeSize();
164   try{vsm.repaintNow();}catch(NullPointerException e){/*System.err.println("VSM null in Glyph "+e);*/}
165 //   vsm.constMgr.suggestAValue(this.ID,"sz",size);
166     }
167 
168     /**get width*/
169     public long getWidth(){return vw;}
170 
171     /**get height*/
172     public long getHeight(){return vh;}
173 
174     /**size is disabled*/
175 //     public void sizeToNS(float radius){
176 //   size=radius;
177 //   if (vw>=vh){vw=(long)size;vh=(long)(vw/ar);}
178 //   else {vh=(long)size;vw=(long)(vh*ar);}
179 //     }
180 
181     /**size is disabled*/
182     public void reSize(float factor){
183   size*=factor;
184   if (vw>=vh){vw=(long)size;vh=(long)(vw/ar);}
185   else {vh=(long)size;vw=(long)(vh*ar);}
186   try{vsm.repaintNow();}catch(NullPointerException e){/*System.err.println("VSM null in Glyph "+e);*/}
187 //   vsm.constMgr.suggestAValue(this.ID,"sz",size);
188     }
189 
190     /**used to find out if glyph completely fills the view (in which case it is not necessary to repaint objects at a lower altitude)*/
191     public boolean fillsView(long w,long h,int camIndex){//would be too complex: just say no
192   return false;
193     }
194 
195     /**detects whether the given point is inside this glyph or not 
196      *@param x EXPECTS PROJECTED JPanel COORDINATE
197      *@param y EXPECTS PROJECTED JPanel COORDINATE
198      */
199     public boolean coordInside(int x,int y,int camIndex){
200   if (pc[camIndex].ellipse.contains(x,y)){return true;}
201   else {return false;}
202     }
203 
204     /**returns 1 if mouse has entered the glyph, -1 if it has exited the glyph, 0 if nothing has changed (meaning it was already inside or outside it)*/
205     public int mouseInOut(int x,int y,int camIndex){
206   if (coordInside(x,y,camIndex)){//if the mouse is inside the glyph
207       if (!pc[camIndex].prevMouseIn){//if it was not inside it last time, mouse has entered the glyph
208     pc[camIndex].prevMouseIn=true;
209     return 1;
210       }
211       else {return 0;}  //if it was inside last time, nothing has changed
212   }
213   else{//if the mouse is not inside the glyph
214       if (pc[camIndex].prevMouseIn){//if it was inside it last time, mouse has exited the glyph
215     pc[camIndex].prevMouseIn=false;
216     return -1;
217       }
218       else {return 0;}  //if it was not inside last time, nothing has changed
219   }
220     }
221 
222     /**project shape in camera coord sys prior to actual painting*/
223     public void project(Camera c,ViewPanel v){
224   int i=c.getIndex();
225   coef=(float)(c.focal/(c.focal+c.altitude));
226   //find coordinates of object's geom center wrt to camera center and project
227   pc[i].cx=Math.round((vx-c.posx)*coef);
228   pc[i].cy=Math.round((vy-c.posy)*coef);
229   //translate in JPanel coords
230   pc[i].cx=(v.getSize().width/2)+pc[i].cx;
231   pc[i].cy=(v.getSize().height/2)-pc[i].cy;
232   pc[i].cvw=vw*coef;
233   pc[i].cvh=vh*coef;
234   pc[i].ellipse.setFrame(pc[i].cx-vw*coef,pc[i].cy-vh*coef,2*pc[i].cvw,2*pc[i].cvh);
235     }
236 
237     /**draw text associated with this glyph
238      *@param i camera index in the virtual space
239      */
240     void textDraw(Graphics2D g,int i){
241   if ((fontSizePolicy>=0) && (text!=null)) {     //if appli wants text drawn and if there is a text for this glyph
242       if (!text.equals("")){
243     //g.setColor(this.color);
244     textWidth=(int)g.getFontMetrics().getStringBounds(text,g).getWidth();  //get width of this text : draw if conditions are met
245     if ((fontSizePolicy==1) || ((fontSizePolicy==0) && (textWidth<2*pc[i].cvw))) {
246         if (textPos==1){  
247       //textHeight=(int)g.getFontMetrics().getStringBounds(text,g).getHeight();
248       g.drawString(text,pc[i].cx-textWidth/2,pc[i].cy-pc[i].cvh-4);
249         }
250         else if (textPos==-1){  
251       textHeight=(int)g.getFontMetrics().getStringBounds(text,g).getHeight();
252       g.drawString(text,pc[i].cx-textWidth/2,pc[i].cy+pc[i].cvh+textHeight);
253         }
254         else {g.drawString(text,pc[i].cx-textWidth/2,pc[i].cy);}
255     }
256     else if (fontSizePolicy==2) {  //modify font size to make string fit in glyph   THIS OPTION IS RATHER TIME CONSUMING
257         Font tf=new Font(g.getFont().getName(),g.getFont().getStyle(),g.getFont().getSize());
258         int s=1;
259         while (textWidth>2*pc[i].cvw){
260       s=g.getFont().getSize()-2; if (s<0){s=0;break;}
261       g.setFont(new Font(tf.getName(),tf.getStyle(),s));
262       textWidth=(int)g.getFontMetrics().getStringBounds(text,g).getWidth();
263         }
264         if (s>0) {
265       if (textPos==1){
266           //textHeight=(int)g.getFontMetrics().getStringBounds(text,g).getHeight();
267           g.drawString(text,pc[i].cx-textWidth/2,pc[i].cy-pc[i].cvh-4);
268       }
269       else if (textPos==-1){
270           textHeight=(int)g.getFontMetrics().getStringBounds(text,g).getHeight();
271           g.drawString(text,pc[i].cx-textWidth/2,pc[i].cy+pc[i].cvh+textHeight);
272       }
273       else {g.drawString(text,pc[i].cx-textWidth/2,pc[i].cy);}
274         }
275         g.setFont(tf);
276     }
277       }
278   }
279     }
280 
281     /**draw glyph 
282      *@param i camera index in the virtual space
283      */
284     public void draw(Graphics2D g,int vW,int vH,int i,Stroke stdS,AffineTransform stdT){
285   if ((pc[i].ellipse.getBounds().width>2) && (pc[i].ellipse.getBounds().height>2)){
286       if (filled){
287     g.setColor(this.color);
288     g.fill(pc[i].ellipse);
289       }
290       g.setColor(borderColor);
291       if (paintBorder){
292     if (stroke!=null){
293         g.setStroke(stroke);
294         g.draw(pc[i].ellipse);
295         g.setStroke(stdS);
296     }
297     else {
298         g.draw(pc[i].ellipse);
299     }
300       }   
301       this.textDraw(g,i);
302   }
303   else g.fillRect(pc[i].cx,pc[i].cy,1,1);
304     }
305 
306     /**returns a clone of this object (only basic information is cloned for now: shape, orientation, position, size)*/
307     public Object clone(){
308   VEllipse res=new VEllipse(vx,vy,0,vw,vh,color);
309   res.borderColor=this.borderColor;
310   res.selectedColor=this.selectedColor;
311   res.mouseInsideColor=this.mouseInsideColor;
312   res.bColor=this.bColor;
313   return res;
314     }
315 
316 }