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 * drawing = GetDrawing();
99 return Units::formatLinear(dist, drawing->getUnit(),
100 drawing->getLinearFormat(), drawing->getLinearPrecision());
102 return QString("%1").arg(dist);
105 bool DimLinear::hasEndpointsWithinWindow(Vector v1, Vector v2)
107 return (edata.extensionPoint1.isInWindow(v1, v2)
108 || edata.extensionPoint2.isInWindow(v1, v2));
112 * Updates the sub entities of this dimension. Called when the
113 * text or the position, alignment, .. changes.
115 * @param autoText Automatically reposition the text label
117 void DimLinear::update(bool autoText)
119 DEBUG->print("DimLinear::update");
126 // distance from entities (DIMEXO)
127 double dimexo = getExtensionLineOffset();
128 // extension line extension (DIMEXE)
129 double dimexe = getExtensionLineExtension();
132 double extAngle = edata.angle + (M_PI / 2.0);
134 // direction of dimension line
136 dirDim.setPolar(100.0, edata.angle);
137 // direction of extension lines
139 dirExt.setPolar(100.0, extAngle);
141 // construction line for dimension line
142 ConstructionLine dimLine(NULL, ConstructionLineData(data.definitionPoint,
143 data.definitionPoint + dirDim));
145 Vector dimP1 = dimLine.getNearestPointOnEntity(edata.extensionPoint1);
146 Vector dimP2 = dimLine.getNearestPointOnEntity(edata.extensionPoint2);
148 // Definitive dimension line:
149 updateCreateDimensionLine(dimP1, dimP2, true, true, autoText);
151 ld = LineData(data.definitionPoint, dimP1);
152 Line* dimensionLine = new Line(this, ld);
153 addEntity(dimensionLine);
155 Vector vDimexo1, vDimexe1, vDimexo2, vDimexe2;
156 vDimexe1.setPolar(dimexe, edata.extensionPoint1.angleTo(dimP1));
157 vDimexo1.setPolar(dimexo, edata.extensionPoint1.angleTo(dimP1));
159 vDimexe2.setPolar(dimexe, edata.extensionPoint2.angleTo(dimP2));
160 vDimexo2.setPolar(dimexo, edata.extensionPoint2.angleTo(dimP2));
162 if ((edata.extensionPoint1 - dimP1).magnitude() < 1e-6)
164 vDimexe1.setPolar(dimexe, data.definitionPoint.angleTo(dimP1) - M_PI / 2.0);
165 vDimexo1.setPolar(dimexo, data.definitionPoint.angleTo(dimP1) - M_PI / 2.0);
168 if ((edata.extensionPoint2 - dimP2).magnitude() < 1e-6)
170 vDimexe2.setPolar(dimexe, data.definitionPoint.angleTo(dimP2) - M_PI / 2.0);
171 vDimexo2.setPolar(dimexo, data.definitionPoint.angleTo(dimP2) - M_PI / 2.0);
175 ld = LineData(edata.extensionPoint1 + vDimexo1, dimP1 + vDimexe1);
176 Line * line = new Line(this, ld);
177 line->setPen(Pen(RS2::FlagInvalid));
178 line->setLayer(NULL);
181 ld = LineData(edata.extensionPoint2 + vDimexo2, dimP2 + vDimexe2);
182 //data.definitionPoint+vDimexe2);
183 line = new Line(this, ld);
184 line->setPen(Pen(RS2::FlagInvalid));
185 line->setLayer(NULL);
191 Vector DimLinear::getExtensionPoint1()
193 return edata.extensionPoint1;
196 Vector DimLinear::getExtensionPoint2()
198 return edata.extensionPoint2;
201 double DimLinear::getAngle()
206 void DimLinear::setAngle(double a)
208 edata.angle = Math::correctAngle(a);
211 double DimLinear::getOblique()
213 return edata.oblique;
216 void DimLinear::move(Vector offset)
218 Dimension::move(offset);
220 edata.extensionPoint1.move(offset);
221 edata.extensionPoint2.move(offset);
225 void DimLinear::rotate(Vector center, double angle)
227 Dimension::rotate(center, angle);
229 edata.extensionPoint1.rotate(center, angle);
230 edata.extensionPoint2.rotate(center, angle);
231 edata.angle = Math::correctAngle(edata.angle+angle);
235 void DimLinear::scale(Vector center, Vector factor)
237 Dimension::scale(center, factor);
239 edata.extensionPoint1.scale(center, factor);
240 edata.extensionPoint2.scale(center, factor);
244 void DimLinear::mirror(Vector axisPoint1, Vector axisPoint2)
246 Dimension::mirror(axisPoint1, axisPoint2);
248 edata.extensionPoint1.mirror(axisPoint1, axisPoint2);
249 edata.extensionPoint2.mirror(axisPoint1, axisPoint2);
252 vec.setPolar(1.0, edata.angle);
253 vec.mirror(Vector(0.0, 0.0), axisPoint2 - axisPoint1);
254 edata.angle = vec.angle();
259 void DimLinear::stretch(Vector firstCorner, Vector secondCorner, Vector offset)
261 //e->calculateBorders();
262 if (getMin().isInWindow(firstCorner, secondCorner)
263 && getMax().isInWindow(firstCorner, secondCorner))
269 //Vector v = data.definitionPoint - edata.extensionPoint2;
270 //double len = edata.extensionPoint2.distanceTo(data.definitionPoint);
271 //double ang1 = edata.extensionPoint1.angleTo(edata.extensionPoint2)
274 if (edata.extensionPoint1.isInWindow(firstCorner, secondCorner))
275 edata.extensionPoint1.move(offset);
277 if (edata.extensionPoint2.isInWindow(firstCorner, secondCorner))
278 edata.extensionPoint2.move(offset);
281 double ang2 = edata.extensionPoint1.angleTo(edata.extensionPoint2)
284 double diff = Math::getAngleDifference(ang1, ang2);
289 if (fabs(diff)>M_PI/2) {
290 ang2 = Math::correctAngle(ang2+M_PI);
294 v.setPolar(len, ang2);
295 data.definitionPoint = edata.extensionPoint2 + v;
302 void DimLinear::moveRef(const Vector & ref, const Vector & offset)
304 if (ref.distanceTo(data.definitionPoint) < 1.0e-4)
306 data.definitionPoint += offset;
309 else if (ref.distanceTo(data.middleOfText) < 1.0e-4)
311 data.middleOfText += offset;
314 else if (ref.distanceTo(edata.extensionPoint1) < 1.0e-4)
316 edata.extensionPoint1 += offset;
319 else if (ref.distanceTo(edata.extensionPoint2) < 1.0e-4)
321 edata.extensionPoint2 += offset;
327 * Dumps the point's data to stdout.
329 std::ostream & operator<<(std::ostream & os, const DimLinear & d)
331 os << " DimLinear: " << d.getData() << "\n" << d.getEData() << "\n";