]> Shamusworld >> Repos - architektonas/blob - src/base/dimradial.cpp
Bugfixes related to removing Snapper class.
[architektonas] / src / base / dimradial.cpp
1 // dimradial.cpp
2 //
3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
9 //
10 // JLH = James L. Hammons <jlhamm@acm.org>
11 //
12 // Who  When        What
13 // ---  ----------  -----------------------------------------------------------
14 // JLH  05/28/2010  Added this text. :-)
15 //
16
17 #include "dimradial.h"
18
19 #include "drawing.h"
20 #include "solid.h"
21 #include "text.h"
22 #include "units.h"
23
24 /**
25  * Constructor.
26  *
27  * @para parent Parent Entity Container.
28  * @para d Common dimension geometrical data.
29  * @para ed Extended geometrical data for radial dimension.
30  */
31 DimRadial::DimRadial(EntityContainer * parent, const DimensionData & d,
32         const DimRadialData & ed): Dimension(parent, d), edata(ed)
33 {
34 }
35
36 /*virtual*/ DimRadial::~DimRadial()
37 {
38 }
39
40 /*virtual*/ Entity * DimRadial::clone()
41 {
42         DimRadial * d = new DimRadial(*this);
43 #warning "!!! Need to deal with setAutoDelete() Qt3->Qt4 !!!"
44 //      d->entities.setAutoDelete(entities.autoDelete());
45         d->initId();
46         d->detach();
47         return d;
48 }
49
50 /**     @return RS2::EntityDimRadial */
51 /*virtual*/ RS2::EntityType DimRadial::rtti() const
52 {
53         return RS2::EntityDimRadial;
54 }
55
56 /**
57  * @return Copy of data that defines the radial dimension.
58  * @see getData()
59  */
60 DimRadialData DimRadial::getEData() const
61 {
62         return edata;
63 }
64
65 /**
66  * @return Automatically created label for the default
67  * measurement of this dimension.
68  */
69 QString DimRadial::getMeasuredLabel()
70 {
71     // Definitive dimension line:
72     double dist = data.definitionPoint.distanceTo(edata.definitionPoint);
73
74     Drawing* graphic = getGraphic();
75
76     QString ret;
77     if (graphic!=NULL) {
78         ret = Units::formatLinear(dist, graphic->getUnit(),
79                                      graphic->getLinearFormat(), graphic->getLinearPrecision());
80     } else {
81         ret = QString("%1").arg(dist);
82     }
83
84     return ret;
85 }
86
87
88 VectorSolutions DimRadial::getRefPoints() {
89         VectorSolutions ret(edata.definitionPoint,
90                                                 data.definitionPoint, data.middleOfText);
91         return ret;
92 }
93
94 /**
95  * Updates the sub entities of this dimension. Called when the
96  * dimension or the position, alignment, .. changes.
97  *
98  * @param autoText Automatically reposition the text label
99  */
100 void DimRadial::update(bool autoText)
101 {
102     DEBUG->print("DimRadial::update");
103
104     clear();
105
106     if (isUndone()) {
107         return;
108     }
109
110     // dimension line:
111     //updateCreateDimensionLine(data.definitionPoint, edata.definitionPoint,
112     //false, true);
113
114     Vector p1 = data.definitionPoint;
115     Vector p2 = edata.definitionPoint;
116     double angle = p1.angleTo(p2);
117
118     // text height (DIMTXT)
119     double dimtxt = getTextHeight();
120     // text distance to line (DIMGAP)
121     double dimgap = getDimensionLineGap();
122
123     // length of dimension line:
124     double length = p1.distanceTo(p2);
125
126     TextData textData;
127
128     textData = TextData(Vector(0.0,0.0),
129                            dimtxt, 30.0,
130                            RS2::VAlignMiddle,
131                            RS2::HAlignCenter,
132                            RS2::LeftToRight,
133                            RS2::Exact,
134                            1.0,
135                            getLabel(),
136                            "standard",
137                            0.0);
138
139     Text* text = new Text(this, textData);
140     double textWidth = text->getSize().x;
141
142     // do we have to put the arrow / text outside of the arc?
143     bool outsideArrow = (length<getArrowSize()*2+textWidth);
144     double arrowAngle;
145
146     if (outsideArrow) {
147         length += getArrowSize()*2 + textWidth;
148         arrowAngle = angle+M_PI;
149     } else {
150         arrowAngle = angle;
151     }
152
153     // create arrow:
154     SolidData sd;
155     Solid* arrow;
156
157     arrow = new Solid(this, sd);
158     arrow->shapeArrow(p2,
159                       arrowAngle,
160                       getArrowSize());
161     arrow->setPen(Pen(RS2::FlagInvalid));
162     arrow->setLayer(NULL);
163     addEntity(arrow);
164
165     Vector p3;
166     p3.setPolar(length, angle);
167     p3 += p1;
168
169     // Create dimension line:
170     Line* dimensionLine = new Line(this, LineData(p1, p3));
171     dimensionLine->setPen(Pen(RS2::FlagInvalid));
172     dimensionLine->setLayer(NULL);
173     addEntity(dimensionLine);
174
175     Vector distV;
176     double textAngle;
177
178     // rotate text so it's readable from the bottom or right (ISO)
179     // quadrant 1 & 4
180     if (angle>M_PI/2.0*3.0+0.001 ||
181             angle<M_PI/2.0+0.001) {
182
183         distV.setPolar(dimgap + dimtxt/2.0, angle+M_PI/2.0);
184         textAngle = angle;
185     }
186     // quadrant 2 & 3
187     else {
188         distV.setPolar(dimgap + dimtxt/2.0, angle-M_PI/2.0);
189         textAngle = angle+M_PI;
190     }
191
192     // move text label:
193     Vector textPos;
194
195     if (data.middleOfText.valid && !autoText) {
196         textPos = data.middleOfText;
197     } else {
198         if (outsideArrow) {
199             textPos.setPolar(length-textWidth/2.0-getArrowSize(), angle);
200         } else {
201             textPos.setPolar(length/2.0, angle);
202         }
203         textPos+=p1;
204         // move text away from dimension line:
205         textPos += distV;
206         data.middleOfText = textPos;
207     }
208
209     text->rotate(Vector(0.0,0.0), textAngle);
210     text->move(textPos);
211
212     text->setPen(Pen(RS2::FlagInvalid));
213     text->setLayer(NULL);
214     addEntity(text);
215
216     calculateBorders();
217 }
218
219 Vector DimRadial::getDefinitionPoint()
220 {
221         return edata.definitionPoint;
222 }
223
224 double DimRadial::getLeader()
225 {
226         return edata.leader;
227 }
228
229 void DimRadial::move(Vector offset)
230 {
231     Dimension::move(offset);
232
233     edata.definitionPoint.move(offset);
234     update();
235 }
236
237 void DimRadial::rotate(Vector center, double angle)
238 {
239     Dimension::rotate(center, angle);
240
241     edata.definitionPoint.rotate(center, angle);
242     update();
243 }
244
245
246
247 void DimRadial::scale(Vector center, Vector factor) {
248     Dimension::scale(center, factor);
249
250     edata.definitionPoint.scale(center, factor);
251     edata.leader*=factor.x;
252     update();
253 }
254
255
256
257 void DimRadial::mirror(Vector axisPoint1, Vector axisPoint2) {
258     Dimension::mirror(axisPoint1, axisPoint2);
259
260     edata.definitionPoint.mirror(axisPoint1, axisPoint2);
261     update();
262 }
263
264
265 void DimRadial::moveRef(const Vector& ref, const Vector& offset) {
266
267     if (ref.distanceTo(edata.definitionPoint)<1.0e-4) {
268                 double d = data.definitionPoint.distanceTo(edata.definitionPoint);
269                 double a = data.definitionPoint.angleTo(edata.definitionPoint + offset);
270
271                 Vector v;
272                 v.setPolar(d, a);
273         edata.definitionPoint = data.definitionPoint + v;
274                 update(true);
275     }
276         else if (ref.distanceTo(data.middleOfText)<1.0e-4) {
277         data.middleOfText.move(offset);
278                 update(false);
279     }
280 }
281
282 /**
283  * Dumps the point's data to stdout.
284  */
285 std::ostream& operator << (std::ostream& os, const DimRadial& d) {
286     os << " DimRadial: " << d.getData() << "\n" << d.getEData() << "\n";
287     return os;
288 }
289
290