diff --git a/src/app/dialogs/dialogs.h b/src/app/dialogs/dialogs.h index c9b296c6a..fd7f165a6 100644 --- a/src/app/dialogs/dialogs.h +++ b/src/app/dialogs/dialogs.h @@ -53,6 +53,7 @@ #include "tools/dialogcurveintersectaxis.h" #include "tools/dialogpointofintersectionarcs.h" #include "tools/dialogpointofintersectioncircles.h" +#include "tools/dialogpointfromcircleandtangent.h" #include "app/dialoghistory.h" #include "app/dialogincrements.h" diff --git a/src/app/dialogs/dialogs.pri b/src/app/dialogs/dialogs.pri index d5c073d11..92a97ef7f 100644 --- a/src/app/dialogs/dialogs.pri +++ b/src/app/dialogs/dialogs.pri @@ -46,7 +46,8 @@ HEADERS += \ $$PWD/app/dialoglayoutprogress.h \ $$PWD/app/dialogsavelayout.h \ $$PWD/tools/dialogpointofintersectionarcs.h \ - $$PWD/tools/dialogpointofintersectioncircles.h + $$PWD/tools/dialogpointofintersectioncircles.h \ + $$PWD/tools/dialogpointfromcircleandtangent.h SOURCES += \ $$PWD/tools/dialogtriangle.cpp \ @@ -91,7 +92,8 @@ SOURCES += \ $$PWD/app/dialoglayoutprogress.cpp \ $$PWD/app/dialogsavelayout.cpp \ $$PWD/tools/dialogpointofintersectionarcs.cpp \ - $$PWD/tools/dialogpointofintersectioncircles.cpp + $$PWD/tools/dialogpointofintersectioncircles.cpp \ + $$PWD/tools/dialogpointfromcircleandtangent.cpp FORMS += \ $$PWD/tools/dialogtriangle.ui \ @@ -130,4 +132,5 @@ FORMS += \ $$PWD/app/dialoglayoutprogress.ui \ $$PWD/app/dialogsavelayout.ui \ $$PWD/tools/dialogpointofintersectionarcs.ui \ - $$PWD/tools/dialogpointofintersectioncircles.ui + $$PWD/tools/dialogpointofintersectioncircles.ui \ + $$PWD/tools/dialogpointfromcircleandtangent.ui diff --git a/src/app/dialogs/tools/dialogpointfromcircleandtangent.cpp b/src/app/dialogs/tools/dialogpointfromcircleandtangent.cpp new file mode 100644 index 000000000..40988afd4 --- /dev/null +++ b/src/app/dialogs/tools/dialogpointfromcircleandtangent.cpp @@ -0,0 +1,317 @@ +/************************************************************************ + ** + ** @file dialogpointfromcircleandtangent.cpp + ** @author Roman Telezhynskyi + ** @date 3 6, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include "dialogpointfromcircleandtangent.h" +#include "ui_dialogpointfromcircleandtangent.h" + +#include "../../libs/vgeometry/vpointf.h" +#include "../../container/vcontainer.h" +#include "../../visualization/vistoolpointfromcircleandtangent.h" +#include "../../widgets/vmaingraphicsscene.h" +#include "dialogeditwrongformula.h" + +//--------------------------------------------------------------------------------------------------------------------- +DialogPointFromCircleAndTangent::DialogPointFromCircleAndTangent(const VContainer *data, const quint32 &toolId, + QWidget *parent) + :DialogTool(data, toolId, parent), ui(new Ui::DialogPointFromCircleAndTangent), flagCircleRadius(false), + timerCircleRadius(nullptr), circleRadius(), formulaBaseHeightCircleRadius(0), angleCircleRadius(INT_MIN) +{ + ui->setupUi(this); + + ui->lineEditNamePoint->setText(qApp->getCurrentDocument()->GenerateLabel(LabelType::NewLabel)); + labelEditNamePoint = ui->labelEditNamePoint; + + plainTextEditFormula = ui->plainTextEditRadius; + this->formulaBaseHeightCircleRadius = ui->plainTextEditRadius->height(); + + ui->plainTextEditRadius->installEventFilter(this); + + timerCircleRadius = new QTimer(this); + connect(timerCircleRadius, &QTimer::timeout, this, &DialogPointFromCircleAndTangent::EvalCircleRadius); + + InitOkCancelApply(ui); + CheckState(); + + FillComboBoxPoints(ui->comboBoxCircleCenter); + FillComboBoxPoints(ui->comboBoxTangentPoint); + FillComboBoxCrossCirclesPoints(ui->comboBoxResult); + + connect(ui->lineEditNamePoint, &QLineEdit::textChanged, this, &DialogPointFromCircleAndTangent::NamePointChanged); + connect(ui->comboBoxCircleCenter, + static_cast(&QComboBox::currentIndexChanged), + this, &DialogPointFromCircleAndTangent::PointChanged); + + connect(ui->toolButtonExprRadius, &QPushButton::clicked, this, + &DialogPointFromCircleAndTangent::FXCircleRadius); + + connect(ui->plainTextEditRadius, &QPlainTextEdit::textChanged, this, + &DialogPointFromCircleAndTangent::CircleRadiusChanged); + + connect(ui->pushButtonGrowRadius, &QPushButton::clicked, this, + &DialogPointFromCircleAndTangent::DeployCircleRadiusTextEdit); + + vis = new VisToolPointFromCircleAndTangent(data); +} + +//--------------------------------------------------------------------------------------------------------------------- +DialogPointFromCircleAndTangent::~DialogPointFromCircleAndTangent() +{ + DeleteVisualization(); + delete ui; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPointFromCircleAndTangent::SetPointName(const QString &value) +{ + pointName = value; + ui->lineEditNamePoint->setText(pointName); +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 DialogPointFromCircleAndTangent::GetCircleCenterId() const +{ + return getCurrentObjectId(ui->comboBoxCircleCenter); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPointFromCircleAndTangent::SetCircleCenterId(const quint32 &value) +{ + setCurrentPointId(ui->comboBoxCircleCenter, value); + + VisToolPointFromCircleAndTangent *point = qobject_cast(vis); + SCASSERT(point != nullptr); + point->setPoint2Id(value); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString DialogPointFromCircleAndTangent::GetCircleRadius() const +{ + return qApp->FormulaFromUser(ui->plainTextEditRadius->toPlainText()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPointFromCircleAndTangent::SetCircleRadius(const QString &value) +{ + const QString formula = qApp->FormulaToUser(value); + // increase height if needed. + if (formula.length() > 80) + { + this->DeployCircleRadiusTextEdit(); + } + ui->plainTextEditRadius->setPlainText(formula); + + VisToolPointFromCircleAndTangent *point = qobject_cast(vis); + SCASSERT(point != nullptr); + point->setCRadius(formula); + + MoveCursorToEnd(ui->plainTextEditRadius); +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 DialogPointFromCircleAndTangent::GetTangentPointId() const +{ + return getCurrentObjectId(ui->comboBoxTangentPoint); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPointFromCircleAndTangent::SetTangentPointId(const quint32 &value) +{ + setCurrentPointId(ui->comboBoxTangentPoint, value); + + VisToolPointFromCircleAndTangent *point = qobject_cast(vis); + SCASSERT(point != nullptr); + point->setPoint1Id(value); +} + +//--------------------------------------------------------------------------------------------------------------------- +CrossCirclesPoint DialogPointFromCircleAndTangent::GetCrossCirclesPoint() const +{ + return getCurrentCrossPoint(ui->comboBoxResult); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPointFromCircleAndTangent::SetCrossCirclesPoint(CrossCirclesPoint &p) +{ + const qint32 index = ui->comboBoxResult->findData(static_cast(p)); + if (index != -1) + { + ui->comboBoxResult->setCurrentIndex(index); + + VisToolPointFromCircleAndTangent *point = qobject_cast(vis); + SCASSERT(point != nullptr); + point->setCrossPoint(p); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPointFromCircleAndTangent::ChosenObject(quint32 id, const SceneObject &type) +{ + if (prepare == false)// After first choose we ignore all objects + { + if (type == SceneObject::Point) + { + VisToolPointFromCircleAndTangent *point = qobject_cast(vis); + SCASSERT(point != nullptr); + + switch (number) + { + case 0: + if (SetObject(id, ui->comboBoxTangentPoint, tr("Select a circle center"))) + { + number++; + point->VisualMode(id); + } + break; + case 1: + if (getCurrentObjectId(ui->comboBoxTangentPoint) != id) + { + if (SetObject(id, ui->comboBoxCircleCenter, "")) + { + number = 0; + point->setPoint2Id(id); + point->RefreshGeometry(); + prepare = true; + this->setModal(true); + this->show(); + } + } + break; + default: + break; + } + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPointFromCircleAndTangent::PointChanged() +{ + QColor color = okColor; + if (getCurrentObjectId(ui->comboBoxCircleCenter) == getCurrentObjectId(ui->comboBoxTangentPoint)) + { + flagError = false; + color = errorColor; + } + else + { + flagError = true; + color = okColor; + } + ChangeColor(ui->labelCircleCenter, color); + ChangeColor(ui->labelTangentPoint, color); + CheckState(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPointFromCircleAndTangent::DeployCircleRadiusTextEdit() +{ + DeployFormula(ui->plainTextEditRadius, ui->pushButtonGrowRadius, formulaBaseHeightCircleRadius); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPointFromCircleAndTangent::CircleRadiusChanged() +{ + labelEditFormula = ui->labelEditRadius; + labelResultCalculation = ui->labelResultCircleRadius; + ValFormulaChanged(flagCircleRadius, ui->plainTextEditRadius, timerCircleRadius); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPointFromCircleAndTangent::FXCircleRadius() +{ + DialogEditWrongFormula *dialog = new DialogEditWrongFormula(data, toolId, this); + dialog->setWindowTitle(tr("Edit radius")); + dialog->SetFormula(GetCircleRadius()); + if (dialog->exec() == QDialog::Accepted) + { + SetCircleRadius(dialog->GetFormula()); + } + delete dialog; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPointFromCircleAndTangent::EvalCircleRadius() +{ + labelEditFormula = ui->labelEditRadius; + const QString postfix = VDomDocument::UnitsToStr(qApp->patternUnit(), true); + const qreal radius = Eval(ui->plainTextEditRadius->toPlainText(), flagCircleRadius, + ui->labelResultCircleRadius, postfix); + + if (radius < 0) + { + flagCircleRadius = false; + ChangeColor(labelEditFormula, Qt::red); + ui->labelResultCircleRadius->setText(tr("Error")); + ui->labelResultCircleRadius->setToolTip(tr("Radius can't be negative")); + + DialogPointFromCircleAndTangent::CheckState(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPointFromCircleAndTangent::ShowVisualization() +{ + AddVisualization(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPointFromCircleAndTangent::SaveData() +{ + pointName = ui->lineEditNamePoint->text(); + + QString radius = ui->plainTextEditRadius->toPlainText(); + radius.replace("\n", " "); + + VisToolPointFromCircleAndTangent *point = qobject_cast(vis); + SCASSERT(point != nullptr); + + point->setPoint1Id(GetTangentPointId()); + point->setPoint2Id(GetCircleCenterId()); + point->setCRadius(radius); + point->setCrossPoint(GetCrossCirclesPoint()); + point->RefreshGeometry(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPointFromCircleAndTangent::closeEvent(QCloseEvent *event) +{ + ui->plainTextEditRadius->blockSignals(true); + DialogTool::closeEvent(event); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPointFromCircleAndTangent::CheckState() +{ + SCASSERT(bOk != nullptr); + bOk->setEnabled(flagFormula && flagName && flagError && flagCircleRadius); + // In case dialog hasn't apply button + if ( bApply != nullptr) + { + bApply->setEnabled(bOk->isEnabled()); + } +} diff --git a/src/app/dialogs/tools/dialogpointfromcircleandtangent.h b/src/app/dialogs/tools/dialogpointfromcircleandtangent.h new file mode 100644 index 000000000..f1fdcaf9d --- /dev/null +++ b/src/app/dialogs/tools/dialogpointfromcircleandtangent.h @@ -0,0 +1,91 @@ +/************************************************************************ + ** + ** @file dialogpointfromcircleandtangent.h + ** @author Roman Telezhynskyi + ** @date 3 6, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef DIALOGPOINTFROMCIRCLEANDTANGENT_H +#define DIALOGPOINTFROMCIRCLEANDTANGENT_H + +#include "dialogtool.h" + +namespace Ui +{ + class DialogPointFromCircleAndTangent; +} + +class DialogPointFromCircleAndTangent : public DialogTool +{ + Q_OBJECT + +public: + DialogPointFromCircleAndTangent(const VContainer *data, const quint32 &toolId, QWidget *parent = 0); + ~DialogPointFromCircleAndTangent(); + + void SetPointName(const QString &value); + + quint32 GetCircleCenterId() const; + void SetCircleCenterId(const quint32 &value); + + QString GetCircleRadius() const; + void SetCircleRadius(const QString &value); + + quint32 GetTangentPointId() const; + void SetTangentPointId(const quint32 &value); + + CrossCirclesPoint GetCrossCirclesPoint() const; + void SetCrossCirclesPoint(CrossCirclesPoint &p); + +public slots: + virtual void ChosenObject(quint32 id, const SceneObject &type); + void PointChanged(); + + void DeployCircleRadiusTextEdit(); + void CircleRadiusChanged(); + void FXCircleRadius(); + void EvalCircleRadius(); + +protected: + virtual void ShowVisualization(); + /** + * @brief SaveData Put dialog data in local variables + */ + virtual void SaveData(); + virtual void closeEvent(QCloseEvent *event); + virtual void CheckState(); + +private: + Q_DISABLE_COPY(DialogPointFromCircleAndTangent) + + Ui::DialogPointFromCircleAndTangent *ui; + + bool flagCircleRadius; + QTimer *timerCircleRadius; + QString circleRadius; + int formulaBaseHeightCircleRadius; + qreal angleCircleRadius; +}; + +#endif // DIALOGPOINTFROMCIRCLEANDTANGENT_H diff --git a/src/app/dialogs/tools/dialogpointfromcircleandtangent.ui b/src/app/dialogs/tools/dialogpointfromcircleandtangent.ui new file mode 100644 index 000000000..5b73f4ed7 --- /dev/null +++ b/src/app/dialogs/tools/dialogpointfromcircleandtangent.ui @@ -0,0 +1,347 @@ + + + DialogPointFromCircleAndTangent + + + + 0 + 0 + 430 + 251 + + + + + 430 + 251 + + + + + 430 + 251 + + + + Dialog + + + + + + + + + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + Radius + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + ... + + + + :/icon/24x24/fx.png:/icon/24x24/fx.png + + + + 24 + 24 + + + + + + + + + + + :/icon/24x24/equal.png + + + + + + + + 0 + 0 + + + + + 87 + 0 + + + + Value of first angle + + + _ + + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 24 + + + + true + + + + + + + + 18 + 18 + + + + + 0 + 0 + + + + <html><head/><body><p>Show full calculation in message box</p></body></html> + + + + + + + + + + + + 16 + 16 + + + + true + + + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + + 0 + 0 + + + + Point label + + + + + + + + + + + 0 + 0 + + + + Center of the circle + + + + + + + + 0 + 0 + + + + + 145 + 0 + + + + Select point of center of arc + + + + + + + + 0 + 0 + + + + Tangent point + + + + + + + + 0 + 0 + + + + + 143 + 0 + + + + + + + + Take + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + DialogPointFromCircleAndTangent + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + DialogPointFromCircleAndTangent + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/app/mainwindow.cpp b/src/app/mainwindow.cpp index 4ad200324..a2a28d5d2 100644 --- a/src/app/mainwindow.cpp +++ b/src/app/mainwindow.cpp @@ -712,7 +712,17 @@ void MainWindow::ToolPointOfIntersectionCircles(bool checked) "://cursor/point_of_intersection_circles.png", tr("Select first circle center "), &MainWindow::ClosedDialogWithApply, - &MainWindow::ApplyDialog); + &MainWindow::ApplyDialog); +} + +//--------------------------------------------------------------------------------------------------------------------- +void MainWindow::ToolPointFromCircleAndTangent(bool checked) +{ + SetToolButtonWithApply(checked, Tool::PointFromCircleAndTangent, + "://cursor/point_from_circle_and_tangent_cursor.png", + tr("Select point on tangent "), + &MainWindow::ClosedDialogWithApply, + &MainWindow::ApplyDialog); } //--------------------------------------------------------------------------------------------------------------------- @@ -1014,6 +1024,8 @@ void MainWindow::InitToolButtons() &MainWindow::ToolPointOfIntersectionArcs); connect(ui->toolButtonPointOfIntersectionCircles, &QToolButton::clicked, this, &MainWindow::ToolPointOfIntersectionCircles); + connect(ui->toolButtonPointFromCircleAndTangent, &QToolButton::clicked, this, + &MainWindow::ToolPointFromCircleAndTangent); } //--------------------------------------------------------------------------------------------------------------------- @@ -2160,6 +2172,7 @@ void MainWindow::SetEnableTool(bool enable) ui->toolButtonArcIntersectAxis->setEnabled(drawTools); ui->toolButtonPointOfIntersectionArcs->setEnabled(drawTools); ui->toolButtonPointOfIntersectionCircles->setEnabled(drawTools); + ui->toolButtonPointFromCircleAndTangent->setEnabled(drawTools); ui->actionLast_tool->setEnabled(drawTools); @@ -2526,6 +2539,10 @@ void MainWindow::LastUsedTool() ui->toolButtonPointOfIntersectionCircles->setChecked(true); ToolPointOfIntersectionCircles(true); break; + case Tool::PointFromCircleAndTangent: + ui->toolButtonPointFromCircleAndTangent->setChecked(true); + ToolPointFromCircleAndTangent(true); + break; case Tool::NodePoint: case Tool::NodeArc: case Tool::NodeSpline: diff --git a/src/app/mainwindow.h b/src/app/mainwindow.h index 89e096073..2455b8de5 100644 --- a/src/app/mainwindow.h +++ b/src/app/mainwindow.h @@ -117,6 +117,7 @@ public slots: void ToolCurveIntersectAxis(bool checked); void ToolPointOfIntersectionArcs(bool checked); void ToolPointOfIntersectionCircles(bool checked); + void ToolPointFromCircleAndTangent(bool checked); void ClosedDialogDetail(int result); void ClosedDialogUnionDetails(int result); diff --git a/src/app/mainwindow.ui b/src/app/mainwindow.ui index d2b9c5d77..e7ed1cf2f 100644 --- a/src/app/mainwindow.ui +++ b/src/app/mainwindow.ui @@ -650,7 +650,7 @@ Point intersect arc and axis - ... + ... @@ -676,7 +676,7 @@ Point of intersection arcs - ... + ... @@ -702,7 +702,7 @@ Point of intersection circles - ... + ... @@ -719,6 +719,32 @@ + + + + false + + + Point from circle and tangent + + + ... + + + + :/icon/32x32/point_from_circle_and_tangent.png:/icon/32x32/point_from_circle_and_tangent.png + + + + 32 + 32 + + + + true + + + diff --git a/src/app/options.h b/src/app/options.h index 2ff8731c7..7abc0feec 100644 --- a/src/app/options.h +++ b/src/app/options.h @@ -90,12 +90,13 @@ enum class Tool : unsigned char PointOfIntersectionCircles, CurveIntersectAxis, PointOfIntersection, - UnionDetails // 32 + PointFromCircleAndTangent, + UnionDetails // 33 }; enum class Vis : unsigned char { - ControlPointSpline = 33, // increase this value if need more positions in Tool enum + ControlPointSpline = 34, // increase this value if need more positions in Tool enum GraphicsSimpleTextItem, SimpleSplinePath, Line, @@ -113,6 +114,7 @@ enum class Vis : unsigned char ToolPointOfIntersection, ToolPointOfIntersectionArcs, ToolPointOfIntersectionCircles, + ToolPointFromCircleAndTangent, ToolShoulderPoint, ToolSpline, ToolTriangle, diff --git a/src/app/share/resources/cursor.qrc b/src/app/share/resources/cursor.qrc index b59e2c58f..442106fb8 100644 --- a/src/app/share/resources/cursor.qrc +++ b/src/app/share/resources/cursor.qrc @@ -26,5 +26,6 @@ cursor/curve_intersect_axis_cursor.png cursor/point_of_intersection_arcs.png cursor/point_of_intersection_circles.png + cursor/point_from_circle_and_tangent_cursor.png diff --git a/src/app/share/resources/cursor/point_from_circle_and_tangent_cursor.png b/src/app/share/resources/cursor/point_from_circle_and_tangent_cursor.png new file mode 100644 index 000000000..192ca051b Binary files /dev/null and b/src/app/share/resources/cursor/point_from_circle_and_tangent_cursor.png differ diff --git a/src/app/share/resources/icon.qrc b/src/app/share/resources/icon.qrc index f3ecd6276..9dde5b4e5 100644 --- a/src/app/share/resources/icon.qrc +++ b/src/app/share/resources/icon.qrc @@ -63,5 +63,6 @@ icon/32x32/export_to_picture_document.png icon/32x32/point_of_intersection_arcs.png icon/32x32/point_of_intersection_circles.png + icon/32x32/point_from_circle_and_tangent.png diff --git a/src/app/share/resources/icon/32x32/point_from_circle_and_tangent.png b/src/app/share/resources/icon/32x32/point_from_circle_and_tangent.png new file mode 100644 index 000000000..86ea54a9c Binary files /dev/null and b/src/app/share/resources/icon/32x32/point_from_circle_and_tangent.png differ diff --git a/src/app/share/resources/icon/svg/point_from_circle_and_tangent.svg b/src/app/share/resources/icon/svg/point_from_circle_and_tangent.svg new file mode 100644 index 000000000..40c944226 --- /dev/null +++ b/src/app/share/resources/icon/svg/point_from_circle_and_tangent.svg @@ -0,0 +1,95 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/src/app/tools/drawTools/drawtools.h b/src/app/tools/drawTools/drawtools.h index 4134de51a..ab8766669 100644 --- a/src/app/tools/drawTools/drawtools.h +++ b/src/app/tools/drawTools/drawtools.h @@ -51,5 +51,6 @@ #include "vtoolcutarc.h" #include "vtoollineintersectaxis.h" #include "vtoolcurveintersectaxis.h" +#include "vtoolpointfromcircleandtangent.h" #endif // DRAWTOOLS_H diff --git a/src/app/tools/drawTools/vtoolpointfromcircleandtangent.cpp b/src/app/tools/drawTools/vtoolpointfromcircleandtangent.cpp new file mode 100644 index 000000000..0e9673489 --- /dev/null +++ b/src/app/tools/drawTools/vtoolpointfromcircleandtangent.cpp @@ -0,0 +1,305 @@ +/************************************************************************ + ** + ** @file vtoolpointfromcircleandtangent.cpp + ** @author Roman Telezhynskyi + ** @date 3 6, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include "vtoolpointfromcircleandtangent.h" +#include "../../dialogs/tools/dialogpointfromcircleandtangent.h" +#include "../../libs/vgeometry/vpointf.h" +#include "../../libs/vgeometry/varc.h" +#include "../../visualization/vistoolpointfromcircleandtangent.h" +#include "../container/vformula.h" + +const QString VToolPointFromCircleAndTangent::ToolType = QStringLiteral("pointFromCircleAndTangent"); + +//--------------------------------------------------------------------------------------------------------------------- +VToolPointFromCircleAndTangent::VToolPointFromCircleAndTangent(VPattern *doc, VContainer *data, const quint32 &id, + quint32 circleCenterId, const QString &circleRadius, + quint32 tangentPointId, CrossCirclesPoint crossPoint, + const Source &typeCreation, QGraphicsItem *parent) + :VToolPoint(doc, data, id, parent), circleCenterId(circleCenterId), tangentPointId(tangentPointId), + circleRadius(circleRadius), crossPoint(crossPoint) +{ + ToolCreation(typeCreation); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPointFromCircleAndTangent::setDialog() +{ + SCASSERT(dialog != nullptr); + DialogPointFromCircleAndTangent *dialogTool = qobject_cast(dialog); + SCASSERT(dialogTool != nullptr); + const QSharedPointer p = VAbstractTool::data.GeometricObject(id); + dialogTool->SetCircleCenterId(circleCenterId); + dialogTool->SetCircleRadius(circleRadius); + dialogTool->SetCrossCirclesPoint(crossPoint); + dialogTool->SetPointName(p->name()); +} + +//--------------------------------------------------------------------------------------------------------------------- +VToolPointFromCircleAndTangent *VToolPointFromCircleAndTangent::Create(DialogTool *dialog, VMainGraphicsScene *scene, + VPattern *doc, VContainer *data) +{ + SCASSERT(dialog != nullptr); + DialogPointFromCircleAndTangent *dialogTool = qobject_cast(dialog); + SCASSERT(dialogTool != nullptr); + const quint32 circleCenterId = dialogTool->GetCircleCenterId(); + QString circleRadius = dialogTool->GetCircleRadius(); + const quint32 tangentPointId = dialogTool->GetTangentPointId(); + const CrossCirclesPoint pType = dialogTool->GetCrossCirclesPoint(); + const QString pointName = dialogTool->getPointName(); + VToolPointFromCircleAndTangent *point = nullptr; + point = Create(0, pointName, circleCenterId, circleRadius, tangentPointId, pType, 5, 10, scene, doc, data, + Document::FullParse, Source::FromGui); + if (point != nullptr) + { + point->dialog=dialogTool; + } + return point; +} + +//--------------------------------------------------------------------------------------------------------------------- +VToolPointFromCircleAndTangent *VToolPointFromCircleAndTangent::Create(const quint32 _id, const QString &pointName, + quint32 circleCenterId, QString &circleRadius, + quint32 tangentPointId, + CrossCirclesPoint crossPoint, const qreal &mx, + const qreal &my, VMainGraphicsScene *scene, + VPattern *doc, VContainer *data, + const Document &parse, + const Source &typeCreation) +{ + const qreal radius = qApp->toPixel(CheckFormula(_id, circleRadius, data)); + const VPointF cPoint = *data->GeometricObject(circleCenterId); + const VPointF tPoint = *data->GeometricObject(tangentPointId); + + const QPointF point = VToolPointFromCircleAndTangent::FindPoint(tPoint.toQPointF(), cPoint.toQPointF(), radius, + crossPoint); + quint32 id = _id; + if (typeCreation == Source::FromGui) + { + id = data->AddGObject(new VPointF(point, pointName, mx, my)); + } + else + { + data->UpdateGObject(id, new VPointF(point, pointName, mx, my)); + if (parse != Document::FullParse) + { + doc->UpdateToolData(id, data); + } + } + VDrawTool::AddRecord(id, Tool::PointOfIntersectionCircles, doc); + if (parse == Document::FullParse) + { + VToolPointFromCircleAndTangent *point = new VToolPointFromCircleAndTangent(doc, data, id, circleCenterId, + circleRadius, tangentPointId, + crossPoint, typeCreation); + scene->addItem(point); + connect(point, &VToolPointFromCircleAndTangent::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem); + connect(scene, &VMainGraphicsScene::NewFactor, point, &VToolPointFromCircleAndTangent::SetFactor); + connect(scene, &VMainGraphicsScene::DisableItem, point, &VToolPointFromCircleAndTangent::Disable); + connect(scene, &VMainGraphicsScene::EnableToolMove, point, &VToolPointFromCircleAndTangent::EnableToolMove); + doc->AddTool(id, point); + doc->IncrementReferens(circleCenterId); + doc->IncrementReferens(tangentPointId); + return point; + } + return nullptr; +} + +//--------------------------------------------------------------------------------------------------------------------- +QPointF VToolPointFromCircleAndTangent::FindPoint(const QPointF &p, const QPointF ¢er, qreal radius, + const CrossCirclesPoint crossPoint) +{ + QPointF p1, p2; + const int res = VGObject::ContactPoints (p, center, radius, p1, p2); + + switch(res) + { + case 2: + if (crossPoint == CrossCirclesPoint::FirstPoint) + { + return p1; + } + else + { + return p2; + } + break; + case 1: + return p1; + break; + case 3: + case 0: + default: + return QPointF(0, 0); + break; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 VToolPointFromCircleAndTangent::GetTangentPointId() const +{ + return tangentPointId; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPointFromCircleAndTangent::SetTangentPointId(const quint32 &value) +{ + if (value != NULL_ID) + { + tangentPointId = value; + + QSharedPointer obj = VAbstractTool::data.GetGObject(id); + SaveOption(obj); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +quint32 VToolPointFromCircleAndTangent::GetCircleCenterId() const +{ + return circleCenterId; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPointFromCircleAndTangent::SetCircleCenterId(const quint32 &value) +{ + if (value != NULL_ID) + { + circleCenterId = value; + + QSharedPointer obj = VAbstractTool::data.GetGObject(id); + SaveOption(obj); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +VFormula VToolPointFromCircleAndTangent::GetCircleRadius() const +{ + VFormula radius(circleRadius, getData()); + radius.setCheckZero(true); + radius.setToolId(id); + radius.setPostfix(VDomDocument::UnitsToStr(qApp->patternUnit())); + return radius; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPointFromCircleAndTangent::SetCircleRadius(const VFormula &value) +{ + if (value.error() == false) + { + if (value.getDoubleValue() > 0)// Formula don't check this, but radius can't be 0 or negative + { + circleRadius = value.GetFormula(FormulaType::FromUser); + QSharedPointer obj = VAbstractTool::data.GetGObject(id); + SaveOption(obj); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +CrossCirclesPoint VToolPointFromCircleAndTangent::GetCrossCirclesPoint() const +{ + return crossPoint; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPointFromCircleAndTangent::SetCrossCirclesPoint(CrossCirclesPoint &value) +{ + crossPoint = value; + + QSharedPointer obj = VAbstractTool::data.GetGObject(id); + SaveOption(obj); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPointFromCircleAndTangent::ShowVisualization(bool show) +{ + ShowToolVisualization(show); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPointFromCircleAndTangent::RemoveReferens() +{ + doc->DecrementReferens(circleCenterId); + doc->DecrementReferens(tangentPointId); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPointFromCircleAndTangent::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) +{ + ContextMenu(this, event); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPointFromCircleAndTangent::SaveDialog(QDomElement &domElement) +{ + SCASSERT(dialog != nullptr); + DialogPointFromCircleAndTangent *dialogTool = qobject_cast(dialog); + SCASSERT(dialogTool != nullptr); + doc->SetAttribute(domElement, AttrName, dialogTool->getPointName()); + doc->SetAttribute(domElement, AttrCCenter, QString().setNum(dialogTool->GetCircleCenterId())); + doc->SetAttribute(domElement, AttrTangent, QString().setNum(dialogTool->GetTangentPointId())); + doc->SetAttribute(domElement, AttrCRadius, dialogTool->GetCircleRadius()); + doc->SetAttribute(domElement, AttrCrossPoint, + QString().setNum(static_cast(dialogTool->GetCrossCirclesPoint()))); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPointFromCircleAndTangent::SaveOptions(QDomElement &tag, QSharedPointer &obj) +{ + VToolPoint::SaveOptions(tag, obj); + + doc->SetAttribute(tag, AttrType, ToolType); + doc->SetAttribute(tag, AttrCCenter, circleCenterId); + doc->SetAttribute(tag, AttrTangent, tangentPointId); + doc->SetAttribute(tag, AttrCRadius, circleRadius); + doc->SetAttribute(tag, AttrCrossPoint, static_cast(crossPoint)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPointFromCircleAndTangent::ReadToolAttributes(const QDomElement &domElement) +{ + circleCenterId = doc->GetParametrUInt(domElement, AttrCCenter, NULL_ID_STR); + tangentPointId = doc->GetParametrUInt(domElement, AttrTangent, NULL_ID_STR); + circleRadius = doc->GetParametrString(domElement, AttrCRadius); + crossPoint = static_cast(doc->GetParametrUInt(domElement, AttrCrossPoint, "1")); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolPointFromCircleAndTangent::SetVisualization() +{ + if (vis != nullptr) + { + VisToolPointFromCircleAndTangent *visual = qobject_cast(vis); + SCASSERT(visual != nullptr); + + visual->setPoint1Id(tangentPointId); + visual->setPoint2Id(circleCenterId); + visual->setCRadius(circleRadius); + visual->setCrossPoint(crossPoint); + visual->RefreshGeometry(); + } +} diff --git a/src/app/tools/drawTools/vtoolpointfromcircleandtangent.h b/src/app/tools/drawTools/vtoolpointfromcircleandtangent.h new file mode 100644 index 000000000..7e084f1a8 --- /dev/null +++ b/src/app/tools/drawTools/vtoolpointfromcircleandtangent.h @@ -0,0 +1,86 @@ +/************************************************************************ + ** + ** @file vtoolpointfromcircleandtangent.h + ** @author Roman Telezhynskyi + ** @date 3 6, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef VTOOLPOINTFROMCIRCLEANDTANGENT_H +#define VTOOLPOINTFROMCIRCLEANDTANGENT_H + +#include "vtoolpoint.h" +#include "../../xml/vpattern.h" + +class VFormula; + +class VToolPointFromCircleAndTangent : public VToolPoint +{ + Q_OBJECT +public: + VToolPointFromCircleAndTangent(VPattern *doc, VContainer *data, const quint32 &id, quint32 circleCenterId, + const QString &circleRadius, quint32 tangentPointId, CrossCirclesPoint crossPoint, + const Source &typeCreation, QGraphicsItem * parent = nullptr); + virtual void setDialog(); + static VToolPointFromCircleAndTangent *Create(DialogTool *dialog, VMainGraphicsScene *scene, VPattern *doc, + VContainer *data); + static VToolPointFromCircleAndTangent *Create(const quint32 _id, const QString &pointName, + quint32 circleCenterId, QString &circleRadius, quint32 tangentPointId, + CrossCirclesPoint crossPoint, const qreal &mx, const qreal &my, + VMainGraphicsScene *scene, VPattern *doc, VContainer *data, + const Document &parse, const Source &typeCreation); + static QPointF FindPoint(const QPointF &p, const QPointF ¢er, qreal radius, const CrossCirclesPoint crossPoint); + static const QString ToolType; + virtual int type() const {return Type;} + enum { Type = UserType + static_cast(Tool::PointFromCircleAndTangent) }; + + quint32 GetTangentPointId() const; + void SetTangentPointId(const quint32 &value); + + quint32 GetCircleCenterId() const; + void SetCircleCenterId(const quint32 &value); + + VFormula GetCircleRadius() const; + void SetCircleRadius(const VFormula &value); + + CrossCirclesPoint GetCrossCirclesPoint() const; + void SetCrossCirclesPoint(CrossCirclesPoint &value); + + virtual void ShowVisualization(bool show); +protected: + virtual void RemoveReferens(); + virtual void contextMenuEvent ( QGraphicsSceneContextMenuEvent * event ); + virtual void SaveDialog(QDomElement &domElement); + virtual void SaveOptions(QDomElement &tag, QSharedPointer &obj); + virtual void ReadToolAttributes(const QDomElement &domElement); + virtual void SetVisualization(); +private: + Q_DISABLE_COPY(VToolPointFromCircleAndTangent) + + quint32 circleCenterId; + quint32 tangentPointId; + QString circleRadius; + CrossCirclesPoint crossPoint; +}; + +#endif // VTOOLPOINTFROMCIRCLEANDTANGENT_H diff --git a/src/app/tools/tools.pri b/src/app/tools/tools.pri index e12a29f1a..fc6c4a542 100644 --- a/src/app/tools/tools.pri +++ b/src/app/tools/tools.pri @@ -40,7 +40,8 @@ HEADERS += \ $$PWD/drawTools/vtoollineintersectaxis.h \ $$PWD/drawTools/vtoolcurveintersectaxis.h \ $$PWD/drawTools/vtoolpointofintersectionarcs.h \ - $$PWD/drawTools/vtoolpointofintersectioncircles.h + $$PWD/drawTools/vtoolpointofintersectioncircles.h \ + $$PWD/drawTools/vtoolpointfromcircleandtangent.h SOURCES += \ $$PWD/vtooldetail.cpp \ @@ -78,4 +79,5 @@ SOURCES += \ $$PWD/drawTools/vtoollineintersectaxis.cpp \ $$PWD/drawTools/vtoolcurveintersectaxis.cpp \ $$PWD/drawTools/vtoolpointofintersectionarcs.cpp \ - $$PWD/drawTools/vtoolpointofintersectioncircles.cpp + $$PWD/drawTools/vtoolpointofintersectioncircles.cpp \ + $$PWD/drawTools/vtoolpointfromcircleandtangent.cpp diff --git a/src/app/tools/vabstracttool.cpp b/src/app/tools/vabstracttool.cpp index f58a6bf24..4b6c73336 100644 --- a/src/app/tools/vabstracttool.cpp +++ b/src/app/tools/vabstracttool.cpp @@ -83,6 +83,9 @@ const QString VAbstractTool::AttrC1Center = QStringLiteral("c1Center"); const QString VAbstractTool::AttrC2Center = QStringLiteral("c2Center"); const QString VAbstractTool::AttrC1Radius = QStringLiteral("c1Radius"); const QString VAbstractTool::AttrC2Radius = QStringLiteral("c2Radius"); +const QString VAbstractTool::AttrCCenter = QStringLiteral("cCenter"); +const QString VAbstractTool::AttrTangent = QStringLiteral("tangent"); +const QString VAbstractTool::AttrCRadius = QStringLiteral("cRadius"); const QString VAbstractTool::TypeLineNone = QStringLiteral("none"); const QString VAbstractTool::TypeLineLine = QStringLiteral("hair"); diff --git a/src/app/tools/vabstracttool.h b/src/app/tools/vabstracttool.h index 1ff441f4d..46c17cf1a 100644 --- a/src/app/tools/vabstracttool.h +++ b/src/app/tools/vabstracttool.h @@ -98,6 +98,9 @@ public: static const QString AttrC2Center; static const QString AttrC1Radius; static const QString AttrC2Radius; + static const QString AttrCCenter; + static const QString AttrTangent; + static const QString AttrCRadius; static const QString TypeLineNone; static const QString TypeLineLine; diff --git a/src/app/visualization/visline.cpp b/src/app/visualization/visline.cpp index 6c8424784..82009a6e4 100644 --- a/src/app/visualization/visline.cpp +++ b/src/app/visualization/visline.cpp @@ -128,3 +128,15 @@ void VisLine::AddOnScene() { AddItem(this); } + +//--------------------------------------------------------------------------------------------------------------------- +void VisLine::DrawRay(QGraphicsLineItem *lineItem, const QPointF &p, const QPointF &pTangent, const QColor &color, + Qt::PenStyle style) +{ + SCASSERT (lineItem != nullptr); + + const qreal angle = QLineF(p, pTangent).angle(); + const QPointF endRay = Ray(p, angle); + const QLineF tangent = VGObject::BuildLine(p, QLineF(p, endRay).length(), angle); + DrawLine(lineItem, tangent, color, style); +} diff --git a/src/app/visualization/visline.h b/src/app/visualization/visline.h index dfad23120..b657cd84e 100644 --- a/src/app/visualization/visline.h +++ b/src/app/visualization/visline.h @@ -52,6 +52,9 @@ protected: QLineF Axis(const QPointF &p1, const QPointF &p2) const; virtual void InitPen(); virtual void AddOnScene(); + + void DrawRay(QGraphicsLineItem *lineItem, const QPointF &p, const QPointF &pTangent, + const QColor &color, Qt::PenStyle style); private: Q_DISABLE_COPY(VisLine) }; diff --git a/src/app/visualization/vistoolpointfromcircleandtangent.cpp b/src/app/visualization/vistoolpointfromcircleandtangent.cpp new file mode 100644 index 000000000..3164f9874 --- /dev/null +++ b/src/app/visualization/vistoolpointfromcircleandtangent.cpp @@ -0,0 +1,117 @@ +/************************************************************************ + ** + ** @file vistoolpointfromcircleandtangent.cpp + ** @author Roman Telezhynskyi + ** @date 5 6, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include "vistoolpointfromcircleandtangent.h" +#include "../container/vcontainer.h" +#include "../tools/drawTools/vtoolpointfromcircleandtangent.h" +#include "../libs/vgeometry/vpointf.h" + +//--------------------------------------------------------------------------------------------------------------------- +VisToolPointFromCircleAndTangent::VisToolPointFromCircleAndTangent(const VContainer *data, QGraphicsItem *parent) + : VisLine(data, parent), point2Id(NULL_ID), cRadius(0), crossPoint(CrossCirclesPoint::FirstPoint), + point(nullptr), tangent(nullptr), cCenter(nullptr), cPath(nullptr), tangent2(nullptr) +{ + cPath = InitItem(Qt::darkGreen, this); + point = InitPoint(mainColor, this); + tangent = InitPoint(supportColor, this); + cCenter = InitPoint(supportColor, this); + tangent2 = InitItem(supportColor, this); +} + +//--------------------------------------------------------------------------------------------------------------------- +VisToolPointFromCircleAndTangent::~VisToolPointFromCircleAndTangent() +{} + +//--------------------------------------------------------------------------------------------------------------------- +void VisToolPointFromCircleAndTangent::RefreshGeometry() +{ + if (point1Id > NULL_ID)// tangent point + { + const QSharedPointer tan = Visualization::data->GeometricObject(point1Id); + DrawPoint(tangent, tan->toQPointF(), supportColor); + + if (point2Id > NULL_ID)// circle center + { + const QSharedPointer center = Visualization::data->GeometricObject(point2Id); + DrawPoint(cCenter, center->toQPointF(), supportColor); + + if (cRadius > 0) + { + cPath->setRect(PointRect(cRadius)); + DrawPoint(cPath, center->toQPointF(), Qt::darkGreen, Qt::DashLine); + + FindRays(tan->toQPointF(), center->toQPointF(), cRadius); + + const QPointF fPoint = VToolPointFromCircleAndTangent::FindPoint(tan->toQPointF(), center->toQPointF(), + cRadius, crossPoint); + DrawPoint(point, fPoint, mainColor); + } + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VisToolPointFromCircleAndTangent::setPoint2Id(const quint32 &value) +{ + point2Id = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VisToolPointFromCircleAndTangent::setCRadius(const QString &value) +{ + cRadius = FindLength(value); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VisToolPointFromCircleAndTangent::setCrossPoint(const CrossCirclesPoint &value) +{ + crossPoint = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VisToolPointFromCircleAndTangent::FindRays(const QPointF &p, const QPointF ¢er, qreal radius) +{ + QPointF p1, p2; + const int res = VGObject::ContactPoints (p, center, radius, p1, p2); + + switch(res) + { + case 2: + DrawRay(this, p, p1, supportColor, Qt::DashLine); + DrawRay(tangent2, p, p2, supportColor, Qt::DashLine); + break; + case 1: + DrawRay(this, p, p1, supportColor, Qt::DashLine); + tangent2->setVisible(false); + break; + default: + this->setVisible(false); + tangent2->setVisible(false); + break; + } +} diff --git a/src/app/visualization/vistoolpointfromcircleandtangent.h b/src/app/visualization/vistoolpointfromcircleandtangent.h new file mode 100644 index 000000000..995bbf329 --- /dev/null +++ b/src/app/visualization/vistoolpointfromcircleandtangent.h @@ -0,0 +1,64 @@ +/************************************************************************ + ** + ** @file vistoolpointfromcircleandtangent.h + ** @author Roman Telezhynskyi + ** @date 5 6, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef VISTOOLPOINTFROMCIRCLEANDTANGENT_H +#define VISTOOLPOINTFROMCIRCLEANDTANGENT_H + +#include "visline.h" +#include "../xml/vpattern.h" + +class VisToolPointFromCircleAndTangent : public VisLine +{ + Q_OBJECT +public: + VisToolPointFromCircleAndTangent(const VContainer *data, QGraphicsItem *parent = 0); + virtual ~VisToolPointFromCircleAndTangent(); + + virtual void RefreshGeometry(); + + void setPoint2Id(const quint32 &value); + void setCRadius(const QString &value); + void setCrossPoint(const CrossCirclesPoint &value); + + virtual int type() const {return Type;} + enum { Type = UserType + static_cast(Vis::ToolPointFromCircleAndTangent)}; +private: + Q_DISABLE_COPY(VisToolPointFromCircleAndTangent) + quint32 point2Id; + qreal cRadius; + CrossCirclesPoint crossPoint; + QGraphicsEllipseItem *point; + QGraphicsEllipseItem *tangent; + QGraphicsEllipseItem *cCenter; + QGraphicsEllipseItem *cPath; + QGraphicsLineItem *tangent2; + + void FindRays(const QPointF &p, const QPointF ¢er, qreal radius); +}; + +#endif // VISTOOLPOINTFROMCIRCLEANDTANGENT_H diff --git a/src/app/visualization/visualization.pri b/src/app/visualization/visualization.pri index b520fb476..ec1876e2e 100644 --- a/src/app/visualization/visualization.pri +++ b/src/app/visualization/visualization.pri @@ -28,7 +28,8 @@ HEADERS += \ $$PWD/vistoollineintersectaxis.h \ $$PWD/vistoolcurveintersectaxis.h \ $$PWD/vistoolpointofintersectionarcs.h \ - visualization/vistoolpointofintersectioncircles.h + $$PWD/vistoolpointofintersectioncircles.h \ + $$PWD/vistoolpointfromcircleandtangent.h SOURCES += \ $$PWD/vgraphicssimpletextitem.cpp \ @@ -57,4 +58,5 @@ SOURCES += \ $$PWD/vistoollineintersectaxis.cpp \ $$PWD/vistoolcurveintersectaxis.cpp \ $$PWD/vistoolpointofintersectionarcs.cpp \ - visualization/vistoolpointofintersectioncircles.cpp + $$PWD/vistoolpointofintersectioncircles.cpp \ + $$PWD/vistoolpointfromcircleandtangent.cpp diff --git a/src/app/widgets/vtooloptionspropertybrowser.cpp b/src/app/widgets/vtooloptionspropertybrowser.cpp index 9fb089d98..7f5e93647 100644 --- a/src/app/widgets/vtooloptionspropertybrowser.cpp +++ b/src/app/widgets/vtooloptionspropertybrowser.cpp @@ -152,6 +152,9 @@ void VToolOptionsPropertyBrowser::ShowItemOptions(QGraphicsItem *item) case VToolCurveIntersectAxis::Type: ShowOptionsToolCurveIntersectAxis(item); break; + case VToolPointFromCircleAndTangent::Type: + ShowOptionsToolPointFromCircleAndTangent(item); + break; default: break; } @@ -239,6 +242,9 @@ void VToolOptionsPropertyBrowser::UpdateOptions() case VToolCurveIntersectAxis::Type: UpdateOptionsToolCurveIntersectAxis(); break; + case VToolPointFromCircleAndTangent::Type: + UpdateOptionsToolPointFromCircleAndTangent(); + break; default: break; } @@ -341,6 +347,9 @@ void VToolOptionsPropertyBrowser::userChangedData(VProperty *property) case VToolCurveIntersectAxis::Type: ChangeDataToolCurveIntersectAxis(prop); break; + case VToolPointFromCircleAndTangent::Type: + ChangeDataToolPointFromCircleAndTangent(prop); + break; default: break; } @@ -897,8 +906,6 @@ void VToolOptionsPropertyBrowser::ChangeDataToolPointOfIntersectionArcs(VPropert const QVariant value = property->data(VProperty::DPC_Data, Qt::DisplayRole); const QString id = propertyToId[property]; - VToolPointOfIntersectionArcs *i = qgraphicsitem_cast(currentItem); - SCASSERT(i != nullptr); switch (PropertiesList().indexOf(id)) { case 0: // VAbstractTool::AttrName @@ -949,6 +956,36 @@ void VToolOptionsPropertyBrowser::ChangeDataToolPointOfIntersectionCircles(VProp } } +//--------------------------------------------------------------------------------------------------------------------- +void VToolOptionsPropertyBrowser::ChangeDataToolPointFromCircleAndTangent(VProperty *property) +{ + SCASSERT(property != nullptr) + + const QVariant value = property->data(VProperty::DPC_Data, Qt::DisplayRole); + const QString id = propertyToId[property]; + + VToolPointFromCircleAndTangent *i = qgraphicsitem_cast(currentItem); + SCASSERT(i != nullptr); + switch (PropertiesList().indexOf(id)) + { + case 0: // VAbstractTool::AttrName + SetPointName(value.toString()); + break; + case 31: // VAbstractTool::AttrCRadius + i->SetCircleRadius(value.value()); + break; + case 28: // VAbstractTool::AttrCrossPoint + { + const QVariant value = property->data(VProperty::DPC_Data, Qt::EditRole); + SetCrossCirclesPoint(value); + break; + } + default: + qWarning()<<"Unknown property type. id = "<(item); + i->ShowVisualization(true); + formView->setTitle(tr("Tool to make point from circle and tangent")); + + AddPropertyPointName(i, tr("Point label")); + AddPropertyFormula(tr("Circle radius"), i->GetCircleRadius(), VAbstractTool::AttrCRadius); + AddPropertyCrossPoint(i, tr("Take")); +} + //--------------------------------------------------------------------------------------------------------------------- void VToolOptionsPropertyBrowser::ShowOptionsToolShoulderPoint(QGraphicsItem *item) { @@ -1657,6 +1706,19 @@ void VToolOptionsPropertyBrowser::UpdateOptionsToolPointOfIntersectionCircles() idToProperty[VAbstractTool::AttrC2Radius]->setValue(c2Radius); } +//--------------------------------------------------------------------------------------------------------------------- +void VToolOptionsPropertyBrowser::UpdateOptionsToolPointFromCircleAndTangent() +{ + VToolPointFromCircleAndTangent *i = qgraphicsitem_cast(currentItem); + + idToProperty[VAbstractTool::AttrName]->setValue(i->name()); + idToProperty[VAbstractTool::AttrCrossPoint]->setValue(static_cast(i->GetCrossCirclesPoint())-1); + + QVariant cRadius; + cRadius.setValue(i->GetCircleRadius()); + idToProperty[VAbstractTool::AttrCRadius]->setValue(cRadius); +} + //--------------------------------------------------------------------------------------------------------------------- void VToolOptionsPropertyBrowser::UpdateOptionsToolShoulderPoint() { @@ -1786,6 +1848,7 @@ QStringList VToolOptionsPropertyBrowser::PropertiesList() const << VAbstractTool::AttrColor /* 27 */ << VAbstractTool::AttrCrossPoint /* 28 */ << VAbstractTool::AttrC1Radius /* 29 */ - << VAbstractTool::AttrC2Radius; /* 30 */ + << VAbstractTool::AttrC2Radius /* 30 */ + << VAbstractTool::AttrCRadius; /* 31 */ return attr; } diff --git a/src/app/widgets/vtooloptionspropertybrowser.h b/src/app/widgets/vtooloptionspropertybrowser.h index 32854778b..b78842558 100644 --- a/src/app/widgets/vtooloptionspropertybrowser.h +++ b/src/app/widgets/vtooloptionspropertybrowser.h @@ -104,6 +104,7 @@ private: void ChangeDataToolPointOfIntersection(VPE::VProperty *property); void ChangeDataToolPointOfIntersectionArcs(VPE::VProperty *property); void ChangeDataToolPointOfIntersectionCircles(VPE::VProperty *property); + void ChangeDataToolPointFromCircleAndTangent(VPE::VProperty *property); void ChangeDataToolShoulderPoint(VPE::VProperty *property); void ChangeDataToolSpline(VPE::VProperty *property); void ChangeDataToolSplinePath(VPE::VProperty *property); @@ -127,6 +128,7 @@ private: void ShowOptionsToolPointOfIntersection(QGraphicsItem *item); void ShowOptionsToolPointOfIntersectionArcs(QGraphicsItem *item); void ShowOptionsToolPointOfIntersectionCircles(QGraphicsItem *item); + void ShowOptionsToolPointFromCircleAndTangent(QGraphicsItem *item); void ShowOptionsToolShoulderPoint(QGraphicsItem *item); void ShowOptionsToolSpline(QGraphicsItem *item); void ShowOptionsToolSplinePath(QGraphicsItem *item); @@ -150,6 +152,7 @@ private: void UpdateOptionsToolPointOfIntersection(); void UpdateOptionsToolPointOfIntersectionArcs(); void UpdateOptionsToolPointOfIntersectionCircles(); + void UpdateOptionsToolPointFromCircleAndTangent(); void UpdateOptionsToolShoulderPoint(); void UpdateOptionsToolSpline(); void UpdateOptionsToolSplinePath(); diff --git a/src/app/xml/vpattern.cpp b/src/app/xml/vpattern.cpp index f124a8fab..4517301e1 100644 --- a/src/app/xml/vpattern.cpp +++ b/src/app/xml/vpattern.cpp @@ -1144,7 +1144,8 @@ void VPattern::ParsePointElement(VMainGraphicsScene *scene, QDomElement &domElem << VToolCutSplinePath::ToolType << VToolCutArc::ToolType << VToolLineIntersectAxis::ToolType << VToolCurveIntersectAxis::ToolType << VToolPointOfIntersectionArcs::ToolType - << VToolPointOfIntersectionCircles::ToolType; + << VToolPointOfIntersectionCircles::ToolType + << VToolPointFromCircleAndTangent::ToolType; switch (points.indexOf(type)) { case 0: //VToolSinglePoint::ToolType @@ -1686,6 +1687,34 @@ void VPattern::ParsePointElement(VMainGraphicsScene *scene, QDomElement &domElem throw excep; } break; + case 19: //VToolPointFromCircleAndTangent::ToolType + try + { + PointsCommonAttributes(domElement, id, name, mx, my); + const quint32 cCenterId = GetParametrUInt(domElement, VAbstractTool::AttrCCenter, NULL_ID_STR); + const quint32 tangentId = GetParametrUInt(domElement, VAbstractTool::AttrTangent, NULL_ID_STR); + const QString cRadius = GetParametrString(domElement, VAbstractTool::AttrCRadius); + QString cR = cRadius; + const CrossCirclesPoint crossPoint = static_cast(GetParametrUInt(domElement, + VAbstractTool::AttrCrossPoint, + "1")); + + VToolPointFromCircleAndTangent::Create(id, name, cCenterId, cR, tangentId, crossPoint, mx, my, + scene, this, data, parse, Source::FromFile); + //Rewrite attribute formula. Need for situation when we have wrong formula. + if (cR != cRadius) + { + SetAttribute(domElement, VAbstractTool::AttrCCenter, cR); + haveLiteChange(); + } + } + catch (const VExceptionBadId &e) + { + VExceptionObjectError excep(tr("Error creating or updating point from circle and tangent"), domElement); + excep.AddMoreInformation(e.ErrorMessage()); + throw excep; + } + break; default: qDebug() << "Illegal point type in VDomDocument::ParsePointElement()."; break; diff --git a/src/libs/ifc/schema/pattern/v0.1.4.xsd b/src/libs/ifc/schema/pattern/v0.1.4.xsd index c73b2fe63..e6acac940 100644 --- a/src/libs/ifc/schema/pattern/v0.1.4.xsd +++ b/src/libs/ifc/schema/pattern/v0.1.4.xsd @@ -130,6 +130,9 @@ + + + diff --git a/src/libs/vgeometry/vgobject.cpp b/src/libs/vgeometry/vgobject.cpp index c0000900b..5f3c71653 100644 --- a/src/libs/vgeometry/vgobject.cpp +++ b/src/libs/vgeometry/vgobject.cpp @@ -225,6 +225,27 @@ QLineF VGObject::BuildAxis(const QPointF &p1, const QPointF &p2, const QRectF &s return BuildAxis(p1, line.angle(), scRect); } +//--------------------------------------------------------------------------------------------------------------------- +int VGObject::ContactPoints(const QPointF &p, const QPointF ¢er, qreal radius, QPointF &p1, QPointF &p2) +{ + const int flag = PointInCircle(p, center, radius); + + if (flag == 0) + { + return 0; + } + + if (flag == 1) + { + p1 = p; + return 1; + } + + const double d = QLineF (p, center).length(); + const double k = sqrt (d * d - radius * radius); + return IntersectionCircles(p, k, center, radius, p1, p2); +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief LineIntersectRect find point intersection line and rect. @@ -455,6 +476,21 @@ double VGObject::GetEpsilon(const QPointF &p1, const QPointF &p2) return epsilon; } +//--------------------------------------------------------------------------------------------------------------------- +int VGObject::PointInCircle(const QPointF &p, const QPointF ¢er, qreal radius) +{ + const double d = QLineF (p, center).length(); + if (qFuzzyCompare(radius, d)) + { + return 1; // on circle + } + if (radius > d) + { + return 0; // outside circle + } + return 2; // inside circle +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief GetReversePoint return revers container of points. diff --git a/src/libs/vgeometry/vgobject.h b/src/libs/vgeometry/vgobject.h index de8075a76..679cd54a2 100644 --- a/src/libs/vgeometry/vgobject.h +++ b/src/libs/vgeometry/vgobject.h @@ -72,6 +72,7 @@ public: static QLineF BuildAxis(const QPointF &p, const qreal &angle, const QRectF &scRect); static QLineF BuildAxis(const QPointF &p1, const QPointF &p2, const QRectF &scRect); + static int ContactPoints (const QPointF &p, const QPointF ¢er, qreal radius, QPointF &p1, QPointF &p2); static QPointF LineIntersectRect(const QRectF &rec, const QLineF &line); static int IntersectionCircles(const QPointF &c1, double r1, const QPointF &c2, double r2, QPointF &p1, QPointF &p2); @@ -90,6 +91,8 @@ private: static bool IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QPointF &p2); static double PerpDotProduct(const QPointF &t, const QPointF &p1, const QPointF &p2); static double GetEpsilon(const QPointF &p1, const QPointF &p2); + + static int PointInCircle (const QPointF &p, const QPointF ¢er, qreal radius); }; #endif // VGOBJECT_H