View Javadoc

1   /**********************************************
2    * Copyright (C) 2009 Lukas Laag
3    * This file is part of Vectomatic.
4    * 
5    * Vectomatic is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    * 
10   * Vectomatic is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   * 
15   * You should have received a copy of the GNU General Public License
16   * along with Vectomatic.  If not, see http://www.gnu.org/licenses/
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   * Base class for geometric shapes
32   * @author Lukas Laag
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  	 * A map of attribute, attribute values.
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 		// Compute the transform matrix
124 		// T(_t) . R(_r) . S(_s) . T(- _bbox.center)
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 	 * Returns true if the specified shape has the same
176 	 * geometrical and styling properties as this shape,
177 	 * false otherwise.
178 	 * @param shape
179 	 * A shape
180 	 * @return
181 	 * True if the specified shape has the same
182 	 * geometrical and styling properties as this shape,
183 	 * false otherwise.
184 	 */
185 	public abstract boolean isSame(Shape shape);
186 
187 }
188