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 // (C) 2010 Underground Software
8 // JLH = James L. Hammons <jlhamm@acm.org>
11 // --- ---------- -----------------------------------------------------------
12 // JLH 05/28/2010 Added this text. :-)
15 #include "rs_dimaligned.h"
19 #include "rs_constructionline.h"
24 * @para parent Parent Entity Container.
25 * @para d Common dimension geometrical data.
26 * @para ed Extended geometrical data for aligned dimension.
28 RS_DimAligned::RS_DimAligned(RS_EntityContainer * parent, const RS_DimensionData & d,
29 const RS_DimAlignedData & ed): RS_Dimension(parent, d), edata(ed)
34 /*virtual*/ RS_DimAligned::~RS_DimAligned()
38 /*virtual*/ RS_Entity * RS_DimAligned::clone()
40 RS_DimAligned * d = new RS_DimAligned(*this);
41 #warning "!!! Need to port setAutoDelete in QList/QMultiHash from Qt3 to Qt4 !!!"
42 // d->entities.setAutoDelete(entities.autoDelete());
48 /** @return RS2::EntityDimAligned */
49 /*virtual*/ RS2::EntityType RS_DimAligned::rtti() const
51 return RS2::EntityDimAligned;
55 * @return Copy of data that defines the aligned dimension.
58 RS_DimAlignedData RS_DimAligned::getEData() const
64 * Sets a new text. The entities representing the
67 //void RS_DimAligned::setText(const QString& t) {
72 VectorSolutions RS_DimAligned::getRefPoints()
74 VectorSolutions ret(edata.extensionPoint1, edata.extensionPoint2,
75 data.definitionPoint, data.middleOfText);
80 * @return Automatically creted label for the default
81 * measurement of this dimension.
83 QString RS_DimAligned::getMeasuredLabel()
85 double dist = edata.extensionPoint1.distanceTo(edata.extensionPoint2);
86 Drawing * graphic = getGraphic();
91 ret = RS_Units::formatLinear(dist, graphic->getUnit(),
92 graphic->getLinearFormat(), graphic->getLinearPrecision());
96 ret = QString("%1").arg(dist);
103 * Updates the sub entities of this dimension. Called when the
104 * text or the position, alignment, .. changes.
106 * @param autoText Automatically reposition the text label
108 void RS_DimAligned::update(bool autoText)
110 RS_DEBUG->print("RS_DimAligned::update");
117 // distance from entities (DIMEXO)
118 double dimexo = getExtensionLineOffset();
119 // definition line definition (DIMEXE)
120 double dimexe = getExtensionLineExtension();
121 // text height (DIMTXT)
122 //double dimtxt = getTextHeight();
123 // text distance to line (DIMGAP)
124 //double dimgap = getDimensionLineGap();
126 // Angle from extension endpoints towards dimension line
127 double extAngle = edata.extensionPoint2.angleTo(data.definitionPoint);
128 // extension lines length
129 double extLength = edata.extensionPoint2.distanceTo(data.definitionPoint);
135 v1.setPolar(dimexo, extAngle);
136 v2.setPolar(dimexe, extAngle);
137 e1.setPolar(1.0, extAngle);
140 ld = RS_LineData(edata.extensionPoint1 + v1, edata.extensionPoint1 + e1 * extLength + v2);
141 line = new RS_Line(this, ld);
142 //line->setLayerToActive();
143 //line->setPenToActive();
144 line->setPen(RS_Pen(RS2::FlagInvalid));
145 line->setLayer(NULL);
149 ld = RS_LineData(edata.extensionPoint2 + v1, edata.extensionPoint2 + e1 * extLength + v2);
150 line = new RS_Line(this, ld);
151 //line->setLayerToActive();
152 //line->setPenToActive();
153 line->setPen(RS_Pen(RS2::FlagInvalid));
154 line->setLayer(NULL);
158 updateCreateDimensionLine(edata.extensionPoint1 + e1 * extLength,
159 edata.extensionPoint2 + e1 * extLength, true, true, autoText);
164 Vector RS_DimAligned::getExtensionPoint1()
166 return edata.extensionPoint1;
169 Vector RS_DimAligned::getExtensionPoint2()
171 return edata.extensionPoint2;
174 bool RS_DimAligned::hasEndpointsWithinWindow(Vector v1, Vector v2)
176 return (edata.extensionPoint1.isInWindow(v1, v2)
177 || edata.extensionPoint2.isInWindow(v1, v2));
180 void RS_DimAligned::move(Vector offset)
182 RS_Dimension::move(offset);
184 edata.extensionPoint1.move(offset);
185 edata.extensionPoint2.move(offset);
189 void RS_DimAligned::rotate(Vector center, double angle)
191 RS_Dimension::rotate(center, angle);
193 edata.extensionPoint1.rotate(center, angle);
194 edata.extensionPoint2.rotate(center, angle);
198 void RS_DimAligned::scale(Vector center, Vector factor)
200 RS_Dimension::scale(center, factor);
202 edata.extensionPoint1.scale(center, factor);
203 edata.extensionPoint2.scale(center, factor);
207 void RS_DimAligned::mirror(Vector axisPoint1, Vector axisPoint2)
209 RS_Dimension::mirror(axisPoint1, axisPoint2);
211 edata.extensionPoint1.mirror(axisPoint1, axisPoint2);
212 edata.extensionPoint2.mirror(axisPoint1, axisPoint2);
216 void RS_DimAligned::stretch(Vector firstCorner, Vector secondCorner, Vector offset)
218 //e->calculateBorders();
219 if (getMin().isInWindow(firstCorner, secondCorner) && getMax().isInWindow(firstCorner, secondCorner))
225 //Vector v = data.definitionPoint - edata.extensionPoint2;
226 double len = edata.extensionPoint2.distanceTo(data.definitionPoint);
227 double ang1 = edata.extensionPoint1.angleTo(edata.extensionPoint2) + M_PI / 2;
229 if (edata.extensionPoint1.isInWindow(firstCorner, secondCorner))
231 edata.extensionPoint1.move(offset);
234 if (edata.extensionPoint2.isInWindow(firstCorner, secondCorner))
236 edata.extensionPoint2.move(offset);
239 double ang2 = edata.extensionPoint1.angleTo(edata.extensionPoint2) + M_PI / 2;
241 double diff = RS_Math::getAngleDifference(ang1, ang2);
248 if (fabs(diff) > M_PI / 2)
250 ang2 = RS_Math::correctAngle(ang2 + M_PI);
254 v.setPolar(len, ang2);
255 data.definitionPoint = edata.extensionPoint2 + v;
261 void RS_DimAligned::moveRef(const Vector & ref, const Vector & offset)
263 if (ref.distanceTo(data.definitionPoint) < 1.0e-4)
265 RS_ConstructionLine l(NULL, RS_ConstructionLineData(edata.extensionPoint1,
266 edata.extensionPoint2));
267 double d = l.getDistanceToPoint(data.definitionPoint + offset);
268 double a = edata.extensionPoint2.angleTo(data.definitionPoint);
269 double ad = RS_Math::getAngleDifference(a,
270 edata.extensionPoint2.angleTo(data.definitionPoint + offset));
272 if (fabs(ad) > M_PI / 2.0 && fabs(ad) < 3.0 / 2.0 * M_PI)
274 a = RS_Math::correctAngle(a + M_PI);
279 data.definitionPoint = edata.extensionPoint2 + v;
282 else if (ref.distanceTo(data.middleOfText) < 1.0e-4)
284 data.middleOfText.move(offset);
287 else if (ref.distanceTo(edata.extensionPoint1) < 1.0e-4)
289 double a1 = edata.extensionPoint2.angleTo(edata.extensionPoint1);
290 double a2 = edata.extensionPoint2.angleTo(edata.extensionPoint1+offset);
291 double d1 = edata.extensionPoint2.distanceTo(edata.extensionPoint1);
292 double d2 = edata.extensionPoint2.distanceTo(edata.extensionPoint1+offset);
293 rotate(edata.extensionPoint2, a2-a1);
295 if (fabs(d1) > 1.0e-4)
297 scale(edata.extensionPoint2, Vector(d2 / d1, d2 / d1));
302 else if (ref.distanceTo(edata.extensionPoint2) < 1.0e-4)
304 double a1 = edata.extensionPoint1.angleTo(edata.extensionPoint2);
305 double a2 = edata.extensionPoint1.angleTo(edata.extensionPoint2 + offset);
306 double d1 = edata.extensionPoint1.distanceTo(edata.extensionPoint2);
307 double d2 = edata.extensionPoint1.distanceTo(edata.extensionPoint2 + offset);
308 rotate(edata.extensionPoint1, a2 - a1);
310 if (fabs(d1) > 1.0e-4)
312 scale(edata.extensionPoint1, Vector(d2/d1, d2/d1));
320 * Dumps the point's data to stdout.
322 std::ostream & operator<<(std::ostream & os, const RS_DimAligned & d)
324 os << " DimAligned: " << d.getData() << "\n" << d.getEData() << "\n";