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

Quick Search    Search Deep

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


1   /*   FILE: VQdCurve.java
2    *   DATE OF CREATION:   Oct 02 2001
3    *   AUTHOR :            Emmanuel Pietriga (emmanuel.pietriga@xrce.xerox.com)
4    *   MODIF:              Thu Jul 10 16:55:16 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.awt.Color;
23  import java.awt.Font;
24  import java.awt.Graphics2D;
25  import java.awt.Polygon;
26  import java.awt.Stroke;
27  import java.awt.geom.*;
28  import java.awt.geom.AffineTransform;
29  import java.lang.Math;
30  import java.util.Vector;
31  import com.xerox.VTM.engine.*;
32  
33  /**
34   * Quadratic Curve -  can be reoriented -  CANNOT DETECT ENTRY/EXIT in curves, even when filled (they look as, but are not, closed shapes) <br> a quadratic curve is a curved segment that has two endpoints and one control point. The control point determines the shape of the curve by controlling both of the endpoint tangent vectors <br> for this particular glyph, vx and vy correspond to the center of the imaginary segment linking the curve's start and end points <br> the coordinates of the control point are expressed w.r.t this point in polar coordinates (orient=0 on segment linking start and end points, meaning that if orient=0, start control and end points are aligned) 
35   * @author Emmanuel Pietriga
36   **/
37  
38  public class VQdCurve extends Glyph implements Cloneable {
39  
40      /**size (distance between start and end point)*/
41      long vs;
42  
43      /**control point, polar coordinates - origin is vx,vy - orient=0 on segment linking start and end points*/
44      long vrad;
45      float ang;
46  
47      /**array of projected coordinates - index of camera in virtual space is equal to index of projected coords in this array*/
48      ProjQdCurve[] pc;
49  
50      /**
51       *@param x coordinate in virtual space
52       *@param y coordinate in virtual space
53       *@param z altitude
54       *@param s size (width=height) in virtual space
55       *@param c fill color
56       *@param or orientation
57       *@param ctrlDist1 distance of control point (polar coords origin=(x,y) provided in this constructor)
58       *@param or1 orientation of control point (polar coords origin=(x,y) provided in this constructor)
59       */
60      public VQdCurve(long x,long y,float z,long s,Color c,float or,long ctrlDist1,float or1){
61    vx=x;
62    vy=y;
63    vz=z;
64    vs=s;
65    sensit=false;
66    orient=or;
67    vrad=ctrlDist1;
68    ang=or1;
69    computeSize();
70    filled=false;
71    setColor(c);
72    setBorderColor(bColor);
73      }
74  
75      /**set position of control point (polar coords w.r.t center of segment linking start and end points)*/
76      public void setCtrlPoint(long d,float o){
77    vrad=d;
78  //   if (o>2*Math.PI){ang=o%2*(float)Math.PI;}
79  //   else {ang=o;}
80    ang=o;
81    try{vsm.repaintNow();}catch(NullPointerException e){/*System.err.println("VSM null in Glyph "+e);*/}
82      }
83  
84      /**get distance from center of segment linking start and end points to control point (polar coords)*/
85      public long getCtrlPointRadius(){return vrad;}
86  
87      /**get orientation of control point (polar coords)*/
88      public float getCtrlPointAngle(){return ang;}
89  
90      /**called when glyph is created in order to create the initial set of projected coordinates wrt the number of cameras in the space
91       *@param nbCam current number of cameras in the virtual space
92       */
93      public void initCams(int nbCam){
94    pc=new ProjQdCurve[nbCam];
95    for (int i=0;i<nbCam;i++){
96        pc[i]=new ProjQdCurve();
97    }
98      }
99  
100     /**used internally to create new projected coordinates to use with the new camera
101      *@param verifIndex camera index, just to be sure that the number of projected coordinates is consistent with the number of cameras
102      */
103     public void addCamera(int verifIndex){
104   if (pc!=null){
105       if (verifIndex==pc.length){
106     ProjQdCurve[] ta=pc;
107     pc=new ProjQdCurve[ta.length+1];
108     for (int i=0;i<ta.length;i++){
109         pc[i]=ta[i];
110     }
111     pc[pc.length-1]=new ProjQdCurve();
112       }
113       else {System.err.println("VQdCurve:Error while adding camera "+verifIndex);}
114   }
115   else {
116       if (verifIndex==0){
117     pc=new ProjQdCurve[1];
118     pc[0]=new ProjQdCurve();
119       }
120       else {System.err.println("VQdCurve:Error while adding camera "+verifIndex);}
121   }
122     }
123 
124     /**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*/
125     public void removeCamera(int index){
126   pc[index]=null;
127     }
128 
129     /**reset prevMouseIn for projected coordinates nb i*/
130     public void resetMouseIn(int i){
131   if (pc[i]!=null){pc[i].prevMouseIn=false;}
132     }
133 
134     /**get orientation*/
135     public float getOrient(){return orient;}
136 
137     /**set orientation (absolute)*/
138     public void orientTo(float angle){
139   orient=angle;
140   try{vsm.repaintNow();}catch(NullPointerException e){/*System.err.println("VSM null in Glyph "+e);*/}
141 //   vsm.constMgr.suggestAValue(this.ID,"or",orient);
142   //computeOrientCoords();
143     }
144 
145     /**set orientation (absolute)*/
146 //     public void orientToNS(float angle){
147 //   orient=angle;
148 //   //computeOrientCoords();
149 //     }
150 
151     /**get size (bounding circle radius)*/
152     public float getSize(){return size;}
153 
154     /**compute curve from VTM object model*/
155     void computeSize(){
156   size=(float)vs;
157     }
158 
159     /**set absolute size by setting bounding circle radius*/
160     public void sizeTo(float radius){
161   vrad=Math.round(vrad*radius/size);
162   size=radius;
163   vs=Math.round(size);
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     /**set absolute size by setting bounding circle radius*/
169 //     public void sizeToNS(float radius){
170 //   vrad=Math.round(vrad*radius/size);
171 //   size=radius;
172 //   vs=Math.round(size);
173 //     }
174 
175     /**multiply bounding circle radius by factor*/
176     public void reSize(float factor){
177   size*=factor;
178   vs=(long)Math.round(size);
179   vrad=Math.round(vrad*factor);
180   try{vsm.repaintNow();}catch(NullPointerException e){/*System.err.println("VSM null in Glyph "+e);*/}
181 //   vsm.constMgr.suggestAValue(this.ID,"sz",size);
182     }
183 
184     /**used to find out if glyph completely fills the view (in which case it is not necessary to repaint objects at a lower altitude)*/
185     public boolean fillsView(long w,long h,int camIndex){
186   return false;
187     }
188 
189     /**detects whether the given point is inside this glyph or not 
190      *@param x EXPECTS PROJECTED JPanel COORDINATE
191      *@param y EXPECTS PROJECTED JPanel COORDINATE
192      */
193     public boolean coordInside(int x,int y,int camIndex){
194   return false;
195     }
196 
197     /**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)*/
198     public int mouseInOut(int x,int y,int camIndex){
199   return 0;
200     }
201 
202     /**project shape in camera coord sys prior to actual painting*/
203     public void project(Camera c,ViewPanel v){
204   int i=c.getIndex();
205   coef=(float)(c.focal/(c.focal+c.altitude));
206   //find coordinates of object's geom center wrt to camera center and project
207   pc[i].cx=Math.round((vx-c.posx)*coef);
208   pc[i].cy=Math.round((vy-c.posy)*coef);
209   //translate in JPanel coords
210   pc[i].cx=(v.getSize().width/2)+pc[i].cx;
211   pc[i].cy=(v.getSize().height/2)-pc[i].cy;
212   //project height and construct curve
213   pc[i].cs=Math.round(vs*coef);
214   if (pc[i].cs>1){
215       pc[i].start.setLocation(pc[i].cx+pc[i].cs*Math.cos(orient),pc[i].cy+pc[i].cs*Math.sin(orient));
216       pc[i].end.setLocation(pc[i].cx-pc[i].cs*Math.cos(orient),pc[i].cy-pc[i].cs*Math.sin(orient));
217       pc[i].ctrl.setLocation(pc[i].cx+(int)Math.round(coef*vrad*Math.cos(orient-ang)),pc[i].cy+(int)Math.round(coef*vrad*Math.sin(orient-ang)));
218       pc[i].quad.setCurve(pc[i].start,pc[i].ctrl,pc[i].end);
219   }
220     }
221 
222     /**draw text associated with this glyph
223      *@param i camera index in the virtual space
224      */
225     void textDraw(Graphics2D g,int i){
226   if ((fontSizePolicy>=0) && (text!=null)) {
227       if (!text.equals("")){
228     //g.setColor(this.color);
229     textWidth=(int)g.getFontMetrics().getStringBounds(text,g).getWidth();
230     if ((fontSizePolicy==1) || ((fontSizePolicy==0) && (textWidth<2*pc[i].cs))) {
231         if (textPos==1){
232       //textHeight=(int)g.getFontMetrics().getStringBounds(text,g).getHeight();
233       g.drawString(text,pc[i].cx-textWidth/2,pc[i].cy-pc[i].cs-4);
234         }
235         else if (textPos==-1){
236       textHeight=(int)g.getFontMetrics().getStringBounds(text,g).getHeight();
237       g.drawString(text,pc[i].cx-textWidth/2,pc[i].cy+pc[i].cs+textHeight);
238         }
239         else {g.drawString(text,pc[i].cx-textWidth/2,pc[i].cy);}
240     }
241     else if (fontSizePolicy==2) {  //modify font size to make string fit in glyph   THIS OPTION IS RATHER TIME CONSUMING
242         Font tf=new Font(g.getFont().getName(),g.getFont().getStyle(),g.getFont().getSize());
243         int s=1;
244         while (textWidth>2*pc[i].cs){
245       s=g.getFont().getSize()-2; if (s<0){s=0;break;}
246       g.setFont(new Font(tf.getName(),tf.getStyle(),s));
247       textWidth=(int)g.getFontMetrics().getStringBounds(text,g).getWidth();
248         }
249         if (s>0) {
250       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].cs-4);
253       }
254       else if (textPos==-1){
255           textHeight=(int)g.getFontMetrics().getStringBounds(text,g).getHeight();
256           g.drawString(text,pc[i].cx-textWidth/2,pc[i].cy+pc[i].cs+textHeight);
257       }
258       else {g.drawString(text,pc[i].cx-textWidth/2,pc[i].cy);}
259         }
260         g.setFont(tf);
261     }
262       }
263   }
264     }
265 
266     /**draw glyph 
267      *@param i camera index in the virtual space
268      */
269     public void draw(Graphics2D g,int vW,int vH,int i,Stroke stdS,AffineTransform stdT){
270   if (pc[i].cs>1){//repaint only if object is visible
271       if (filled) {
272     g.setColor(this.color);
273     g.fill(pc[i].quad);
274     g.setColor(borderColor);
275     g.drawLine((int)pc[i].start.x,(int)pc[i].start.y,(int)pc[i].end.x,(int)pc[i].end.y);
276       }
277       else {//if not filled (common case), paint curve with main color, not border color
278     g.setColor(this.color);
279       }
280       if (stroke!=null) {
281     g.setStroke(stroke);
282     g.draw(pc[i].quad);
283     g.setStroke(stdS);
284       }
285       else {
286     g.draw(pc[i].quad);
287       }
288       this.textDraw(g,i);
289   }
290   else g.fillRect(pc[i].cx,pc[i].cy,1,1);
291     }
292 
293     /**returns a clone of this object (only basic information is cloned for now: shape, orientation, position, size)*/
294     public Object clone(){
295   VQdCurve res=new VQdCurve(vx,vy,0,vs,color,orient,vrad,ang);
296   res.borderColor=this.borderColor;
297   res.selectedColor=this.selectedColor;
298   res.mouseInsideColor=this.mouseInsideColor;
299   res.bColor=this.bColor;
300   return res;
301     }
302 
303 }
304