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
10 // JLH = James L. Hammons <jlhamm@acm.org>
13 // --- ---------- -----------------------------------------------------------
14 // JLH 05/28/2010 Added this text. :-)
17 #include "dimaligned.h"
21 #include "constructionline.h"
26 * @para parent Parent Entity Container.
27 * @para d Common dimension geometrical data.
28 * @para ed Extended geometrical data for aligned dimension.
30 DimAligned::DimAligned(EntityContainer * parent, const DimensionData & d,
31 const DimAlignedData & ed): Dimension(parent, d), edata(ed)
36 /*virtual*/ DimAligned::~DimAligned()
40 /*virtual*/ Entity * DimAligned::clone()
42 DimAligned * d = new DimAligned(*this);
43 #warning "!!! Need to port setAutoDelete in QList/QMultiHash from Qt3 to Qt4 !!!"
44 // d->entities.setAutoDelete(entities.autoDelete());
50 /** @return RS2::EntityDimAligned */
51 /*virtual*/ RS2::EntityType DimAligned::rtti() const
53 return RS2::EntityDimAligned;
57 * @return Copy of data that defines the aligned dimension.
60 DimAlignedData DimAligned::getEData() const
66 * Sets a new text. The entities representing the
69 //void DimAligned::setText(const QString& t) {
74 VectorSolutions DimAligned::getRefPoints()
76 VectorSolutions ret(edata.extensionPoint1, edata.extensionPoint2,
77 data.definitionPoint, data.middleOfText);
82 * @return Automatically creted label for the default
83 * measurement of this dimension.
85 QString DimAligned::getMeasuredLabel()
87 double dist = edata.extensionPoint1.distanceTo(edata.extensionPoint2);
88 Drawing * graphic = getGraphic();
93 ret = Units::formatLinear(dist, graphic->getUnit(),
94 graphic->getLinearFormat(), graphic->getLinearPrecision());
98 ret = QString("%1").arg(dist);
105 * Updates the sub entities of this dimension. Called when the
106 * text or the position, alignment, .. changes.
108 * @param autoText Automatically reposition the text label
110 void DimAligned::update(bool autoText)
112 DEBUG->print("DimAligned::update");
119 // distance from entities (DIMEXO)
120 double dimexo = getExtensionLineOffset();
121 // definition line definition (DIMEXE)
122 double dimexe = getExtensionLineExtension();
123 // text height (DIMTXT)
124 //double dimtxt = getTextHeight();
125 // text distance to line (DIMGAP)
126 //double dimgap = getDimensionLineGap();
128 // Angle from extension endpoints towards dimension line
129 double extAngle = edata.extensionPoint2.angleTo(data.definitionPoint);
130 // extension lines length
131 double extLength = edata.extensionPoint2.distanceTo(data.definitionPoint);
137 v1.setPolar(dimexo, extAngle);
138 v2.setPolar(dimexe, extAngle);
139 e1.setPolar(1.0, extAngle);
142 ld = LineData(edata.extensionPoint1 + v1, edata.extensionPoint1 + e1 * extLength + v2);
143 line = new Line(this, ld);
144 //line->setLayerToActive();
145 //line->setPenToActive();
146 line->setPen(Pen(RS2::FlagInvalid));
147 line->setLayer(NULL);
151 ld = LineData(edata.extensionPoint2 + v1, edata.extensionPoint2 + e1 * extLength + v2);
152 line = new Line(this, ld);
153 //line->setLayerToActive();
154 //line->setPenToActive();
155 line->setPen(Pen(RS2::FlagInvalid));
156 line->setLayer(NULL);
160 updateCreateDimensionLine(edata.extensionPoint1 + e1 * extLength,
161 edata.extensionPoint2 + e1 * extLength, true, true, autoText);
166 Vector DimAligned::getExtensionPoint1()
168 return edata.extensionPoint1;
171 Vector DimAligned::getExtensionPoint2()
173 return edata.extensionPoint2;
176 bool DimAligned::hasEndpointsWithinWindow(Vector v1, Vector v2)
178 return (edata.extensionPoint1.isInWindow(v1, v2)
179 || edata.extensionPoint2.isInWindow(v1, v2));
182 void DimAligned::move(Vector offset)
184 Dimension::move(offset);
186 edata.extensionPoint1.move(offset);
187 edata.extensionPoint2.move(offset);
191 void DimAligned::rotate(Vector center, double angle)
193 Dimension::rotate(center, angle);
195 edata.extensionPoint1.rotate(center, angle);
196 edata.extensionPoint2.rotate(center, angle);
200 void DimAligned::scale(Vector center, Vector factor)
202 Dimension::scale(center, factor);
204 edata.extensionPoint1.scale(center, factor);
205 edata.extensionPoint2.scale(center, factor);
209 void DimAligned::mirror(Vector axisPoint1, Vector axisPoint2)
211 Dimension::mirror(axisPoint1, axisPoint2);
213 edata.extensionPoint1.mirror(axisPoint1, axisPoint2);
214 edata.extensionPoint2.mirror(axisPoint1, axisPoint2);
218 void DimAligned::stretch(Vector firstCorner, Vector secondCorner, Vector offset)
220 //e->calculateBorders();
221 if (getMin().isInWindow(firstCorner, secondCorner) && getMax().isInWindow(firstCorner, secondCorner))
227 //Vector v = data.definitionPoint - edata.extensionPoint2;
228 double len = edata.extensionPoint2.distanceTo(data.definitionPoint);
229 double ang1 = edata.extensionPoint1.angleTo(edata.extensionPoint2) + M_PI / 2;
231 if (edata.extensionPoint1.isInWindow(firstCorner, secondCorner))
233 edata.extensionPoint1.move(offset);
236 if (edata.extensionPoint2.isInWindow(firstCorner, secondCorner))
238 edata.extensionPoint2.move(offset);
241 double ang2 = edata.extensionPoint1.angleTo(edata.extensionPoint2) + M_PI / 2;
243 double diff = Math::getAngleDifference(ang1, ang2);
250 if (fabs(diff) > M_PI / 2)
252 ang2 = Math::correctAngle(ang2 + M_PI);
256 v.setPolar(len, ang2);
257 data.definitionPoint = edata.extensionPoint2 + v;
263 void DimAligned::moveRef(const Vector & ref, const Vector & offset)
265 if (ref.distanceTo(data.definitionPoint) < 1.0e-4)
267 ConstructionLine l(NULL, ConstructionLineData(edata.extensionPoint1,
268 edata.extensionPoint2));
269 double d = l.getDistanceToPoint(data.definitionPoint + offset);
270 double a = edata.extensionPoint2.angleTo(data.definitionPoint);
271 double ad = Math::getAngleDifference(a,
272 edata.extensionPoint2.angleTo(data.definitionPoint + offset));
274 if (fabs(ad) > M_PI / 2.0 && fabs(ad) < 3.0 / 2.0 * M_PI)
276 a = Math::correctAngle(a + M_PI);
281 data.definitionPoint = edata.extensionPoint2 + v;
284 else if (ref.distanceTo(data.middleOfText) < 1.0e-4)
286 data.middleOfText.move(offset);
289 else if (ref.distanceTo(edata.extensionPoint1) < 1.0e-4)
291 double a1 = edata.extensionPoint2.angleTo(edata.extensionPoint1);
292 double a2 = edata.extensionPoint2.angleTo(edata.extensionPoint1+offset);
293 double d1 = edata.extensionPoint2.distanceTo(edata.extensionPoint1);
294 double d2 = edata.extensionPoint2.distanceTo(edata.extensionPoint1+offset);
295 rotate(edata.extensionPoint2, a2-a1);
297 if (fabs(d1) > 1.0e-4)
299 scale(edata.extensionPoint2, Vector(d2 / d1, d2 / d1));
304 else if (ref.distanceTo(edata.extensionPoint2) < 1.0e-4)
306 double a1 = edata.extensionPoint1.angleTo(edata.extensionPoint2);
307 double a2 = edata.extensionPoint1.angleTo(edata.extensionPoint2 + offset);
308 double d1 = edata.extensionPoint1.distanceTo(edata.extensionPoint2);
309 double d2 = edata.extensionPoint1.distanceTo(edata.extensionPoint2 + offset);
310 rotate(edata.extensionPoint1, a2 - a1);
312 if (fabs(d1) > 1.0e-4)
314 scale(edata.extensionPoint1, Vector(d2/d1, d2/d1));
322 * Dumps the point's data to stdout.
324 std::ostream & operator<<(std::ostream & os, const DimAligned & d)
326 os << " DimAligned: " << d.getData() << "\n" << d.getEData() << "\n";