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();
99 ret = RS_Units::formatLinear(dist, graphic->getUnit(),
100 graphic->getLinearFormat(), graphic->getLinearPrecision());
102 ret = QString("%1").arg(dist);
103 //It's properly creating the label...
104 //printf("RS_DimLinear::getMeasuredLabel: label=\"%s\"\n", ret.toAscii().data());
109 bool RS_DimLinear::hasEndpointsWithinWindow(Vector v1, Vector v2)
111 return (edata.extensionPoint1.isInWindow(v1, v2)
112 || edata.extensionPoint2.isInWindow(v1, v2));
116 * Updates the sub entities of this dimension. Called when the
117 * text or the position, alignment, .. changes.
119 * @param autoText Automatically reposition the text label
121 void RS_DimLinear::update(bool autoText)
123 RS_DEBUG->print("RS_DimLinear::update");
130 // distance from entities (DIMEXO)
131 double dimexo = getExtensionLineOffset();
132 // extension line extension (DIMEXE)
133 double dimexe = getExtensionLineExtension();
136 double extAngle = edata.angle + (M_PI / 2.0);
138 // direction of dimension line
140 dirDim.setPolar(100.0, edata.angle);
141 // direction of extension lines
143 dirExt.setPolar(100.0, extAngle);
145 // construction line for dimension line
146 RS_ConstructionLine dimLine(NULL, RS_ConstructionLineData(data.definitionPoint,
147 data.definitionPoint + dirDim));
149 Vector dimP1 = dimLine.getNearestPointOnEntity(edata.extensionPoint1);
150 Vector dimP2 = dimLine.getNearestPointOnEntity(edata.extensionPoint2);
152 // Definitive dimension line:
153 updateCreateDimensionLine(dimP1, dimP2, true, true, autoText);
155 ld = RS_LineData(data.definitionPoint, dimP1);
156 RS_Line* dimensionLine = new RS_Line(this, ld);
157 addEntity(dimensionLine);
159 Vector vDimexo1, vDimexe1, vDimexo2, vDimexe2;
160 vDimexe1.setPolar(dimexe, edata.extensionPoint1.angleTo(dimP1));
161 vDimexo1.setPolar(dimexo, edata.extensionPoint1.angleTo(dimP1));
163 vDimexe2.setPolar(dimexe, edata.extensionPoint2.angleTo(dimP2));
164 vDimexo2.setPolar(dimexo, edata.extensionPoint2.angleTo(dimP2));
166 if ((edata.extensionPoint1 - dimP1).magnitude() < 1e-6)
168 vDimexe1.setPolar(dimexe, data.definitionPoint.angleTo(dimP1) - M_PI / 2.0);
169 vDimexo1.setPolar(dimexo, data.definitionPoint.angleTo(dimP1) - M_PI / 2.0);
172 if ((edata.extensionPoint2 - dimP2).magnitude() < 1e-6)
174 vDimexe2.setPolar(dimexe, data.definitionPoint.angleTo(dimP2) - M_PI / 2.0);
175 vDimexo2.setPolar(dimexo, data.definitionPoint.angleTo(dimP2) - M_PI / 2.0);
179 ld = RS_LineData(edata.extensionPoint1 + vDimexo1, dimP1 + vDimexe1);
180 RS_Line * line = new RS_Line(this, ld);
181 line->setPen(RS_Pen(RS2::FlagInvalid));
182 line->setLayer(NULL);
185 ld = RS_LineData(edata.extensionPoint2 + vDimexo2, dimP2 + vDimexe2);
186 //data.definitionPoint+vDimexe2);
187 line = new RS_Line(this, ld);
188 line->setPen(RS_Pen(RS2::FlagInvalid));
189 line->setLayer(NULL);
195 Vector RS_DimLinear::getExtensionPoint1()
197 return edata.extensionPoint1;
200 Vector RS_DimLinear::getExtensionPoint2()
202 return edata.extensionPoint2;
205 double RS_DimLinear::getAngle()
210 void RS_DimLinear::setAngle(double a)
212 edata.angle = RS_Math::correctAngle(a);
215 double RS_DimLinear::getOblique()
217 return edata.oblique;
220 void RS_DimLinear::move(Vector offset)
222 RS_Dimension::move(offset);
224 edata.extensionPoint1.move(offset);
225 edata.extensionPoint2.move(offset);
229 void RS_DimLinear::rotate(Vector center, double angle)
231 RS_Dimension::rotate(center, angle);
233 edata.extensionPoint1.rotate(center, angle);
234 edata.extensionPoint2.rotate(center, angle);
235 edata.angle = RS_Math::correctAngle(edata.angle+angle);
239 void RS_DimLinear::scale(Vector center, Vector factor)
241 RS_Dimension::scale(center, factor);
243 edata.extensionPoint1.scale(center, factor);
244 edata.extensionPoint2.scale(center, factor);
248 void RS_DimLinear::mirror(Vector axisPoint1, Vector axisPoint2)
250 RS_Dimension::mirror(axisPoint1, axisPoint2);
252 edata.extensionPoint1.mirror(axisPoint1, axisPoint2);
253 edata.extensionPoint2.mirror(axisPoint1, axisPoint2);
256 vec.setPolar(1.0, edata.angle);
257 vec.mirror(Vector(0.0, 0.0), axisPoint2 - axisPoint1);
258 edata.angle = vec.angle();
263 void RS_DimLinear::stretch(Vector firstCorner, Vector secondCorner, Vector offset)
265 //e->calculateBorders();
266 if (getMin().isInWindow(firstCorner, secondCorner)
267 && getMax().isInWindow(firstCorner, secondCorner))
273 //Vector v = data.definitionPoint - edata.extensionPoint2;
274 //double len = edata.extensionPoint2.distanceTo(data.definitionPoint);
275 //double ang1 = edata.extensionPoint1.angleTo(edata.extensionPoint2)
278 if (edata.extensionPoint1.isInWindow(firstCorner, secondCorner))
279 edata.extensionPoint1.move(offset);
281 if (edata.extensionPoint2.isInWindow(firstCorner, secondCorner))
282 edata.extensionPoint2.move(offset);
285 double ang2 = edata.extensionPoint1.angleTo(edata.extensionPoint2)
288 double diff = RS_Math::getAngleDifference(ang1, ang2);
293 if (fabs(diff)>M_PI/2) {
294 ang2 = RS_Math::correctAngle(ang2+M_PI);
298 v.setPolar(len, ang2);
299 data.definitionPoint = edata.extensionPoint2 + v;
306 void RS_DimLinear::moveRef(const Vector & ref, const Vector & offset)
308 if (ref.distanceTo(data.definitionPoint) < 1.0e-4)
310 data.definitionPoint += offset;
313 else if (ref.distanceTo(data.middleOfText) < 1.0e-4)
315 data.middleOfText += offset;
318 else if (ref.distanceTo(edata.extensionPoint1) < 1.0e-4)
320 edata.extensionPoint1 += offset;
323 else if (ref.distanceTo(edata.extensionPoint2) < 1.0e-4)
325 edata.extensionPoint2 += offset;
331 * Dumps the point's data to stdout.
333 std::ostream & operator<<(std::ostream & os, const RS_DimLinear & d)
335 os << " DimLinear: " << d.getData() << "\n" << d.getEData() << "\n";