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 "dimlinear.h"
19 #include "constructionline.h"
28 * @para parent Parent Entity Container.
29 * @para d Common dimension geometrical data.
30 * @para ed Extended geometrical data for linear dimension.
32 DimLinear::DimLinear(EntityContainer * parent, const DimensionData & d,
33 const DimLinearData & ed): Dimension(parent, d), edata(ed)
38 /*virtual*/ DimLinear::~DimLinear()
42 /*virtual*/ Entity * DimLinear::clone()
44 DimLinear * d = new DimLinear(*this);
45 #warning "!!! Need to deal with setAutoDelete() Qt3->Qt4 !!!"
46 // d->entities.setAutoDelete(entities.autoDelete());
53 /** @return RS2::EntityDimLinear */
54 /*virtual*/ RS2::EntityType DimLinear::rtti() const
56 return RS2::EntityDimLinear;
60 * @return Copy of data that defines the linear dimension.
63 DimLinearData DimLinear::getEData() const
68 VectorSolutions DimLinear::getRefPoints()
70 VectorSolutions ret(edata.extensionPoint1, edata.extensionPoint2,
71 data.definitionPoint, data.middleOfText);
77 * @return Automatically created label for the default
78 * measurement of this dimension.
80 QString DimLinear::getMeasuredLabel()
82 // direction of dimension line
84 dirDim.setPolar(100.0, edata.angle);
86 // construction line for dimension line
87 ConstructionLine dimLine(NULL, ConstructionLineData(data.definitionPoint,
88 data.definitionPoint + dirDim));
90 Vector dimP1 = dimLine.getNearestPointOnEntity(edata.extensionPoint1);
91 Vector dimP2 = dimLine.getNearestPointOnEntity(edata.extensionPoint2);
93 // Definitive dimension line:
94 double dist = dimP1.distanceTo(dimP2);
96 Drawing * graphic = getGraphic();
101 ret = Units::formatLinear(dist, graphic->getUnit(),
102 graphic->getLinearFormat(), graphic->getLinearPrecision());
104 ret = QString("%1").arg(dist);
105 //It's properly creating the label...
106 //printf("DimLinear::getMeasuredLabel: label=\"%s\"\n", ret.toAscii().data());
111 bool DimLinear::hasEndpointsWithinWindow(Vector v1, Vector v2)
113 return (edata.extensionPoint1.isInWindow(v1, v2)
114 || edata.extensionPoint2.isInWindow(v1, v2));
118 * Updates the sub entities of this dimension. Called when the
119 * text or the position, alignment, .. changes.
121 * @param autoText Automatically reposition the text label
123 void DimLinear::update(bool autoText)
125 DEBUG->print("DimLinear::update");
132 // distance from entities (DIMEXO)
133 double dimexo = getExtensionLineOffset();
134 // extension line extension (DIMEXE)
135 double dimexe = getExtensionLineExtension();
138 double extAngle = edata.angle + (M_PI / 2.0);
140 // direction of dimension line
142 dirDim.setPolar(100.0, edata.angle);
143 // direction of extension lines
145 dirExt.setPolar(100.0, extAngle);
147 // construction line for dimension line
148 ConstructionLine dimLine(NULL, ConstructionLineData(data.definitionPoint,
149 data.definitionPoint + dirDim));
151 Vector dimP1 = dimLine.getNearestPointOnEntity(edata.extensionPoint1);
152 Vector dimP2 = dimLine.getNearestPointOnEntity(edata.extensionPoint2);
154 // Definitive dimension line:
155 updateCreateDimensionLine(dimP1, dimP2, true, true, autoText);
157 ld = LineData(data.definitionPoint, dimP1);
158 Line* dimensionLine = new Line(this, ld);
159 addEntity(dimensionLine);
161 Vector vDimexo1, vDimexe1, vDimexo2, vDimexe2;
162 vDimexe1.setPolar(dimexe, edata.extensionPoint1.angleTo(dimP1));
163 vDimexo1.setPolar(dimexo, edata.extensionPoint1.angleTo(dimP1));
165 vDimexe2.setPolar(dimexe, edata.extensionPoint2.angleTo(dimP2));
166 vDimexo2.setPolar(dimexo, edata.extensionPoint2.angleTo(dimP2));
168 if ((edata.extensionPoint1 - dimP1).magnitude() < 1e-6)
170 vDimexe1.setPolar(dimexe, data.definitionPoint.angleTo(dimP1) - M_PI / 2.0);
171 vDimexo1.setPolar(dimexo, data.definitionPoint.angleTo(dimP1) - M_PI / 2.0);
174 if ((edata.extensionPoint2 - dimP2).magnitude() < 1e-6)
176 vDimexe2.setPolar(dimexe, data.definitionPoint.angleTo(dimP2) - M_PI / 2.0);
177 vDimexo2.setPolar(dimexo, data.definitionPoint.angleTo(dimP2) - M_PI / 2.0);
181 ld = LineData(edata.extensionPoint1 + vDimexo1, dimP1 + vDimexe1);
182 Line * line = new Line(this, ld);
183 line->setPen(Pen(RS2::FlagInvalid));
184 line->setLayer(NULL);
187 ld = LineData(edata.extensionPoint2 + vDimexo2, dimP2 + vDimexe2);
188 //data.definitionPoint+vDimexe2);
189 line = new Line(this, ld);
190 line->setPen(Pen(RS2::FlagInvalid));
191 line->setLayer(NULL);
197 Vector DimLinear::getExtensionPoint1()
199 return edata.extensionPoint1;
202 Vector DimLinear::getExtensionPoint2()
204 return edata.extensionPoint2;
207 double DimLinear::getAngle()
212 void DimLinear::setAngle(double a)
214 edata.angle = Math::correctAngle(a);
217 double DimLinear::getOblique()
219 return edata.oblique;
222 void DimLinear::move(Vector offset)
224 Dimension::move(offset);
226 edata.extensionPoint1.move(offset);
227 edata.extensionPoint2.move(offset);
231 void DimLinear::rotate(Vector center, double angle)
233 Dimension::rotate(center, angle);
235 edata.extensionPoint1.rotate(center, angle);
236 edata.extensionPoint2.rotate(center, angle);
237 edata.angle = Math::correctAngle(edata.angle+angle);
241 void DimLinear::scale(Vector center, Vector factor)
243 Dimension::scale(center, factor);
245 edata.extensionPoint1.scale(center, factor);
246 edata.extensionPoint2.scale(center, factor);
250 void DimLinear::mirror(Vector axisPoint1, Vector axisPoint2)
252 Dimension::mirror(axisPoint1, axisPoint2);
254 edata.extensionPoint1.mirror(axisPoint1, axisPoint2);
255 edata.extensionPoint2.mirror(axisPoint1, axisPoint2);
258 vec.setPolar(1.0, edata.angle);
259 vec.mirror(Vector(0.0, 0.0), axisPoint2 - axisPoint1);
260 edata.angle = vec.angle();
265 void DimLinear::stretch(Vector firstCorner, Vector secondCorner, Vector offset)
267 //e->calculateBorders();
268 if (getMin().isInWindow(firstCorner, secondCorner)
269 && getMax().isInWindow(firstCorner, secondCorner))
275 //Vector v = data.definitionPoint - edata.extensionPoint2;
276 //double len = edata.extensionPoint2.distanceTo(data.definitionPoint);
277 //double ang1 = edata.extensionPoint1.angleTo(edata.extensionPoint2)
280 if (edata.extensionPoint1.isInWindow(firstCorner, secondCorner))
281 edata.extensionPoint1.move(offset);
283 if (edata.extensionPoint2.isInWindow(firstCorner, secondCorner))
284 edata.extensionPoint2.move(offset);
287 double ang2 = edata.extensionPoint1.angleTo(edata.extensionPoint2)
290 double diff = Math::getAngleDifference(ang1, ang2);
295 if (fabs(diff)>M_PI/2) {
296 ang2 = Math::correctAngle(ang2+M_PI);
300 v.setPolar(len, ang2);
301 data.definitionPoint = edata.extensionPoint2 + v;
308 void DimLinear::moveRef(const Vector & ref, const Vector & offset)
310 if (ref.distanceTo(data.definitionPoint) < 1.0e-4)
312 data.definitionPoint += offset;
315 else if (ref.distanceTo(data.middleOfText) < 1.0e-4)
317 data.middleOfText += offset;
320 else if (ref.distanceTo(edata.extensionPoint1) < 1.0e-4)
322 edata.extensionPoint1 += offset;
325 else if (ref.distanceTo(edata.extensionPoint2) < 1.0e-4)
327 edata.extensionPoint2 += offset;
333 * Dumps the point's data to stdout.
335 std::ostream & operator<<(std::ostream & os, const DimLinear & d)
337 os << " DimLinear: " << d.getData() << "\n" << d.getEData() << "\n";