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 "dimangular.h"
19 #include "constructionline.h"
20 #include "filterdxf.h"
22 #include "information.h"
30 * @para parent Parent Entity Container.
31 * @para d Common dimension geometrical data.
32 * @para ed Extended geometrical data for angular dimension.
34 RS_DimAngular::RS_DimAngular(RS_EntityContainer * parent, const RS_DimensionData & d,
35 const RS_DimAngularData & ed): RS_Dimension(parent, d), edata(ed)
40 /*virtual*/ RS_DimAngular::~RS_DimAngular()
44 /*virtual*/ RS_Entity * RS_DimAngular::clone()
46 RS_DimAngular * d = new RS_DimAngular(*this);
47 #warning "!!! Need to deal with setAutoDelete() Qt3->Qt4 !!!"
48 // d->entities.setAutoDelete(entities.autoDelete());
54 /** @return RS2::EntityDimAngular */
55 /*virtual*/ RS2::EntityType RS_DimAngular::rtti() const
57 return RS2::EntityDimAngular;
61 * @return Copy of data that defines the angular dimension.
64 RS_DimAngularData RS_DimAngular::getEData() const
70 * @return Automatically created label for the default
71 * measurement of this dimension.
73 QString RS_DimAngular::getMeasuredLabel()
77 int dimaunit = getGraphicVariableInt("$DIMAUNIT", 0);
78 int dimadec = getGraphicVariableInt("$DIMADEC", 0);
80 ret = RS_Units::formatAngle(getAngle(),
81 RS_FilterDXF::numberToAngleFormat(dimaunit),
86 .arg(RS_Math::rad2deg(getAngle()))
95 * @return Angle of the measured dimension.
97 double RS_DimAngular::getAngle() {
100 bool reversed = false;
104 getAngles(ang1, ang2, reversed, p1, p2);
122 * @return Center of the measured dimension.
124 Vector RS_DimAngular::getCenter() {
125 RS_ConstructionLine l1(NULL, RS_ConstructionLineData(edata.definitionPoint1,
126 edata.definitionPoint2));
127 RS_ConstructionLine l2(NULL, RS_ConstructionLineData(edata.definitionPoint3,
128 data.definitionPoint));
129 VectorSolutions vs = RS_Information::getIntersection(&l1, &l2, false);
137 * finds out which angles this dimension actually measures.
139 * @param ang1 Reference will return the start angle
140 * @param ang2 Reference will return the end angle
141 * @param reversed Reference will return the reversed flag.
143 * @return true: on success
145 bool RS_DimAngular::getAngles(double& ang1, double& ang2, bool& reversed,
146 Vector& p1, Vector& p2) {
148 Vector center = getCenter();
149 double ang = center.angleTo(edata.definitionPoint4);
152 // find out the angles this dimension refers to:
153 for (int f1=0; f1<=1 && !done; ++f1) {
154 ang1 = RS_Math::correctAngle(
155 edata.definitionPoint1.angleTo(edata.definitionPoint2) + f1*M_PI);
157 p1 = edata.definitionPoint2;
159 p1 = edata.definitionPoint1;
161 for (int f2=0; f2<=1 && !done; ++f2) {
162 ang2 = RS_Math::correctAngle(
163 edata.definitionPoint3.angleTo(data.definitionPoint) + f2*M_PI);
165 p2 = data.definitionPoint;
167 p2 = edata.definitionPoint3;
169 for (int t=0; t<=1 && !done; ++t) {
186 ang1 = RS_Math::correctAngle(ang1);
187 ang2 = RS_Math::correctAngle(ang2);
189 if (RS_Math::isAngleBetween(ang, ang1, ang2, reversed) &&
204 * Updates the sub entities of this dimension. Called when the
205 * dimension or the position, alignment, .. changes.
207 * @param autoText Automatically reposition the text label
209 void RS_DimAngular::update(bool /*autoText*/) {
211 RS_DEBUG->print("RS_DimAngular::update");
219 // distance from entities (DIMEXO)
220 double dimexo = getExtensionLineOffset();
221 // extension line extension (DIMEXE)
222 double dimexe = getExtensionLineExtension();
223 // text height (DIMTXT)
224 double dimtxt = getTextHeight();
225 // text distance to line (DIMGAP)
226 double dimgap = getDimensionLineGap();
229 Vector center = getCenter();
237 bool reversed = false;
241 getAngles(ang1, ang2, reversed, p1, p2);
243 double rad = edata.definitionPoint4.distanceTo(center);
250 // 1st extension line:
251 dist = center.distanceTo(p1);
252 len = rad - dist + dimexe;
253 dir.setPolar(1.0, ang1);
254 line = new RS_Line(this,
255 RS_LineData(center + dir*dist + dir*dimexo,
256 center + dir*dist + dir*len));
257 line->setPen(RS_Pen(RS2::FlagInvalid));
258 line->setLayer(NULL);
261 // 2nd extension line:
262 dist = center.distanceTo(p2);
263 len = rad - dist + dimexe;
264 dir.setPolar(1.0, ang2);
265 line = new RS_Line(this,
266 RS_LineData(center + dir*dist + dir*dimexo,
267 center + dir*dist + dir*len));
268 line->setPen(RS_Pen(RS2::FlagInvalid));
269 line->setLayer(NULL);
272 // Create dimension line (arc):
273 RS_Arc* arc = new RS_Arc(this,
275 rad, ang1, ang2, reversed));
276 arc->setPen(RS_Pen(RS2::FlagInvalid));
280 // length of dimension arc:
281 double distance = arc->getLength();
283 // do we have to put the arrows outside of the arc?
284 bool outsideArrows = (distance<getArrowSize()*2);
287 double arrowAngle1, arrowAngle2;
290 arrowAng = getArrowSize() / rad;
296 if (!arc->isReversed()) {
297 v1.setPolar(rad, arc->getAngle1()+arrowAng);
299 v1.setPolar(rad, arc->getAngle1()-arrowAng);
301 v1+=arc->getCenter();
302 arrowAngle1 = arc->getStartpoint().angleTo(v1);
305 if (!arc->isReversed()) {
306 v2.setPolar(rad, arc->getAngle2()-arrowAng);
308 v2.setPolar(rad, arc->getAngle2()+arrowAng);
310 v2+=arc->getCenter();
311 arrowAngle2 = arc->getEndpoint().angleTo(v2);
313 if (!outsideArrows) {
314 arrowAngle1 = arrowAngle1+M_PI;
315 arrowAngle2 = arrowAngle2+M_PI;
323 arrow = new RS_Solid(this, sd);
324 arrow->shapeArrow(arc->getStartpoint(),
327 arrow->setPen(RS_Pen(RS2::FlagInvalid));
328 arrow->setLayer(NULL);
332 arrow = new RS_Solid(this, sd);
333 arrow->shapeArrow(arc->getEndpoint(),
336 arrow->setPen(RS_Pen(RS2::FlagInvalid));
337 arrow->setLayer(NULL);
342 RS_TextData textData;
343 Vector textPos = arc->getMiddlepoint();
347 double dimAngle1 = textPos.angleTo(arc->getCenter())-M_PI/2.0;
349 // rotate text so it's readable from the bottom or right (ISO)
351 if (dimAngle1>M_PI/2.0*3.0+0.001 ||
352 dimAngle1<M_PI/2.0+0.001) {
354 distV.setPolar(dimgap, dimAngle1+M_PI/2.0);
355 textAngle = dimAngle1;
359 distV.setPolar(dimgap, dimAngle1-M_PI/2.0);
360 textAngle = dimAngle1+M_PI;
363 // move text away from dimension line:
366 textData = RS_TextData(textPos,
377 RS_Text* text = new RS_Text(this, textData);
379 // move text to the side:
380 text->setPen(RS_Pen(RS2::FlagInvalid));
381 text->setLayer(NULL);
387 Vector RS_DimAngular::getDefinitionPoint1()
389 return edata.definitionPoint1;
392 Vector RS_DimAngular::getDefinitionPoint2()
394 return edata.definitionPoint2;
397 Vector RS_DimAngular::getDefinitionPoint3()
399 return edata.definitionPoint3;
402 Vector RS_DimAngular::getDefinitionPoint4()
404 return edata.definitionPoint4;
407 void RS_DimAngular::move(Vector offset)
409 RS_Dimension::move(offset);
411 edata.definitionPoint1.move(offset);
412 edata.definitionPoint2.move(offset);
413 edata.definitionPoint3.move(offset);
414 edata.definitionPoint4.move(offset);
420 void RS_DimAngular::rotate(Vector center, double angle) {
421 RS_Dimension::rotate(center, angle);
423 edata.definitionPoint1.rotate(center, angle);
424 edata.definitionPoint2.rotate(center, angle);
425 edata.definitionPoint3.rotate(center, angle);
426 edata.definitionPoint4.rotate(center, angle);
432 void RS_DimAngular::scale(Vector center, Vector factor) {
433 RS_Dimension::scale(center, factor);
435 edata.definitionPoint1.scale(center, factor);
436 edata.definitionPoint2.scale(center, factor);
437 edata.definitionPoint3.scale(center, factor);
438 edata.definitionPoint4.scale(center, factor);
444 void RS_DimAngular::mirror(Vector axisPoint1, Vector axisPoint2) {
445 RS_Dimension::mirror(axisPoint1, axisPoint2);
447 edata.definitionPoint1.mirror(axisPoint1, axisPoint2);
448 edata.definitionPoint2.mirror(axisPoint1, axisPoint2);
449 edata.definitionPoint3.mirror(axisPoint1, axisPoint2);
450 edata.definitionPoint4.mirror(axisPoint1, axisPoint2);
455 * Dumps the point's data to stdout.
457 std::ostream& operator << (std::ostream& os, const RS_DimAngular& d) {
458 os << " DimAngular: " << d.getData() << "\n" << d.getEData() << "\n";