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_dimlinear.h"
17 #include "rs_constructionline.h"
26 * @para parent Parent Entity Container.
27 * @para d Common dimension geometrical data.
28 * @para ed Extended geometrical data for linear dimension.
30 RS_DimLinear::RS_DimLinear(RS_EntityContainer * parent, const RS_DimensionData & d,
31 const RS_DimLinearData & ed): RS_Dimension(parent, d), edata(ed)
36 /*virtual*/ RS_DimLinear::~RS_DimLinear()
40 /*virtual*/ RS_Entity * RS_DimLinear::clone()
42 RS_DimLinear * d = new RS_DimLinear(*this);
43 #warning "!!! Need to deal with setAutoDelete() Qt3->Qt4 !!!"
44 // d->entities.setAutoDelete(entities.autoDelete());
51 /** @return RS2::EntityDimLinear */
52 /*virtual*/ RS2::EntityType RS_DimLinear::rtti() const
54 return RS2::EntityDimLinear;
58 * @return Copy of data that defines the linear dimension.
61 RS_DimLinearData RS_DimLinear::getEData() const
66 VectorSolutions RS_DimLinear::getRefPoints()
68 VectorSolutions ret(edata.extensionPoint1, edata.extensionPoint2,
69 data.definitionPoint, data.middleOfText);
75 * @return Automatically created label for the default
76 * measurement of this dimension.
78 QString RS_DimLinear::getMeasuredLabel()
80 // direction of dimension line
82 dirDim.setPolar(100.0, edata.angle);
84 // construction line for dimension line
85 RS_ConstructionLine dimLine(NULL, RS_ConstructionLineData(data.definitionPoint,
86 data.definitionPoint + dirDim));
88 Vector dimP1 = dimLine.getNearestPointOnEntity(edata.extensionPoint1);
89 Vector dimP2 = dimLine.getNearestPointOnEntity(edata.extensionPoint2);
91 // Definitive dimension line:
92 double dist = dimP1.distanceTo(dimP2);
94 Drawing * graphic = getGraphic();
100 ret = RS_Units::formatLinear(dist, graphic->getUnit(),
101 graphic->getLinearFormat(), graphic->getLinearPrecision());
105 ret = QString("%1").arg(dist);
107 //It's properly creating the label...
108 //printf("RS_DimLinear::getMeasuredLabel: label=\"%s\"\n", ret.toAscii().data());
113 bool RS_DimLinear::hasEndpointsWithinWindow(Vector v1, Vector v2)
115 return (edata.extensionPoint1.isInWindow(v1, v2)
116 || edata.extensionPoint2.isInWindow(v1, v2));
120 * Updates the sub entities of this dimension. Called when the
121 * text or the position, alignment, .. changes.
123 * @param autoText Automatically reposition the text label
125 void RS_DimLinear::update(bool autoText)
127 RS_DEBUG->print("RS_DimLinear::update");
134 // distance from entities (DIMEXO)
135 double dimexo = getExtensionLineOffset();
136 // extension line extension (DIMEXE)
137 double dimexe = getExtensionLineExtension();
140 double extAngle = edata.angle + (M_PI/2.0);
142 // direction of dimension line
144 dirDim.setPolar(100.0, edata.angle);
145 // direction of extension lines
147 dirExt.setPolar(100.0, extAngle);
149 // construction line for dimension line
150 RS_ConstructionLine dimLine(NULL, RS_ConstructionLineData(data.definitionPoint,
151 data.definitionPoint + dirDim));
153 Vector dimP1 = dimLine.getNearestPointOnEntity(edata.extensionPoint1);
154 Vector dimP2 = dimLine.getNearestPointOnEntity(edata.extensionPoint2);
156 // Definitive dimension line:
157 updateCreateDimensionLine(dimP1, dimP2, true, true, autoText);
159 ld = RS_LineData(data.definitionPoint, dimP1);
160 RS_Line* dimensionLine = new RS_Line(this, ld);
161 addEntity(dimensionLine);
163 Vector vDimexo1, vDimexe1, vDimexo2, vDimexe2;
164 vDimexe1.setPolar(dimexe, edata.extensionPoint1.angleTo(dimP1));
165 vDimexo1.setPolar(dimexo, edata.extensionPoint1.angleTo(dimP1));
167 vDimexe2.setPolar(dimexe, edata.extensionPoint2.angleTo(dimP2));
168 vDimexo2.setPolar(dimexo, edata.extensionPoint2.angleTo(dimP2));
170 if ((edata.extensionPoint1 - dimP1).magnitude() < 1e-6)
172 vDimexe1.setPolar(dimexe, data.definitionPoint.angleTo(dimP1) - M_PI / 2.0);
173 vDimexo1.setPolar(dimexo, data.definitionPoint.angleTo(dimP1) - M_PI / 2.0);
176 if ((edata.extensionPoint2 - dimP2).magnitude() < 1e-6)
178 vDimexe2.setPolar(dimexe, data.definitionPoint.angleTo(dimP2) - M_PI / 2.0);
179 vDimexo2.setPolar(dimexo, data.definitionPoint.angleTo(dimP2) - M_PI / 2.0);
183 ld = RS_LineData(edata.extensionPoint1 + vDimexo1, dimP1 + vDimexe1);
184 RS_Line * line = new RS_Line(this, ld);
185 line->setPen(RS_Pen(RS2::FlagInvalid));
186 line->setLayer(NULL);
189 ld = RS_LineData(edata.extensionPoint2 + vDimexo2, dimP2 + vDimexe2);
190 //data.definitionPoint+vDimexe2);
191 line = new RS_Line(this, ld);
192 line->setPen(RS_Pen(RS2::FlagInvalid));
193 line->setLayer(NULL);
199 Vector RS_DimLinear::getExtensionPoint1()
201 return edata.extensionPoint1;
204 Vector RS_DimLinear::getExtensionPoint2()
206 return edata.extensionPoint2;
209 double RS_DimLinear::getAngle()
214 void RS_DimLinear::setAngle(double a)
216 edata.angle = RS_Math::correctAngle(a);
219 double RS_DimLinear::getOblique()
221 return edata.oblique;
224 void RS_DimLinear::move(Vector offset)
226 RS_Dimension::move(offset);
228 edata.extensionPoint1.move(offset);
229 edata.extensionPoint2.move(offset);
233 void RS_DimLinear::rotate(Vector center, double angle)
235 RS_Dimension::rotate(center, angle);
237 edata.extensionPoint1.rotate(center, angle);
238 edata.extensionPoint2.rotate(center, angle);
239 edata.angle = RS_Math::correctAngle(edata.angle+angle);
243 void RS_DimLinear::scale(Vector center, Vector factor)
245 RS_Dimension::scale(center, factor);
247 edata.extensionPoint1.scale(center, factor);
248 edata.extensionPoint2.scale(center, factor);
252 void RS_DimLinear::mirror(Vector axisPoint1, Vector axisPoint2)
254 RS_Dimension::mirror(axisPoint1, axisPoint2);
256 edata.extensionPoint1.mirror(axisPoint1, axisPoint2);
257 edata.extensionPoint2.mirror(axisPoint1, axisPoint2);
260 vec.setPolar(1.0, edata.angle);
261 vec.mirror(Vector(0.0, 0.0), axisPoint2 - axisPoint1);
262 edata.angle = vec.angle();
267 void RS_DimLinear::stretch(Vector firstCorner, Vector secondCorner, Vector offset)
269 //e->calculateBorders();
270 if (getMin().isInWindow(firstCorner, secondCorner)
271 && getMax().isInWindow(firstCorner, secondCorner))
277 //Vector v = data.definitionPoint - edata.extensionPoint2;
278 //double len = edata.extensionPoint2.distanceTo(data.definitionPoint);
279 //double ang1 = edata.extensionPoint1.angleTo(edata.extensionPoint2)
282 if (edata.extensionPoint1.isInWindow(firstCorner, secondCorner))
283 edata.extensionPoint1.move(offset);
285 if (edata.extensionPoint2.isInWindow(firstCorner, secondCorner))
286 edata.extensionPoint2.move(offset);
289 double ang2 = edata.extensionPoint1.angleTo(edata.extensionPoint2)
292 double diff = RS_Math::getAngleDifference(ang1, ang2);
297 if (fabs(diff)>M_PI/2) {
298 ang2 = RS_Math::correctAngle(ang2+M_PI);
302 v.setPolar(len, ang2);
303 data.definitionPoint = edata.extensionPoint2 + v;
310 void RS_DimLinear::moveRef(const Vector & ref, const Vector & offset)
312 if (ref.distanceTo(data.definitionPoint) < 1.0e-4)
314 data.definitionPoint += offset;
317 else if (ref.distanceTo(data.middleOfText) < 1.0e-4)
319 data.middleOfText += offset;
322 else if (ref.distanceTo(edata.extensionPoint1) < 1.0e-4)
324 edata.extensionPoint1 += offset;
327 else if (ref.distanceTo(edata.extensionPoint2) < 1.0e-4)
329 edata.extensionPoint2 += offset;
335 * Dumps the point's data to stdout.
337 std::ostream & operator<<(std::ostream & os, const RS_DimLinear & d)
339 os << " DimLinear: " << d.getData() << "\n" << d.getEData() << "\n";