Source code: com/xerox/VTM/glyphs/VImageOr.java
1 /* FILE: VImageOr.java
2 * DATE OF CREATION: Jan 09 2001
3 * AUTHOR : Emmanuel Pietriga (emmanuel.pietriga@xrce.xerox.com)
4 * MODIF: Thu Jul 10 16:53:51 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.Graphics2D;
24 import java.awt.Font;
25 import java.awt.Stroke;
26 import java.awt.BasicStroke;
27 import java.awt.Image;
28 import java.awt.Polygon;
29 import java.awt.geom.AffineTransform;
30 import java.lang.Math;
31 import java.util.Vector;
32 import javax.swing.*;
33 import com.xerox.VTM.engine.*;
34
35 /**
36 * Image (rectangular) - can be reoriented
37 * @author Emmanuel Pietriga
38 **/
39
40 public class VImageOr extends VImage implements Cloneable {
41
42 /**
43 *@param or orientation
44 */
45 public VImageOr(Image img,float or){
46 super(img);
47 orient=or;
48 }
49
50 /**
51 *@param x coordinate in virtual space
52 *@param y coordinate in virtual space
53 *@param z altitude
54 *@param img image to be displayed
55 *@param or orientation
56 */
57 public VImageOr(long x,long y,float z,Image img,float or){
58 super(x,y,z,img);
59 orient=or;
60 }
61
62 /**set orientation (absolute) - NOT STABLE (causes the VTM to hang sometimes) USE AT YOUR OWN RISK!*/
63 public void orientTo(float angle){
64 orient=angle;
65 try{vsm.repaintNow();}catch(NullPointerException e){/*System.err.println("VSM null in Glyph "+e);*/}
66 // vsm.constMgr.suggestAValue(this.ID,"or",orient);
67 }
68
69 /**set orientation (absolute) */
70 // public void orientToNS(float angle){orient=angle;}
71
72 void computeOrientCoords(int i){
73 float x1=-pc[i].cw;
74 float y1=-pc[i].ch;
75 float x2=pc[i].cw;
76 float y2=pc[i].ch;
77 int[] xcoords={(int)Math.round((x2*Math.cos(orient)+y1*Math.sin(orient))+pc[i].cx),(int)Math.round((x1*Math.cos(orient)+y1*Math.sin(orient))+pc[i].cx),(int)Math.round((x1*Math.cos(orient)+y2*Math.sin(orient))+pc[i].cx),(int)Math.round((x2*Math.cos(orient)+y2*Math.sin(orient))+pc[i].cx)};
78 int[] ycoords={(int)Math.round((y1*Math.cos(orient)-x2*Math.sin(orient))+pc[i].cy),(int)Math.round((y1*Math.cos(orient)-x1*Math.sin(orient))+pc[i].cy),(int)Math.round((y2*Math.cos(orient)-x1*Math.sin(orient))+pc[i].cy),(int)Math.round((y2*Math.cos(orient)-x2*Math.sin(orient))+pc[i].cy)};
79 pc[i].p=new Polygon(xcoords,ycoords,4);
80 }
81
82 /**detects whether the given point is inside this glyph or not
83 *@param x EXPECTS PROJECTED JPanel COORDINATE
84 *@param y EXPECTS PROJECTED JPanel COORDINATE
85 */
86 public boolean coordInside(int x,int y,int camIndex){
87 if (pc[camIndex].p.contains(x,y)){return true;}
88 else {return false;}
89 }
90
91 /**project shape in camera coord sys prior to actual painting*/
92 public void project(Camera c,ViewPanel v){
93 int i=c.getIndex();
94 coef=(float)(c.focal/(c.focal+c.altitude));
95 //find coordinates of object's geom center wrt to camera center and project
96 pc[i].cx=Math.round((vx-c.posx)*coef);
97 pc[i].cy=Math.round((vy-c.posy)*coef);
98 //translate in JPanel coords
99 pc[i].cx=(v.getSize().width/2)+pc[i].cx;
100 pc[i].cy=(v.getSize().height/2)-pc[i].cy;
101 //project width and height
102 if (zoomSensitive){pc[i].cw=Math.round(vw*coef);pc[i].ch=Math.round(vh*coef);}else{pc[i].cw=(int)vw;pc[i].ch=(int)vh;}
103 computeOrientCoords(i);
104 }
105
106 /**draw glyph
107 *@param i camera index in the virtual space
108 *@param vW view width - used to determine if contour should be drawn or not (when it is dashed and object too big)
109 *@param vH view height - used to determine if contour should be drawn or not (when it is dashed and object too big)
110 */
111 public void draw(Graphics2D g,int vW,int vH,int i,Stroke stdS,AffineTransform stdT){
112 if ((pc[i].cw>1) && (pc[i].ch>1)){
113 if (zoomSensitive){trueCoef=scaleFactor*coef;}else{trueCoef=scaleFactor;}
114 if (Math.abs(trueCoef-1.0f)<0.01f){trueCoef=1.0f;} //a threshold greater than 0.01 causes jolts when zooming-unzooming around the 1.0 scale region
115 if (trueCoef!=1.0f){
116 at=AffineTransform.getTranslateInstance(pc[i].cx-pc[i].cw,pc[i].cy-pc[i].ch);
117 if (orient!=0){at.concatenate(AffineTransform.getRotateInstance(-orient,(float)pc[i].cw,(float)pc[i].ch));}
118 at.concatenate(AffineTransform.getScaleInstance(trueCoef,trueCoef));
119 g.drawImage(image,at,null);
120 if (drawBorder==1){if (pc[i].prevMouseIn){g.setColor(borderColor);g.drawPolygon(pc[i].p);}}
121 else if (drawBorder==2){g.setColor(borderColor);g.drawPolygon(pc[i].p);}
122 }
123 else {
124 if (orient==0){g.drawImage(image,pc[i].cx-pc[i].cw,pc[i].cy-pc[i].ch,null);}
125 else {
126 at=AffineTransform.getTranslateInstance(pc[i].cx-pc[i].cw,pc[i].cy-pc[i].ch);
127 at.concatenate(AffineTransform.getRotateInstance(-orient,(float)pc[i].cw,(float)pc[i].ch));
128 if (trueCoef!=1.0f){at.concatenate(AffineTransform.getScaleInstance(trueCoef,trueCoef));}
129 g.drawImage(image,at,null);
130 }
131 if (drawBorder==1){if (pc[i].prevMouseIn){g.setColor(borderColor);g.drawPolygon(pc[i].p);}}
132 else if (drawBorder==2){g.setColor(borderColor);g.drawPolygon(pc[i].p);}
133 }
134 }
135 else {g.fillRect(pc[i].cx,pc[i].cy,1,1);}
136 }
137
138 /**returns a clone of this object (only basic information is cloned for now: shape, orientation, position, size)*/
139 public Object clone(){
140 VImageOr res=new VImageOr(vx,vy,0,image,orient);
141 res.setWidth(vw);
142 res.setHeight(vh);
143 res.borderColor=this.borderColor;
144 res.selectedColor=this.selectedColor;
145 res.mouseInsideColor=this.mouseInsideColor;
146 res.bColor=this.bColor;
147 res.setDrawBorderPolicy(drawBorder);
148 res.setZoomSensitive(zoomSensitive);
149 return res;
150 }
151
152 }