1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.vectomatic.common.model;
19
20 import java.util.HashMap;
21 import java.util.Map;
22 import java.util.Set;
23
24 import org.vectomatic.common.model.geometry.BoundingBox;
25 import org.vectomatic.common.model.geometry.Point;
26 import org.vectomatic.common.model.geometry.TransformMatrix;
27
28 import com.google.gwt.user.client.rpc.IsSerializable;
29
30
31
32
33
34 public abstract class Shape implements IsSerializable {
35 protected transient DrawingModel _model;
36 protected int _id;
37 protected float _r;
38 protected Point _s;
39 protected Point _t;
40 protected transient boolean _dirty;
41 protected transient TransformMatrix _m;
42 protected BoundingBox _bbox;
43
44
45
46 protected Map<Attribute, IAttributeValue> _attributes;
47
48 public Shape() {
49 _t = new Point();
50 _s = new Point(Point.UNIT);
51 _m = new TransformMatrix();
52 _attributes = new HashMap<Attribute, IAttributeValue>();
53 _dirty = true;
54 }
55
56 public Shape(Shape shape) {
57 _t = new Point(shape._t);
58 _r = shape._r;
59 _s = new Point(shape._s);
60 _m = new TransformMatrix(shape._m);
61 _dirty = shape._dirty;
62 _bbox = new BoundingBox(shape._bbox);
63 _attributes = new HashMap<Attribute, IAttributeValue>(shape._attributes);
64 }
65
66 public float getRotation() {
67 return _r;
68 }
69
70 public void setRotation(float r) {
71 _r = r;
72 _dirty = true;
73 }
74
75 public Point getScaling(Point s) {
76 _s.copyTo(s);
77 return s;
78 }
79
80 public void setScaling(Point s) {
81 s.copyTo(_s);
82 _dirty = true;
83 }
84
85 public Point getTranslation(Point t) {
86 _t.copyTo(t);
87 return t;
88 }
89
90 public void setTranslation(Point t) {
91 t.copyTo(_t);
92 _dirty = true;
93 }
94
95 public TransformMatrix getTransform() {
96 if (_dirty) {
97 updateTransform();
98 }
99 return _m;
100 }
101
102 public void setTransform(TransformMatrix m) {
103 m.copyTo(_m);
104 _s.x = (float)Math.sqrt(_m.m11 * _m.m11 + _m.m21 * _m.m21);
105 _s.y = (float)Math.sqrt(_m.m12 * _m.m12 + _m.m22 * _m.m22);
106 _r = (float)(Math.acos(_m.m11 / _s.x));
107 if (_m.m21 < 0f) {
108 _r = 2f * (float)Math.PI - _r;
109 }
110 if (_m.m11 * _m.m22 < 0f) {
111 _s.y = -_s.y;
112 }
113 float cos = (float)Math.cos(_r);
114 float sin = (float)Math.sin(_r);
115 float x1 = _bbox.getXCenter();
116 float y1 = _bbox.getYCenter();
117 _t.x = _m.m13 + _s.x * x1 * cos - _s.y * y1 * sin;
118 _t.y = _m.m23 + _s.x * x1 * sin + _s.y * y1 * cos;
119 _dirty = false;
120 }
121
122 protected void updateTransform() {
123
124
125 float cos = (float)Math.cos(_r);
126 float sin = (float)Math.sin(_r);
127 float x1 = _bbox.getXCenter();
128 float y1 = _bbox.getYCenter();
129 _m.m11 = _s.x * cos; _m.m12 = -_s.y * sin; _m.m13 = - _s.x * x1 * cos + _s.y * y1 * sin + _t.x;
130 _m.m21 = _s.x * sin; _m.m22 = _s.y * cos; _m.m23 = - _s.x * x1 * sin - _s.y * y1 * cos + _t.y;
131 _dirty = false;
132 }
133
134
135 public BoundingBox getBoundingBox() {
136 return _bbox;
137 }
138
139 public DrawingModel getModel() {
140 return _model;
141 }
142
143 public void setModel(DrawingModel model) {
144 _model = model;
145 }
146
147 public IAttributeValue getAttribute(Attribute attr) {
148 return _attributes.get(attr);
149 }
150
151 public IAttributeValue setAttribute(Attribute attr, IAttributeValue value) {
152 return _attributes.put(attr, value);
153 }
154
155 public IAttributeValue clearAttribute(Attribute attr) {
156 return _attributes.remove(attr);
157 }
158
159 public Set<Attribute> getDefinedAttributes() {
160 return _attributes.keySet();
161 }
162
163 public boolean definesAttribute(Attribute attr) {
164 return _attributes.containsKey(attr);
165 }
166
167 public void copyAttributes(Shape src) {
168 _attributes.clear();
169 _attributes.putAll(src._attributes);
170 }
171
172 public abstract void acceptVisitor(IShapeVisitor visitor);
173
174
175
176
177
178
179
180
181
182
183
184
185 public abstract boolean isSame(Shape shape);
186
187 }
188