Add tool spline
This commit is contained in:
parent
066432c980
commit
45856338f9
|
@ -15,7 +15,6 @@ SOURCES += main.cpp\
|
|||
mainwindow.cpp \
|
||||
widgets/vmaingraphicsscene.cpp \
|
||||
dialogs/dialogsinglepoint.cpp \
|
||||
tools/vtoolsimplepoint.cpp \
|
||||
widgets/vgraphicssimpletextitem.cpp \
|
||||
xml/vdomdocument.cpp \
|
||||
container/vpointf.cpp \
|
||||
|
@ -43,13 +42,18 @@ SOURCES += main.cpp\
|
|||
dialogs/dialogbisector.cpp \
|
||||
tools/vtoollinepoint.cpp \
|
||||
tools/vtoollineintersect.cpp \
|
||||
dialogs/dialoglineintersect.cpp
|
||||
dialogs/dialoglineintersect.cpp \
|
||||
geometry/vspline.cpp \
|
||||
tools/vtoolsinglepoint.cpp \
|
||||
geometry/varc.cpp \
|
||||
widgets/vcontrolpointspline.cpp \
|
||||
tools/vtoolspline.cpp \
|
||||
dialogs/dialogspline.cpp
|
||||
|
||||
HEADERS += mainwindow.h \
|
||||
widgets/vmaingraphicsscene.h \
|
||||
dialogs/dialogsinglepoint.h \
|
||||
options.h \
|
||||
tools/vtoolsimplepoint.h \
|
||||
widgets/vgraphicssimpletextitem.h \
|
||||
xml/vdomdocument.h \
|
||||
container/vpointf.h \
|
||||
|
@ -77,7 +81,13 @@ HEADERS += mainwindow.h \
|
|||
dialogs/dialogbisector.h \
|
||||
tools/vtoollinepoint.h \
|
||||
tools/vtoollineintersect.h \
|
||||
dialogs/dialoglineintersect.h
|
||||
dialogs/dialoglineintersect.h \
|
||||
geometry/vspline.h \
|
||||
tools/vtoolsinglepoint.h \
|
||||
geometry/varc.h \
|
||||
widgets/vcontrolpointspline.h \
|
||||
tools/vtoolspline.h \
|
||||
dialogs/dialogspline.h
|
||||
|
||||
FORMS += mainwindow.ui \
|
||||
dialogs/dialogsinglepoint.ui \
|
||||
|
@ -88,7 +98,8 @@ FORMS += mainwindow.ui \
|
|||
dialogs/dialogshoulderpoint.ui \
|
||||
dialogs/dialognormal.ui \
|
||||
dialogs/dialogbisector.ui \
|
||||
dialogs/dialoglineintersect.ui
|
||||
dialogs/dialoglineintersect.ui \
|
||||
dialogs/dialogspline.ui
|
||||
|
||||
RESOURCES += \
|
||||
icon.qrc \
|
||||
|
|
|
@ -73,6 +73,20 @@ void VContainer::UpdatePoint(qint64 id, const VPointF& point){
|
|||
}
|
||||
}
|
||||
|
||||
void VContainer::UpdateSpline(qint64 id, const VSpline &spl){
|
||||
splines[id] = spl;
|
||||
if(id > _id){
|
||||
_id = id;
|
||||
}
|
||||
}
|
||||
|
||||
void VContainer::UpdateArc(qint64 id, const VArc &arc){
|
||||
arcs[id] = arc;
|
||||
if(id > _id){
|
||||
_id = id;
|
||||
}
|
||||
}
|
||||
|
||||
void VContainer::UpdateStandartTableCell(const QString& name, const VStandartTableCell& cell){
|
||||
standartTable[name] = cell;
|
||||
}
|
||||
|
@ -103,6 +117,9 @@ void VContainer::Clear(){
|
|||
standartTable.clear();
|
||||
incrementTable.clear();
|
||||
lengthLines.clear();
|
||||
splines.clear();
|
||||
arcs.clear();
|
||||
lengthArcs.clear();
|
||||
}
|
||||
|
||||
void VContainer::ClearIncrementTable(){
|
||||
|
@ -113,6 +130,14 @@ void VContainer::ClearLengthLines(){
|
|||
lengthLines.clear();
|
||||
}
|
||||
|
||||
void VContainer::ClearLengthSplines(){
|
||||
lengthSplines.clear();
|
||||
}
|
||||
|
||||
void VContainer::ClearLengthArcs(){
|
||||
lengthArcs.clear();
|
||||
}
|
||||
|
||||
void VContainer::SetSize(qint32 size){
|
||||
base["Сг"] = size;
|
||||
}
|
||||
|
@ -159,6 +184,14 @@ const QMap<qint64, VPointF> *VContainer::DataPoints() const{
|
|||
return &points;
|
||||
}
|
||||
|
||||
const QMap<qint64, VSpline> *VContainer::DataSplines() const{
|
||||
return &splines;
|
||||
}
|
||||
|
||||
const QMap<qint64, VArc> *VContainer::DataArcs() const{
|
||||
return &arcs;
|
||||
}
|
||||
|
||||
const QMap<QString, qint32> *VContainer::DataBase() const{
|
||||
return &base;
|
||||
}
|
||||
|
@ -175,11 +208,27 @@ const QMap<QString, qreal> *VContainer::DataLengthLines() const{
|
|||
return &lengthLines;
|
||||
}
|
||||
|
||||
const QMap<QString, qreal> *VContainer::DataLengthSplines() const{
|
||||
return &lengthSplines;
|
||||
}
|
||||
|
||||
void VContainer::AddLine(const qint64 &firstPointId, const qint64 &secondPointId){
|
||||
QString nameLine = GetNameLine(firstPointId, secondPointId);
|
||||
VPointF firstPoint = GetPoint(firstPointId);
|
||||
VPointF secondPoint = GetPoint(secondPointId);
|
||||
AddLine(nameLine, QLineF(firstPoint.toQPointF(), secondPoint.toQPointF()).length());
|
||||
AddLengthLine(nameLine, QLineF(firstPoint.toQPointF(), secondPoint.toQPointF()).length());
|
||||
}
|
||||
|
||||
qint64 VContainer::AddSpline(const VSpline &spl){
|
||||
qint64 id = getNextId();
|
||||
splines[id] = spl;
|
||||
return id;
|
||||
}
|
||||
|
||||
qint64 VContainer::AddArc(const VArc &arc){
|
||||
qint64 id = getNextId();
|
||||
arcs[id] = arc;
|
||||
return id;
|
||||
}
|
||||
|
||||
QString VContainer::GetNameLine(const qint64 &firstPoint, const qint64 &secondPoint) const{
|
||||
|
@ -188,11 +237,50 @@ QString VContainer::GetNameLine(const qint64 &firstPoint, const qint64 &secondPo
|
|||
return QString("Line_%1_%2").arg(first.name(), second.name());
|
||||
}
|
||||
|
||||
void VContainer::AddLine(const QString &name, const qreal &value){
|
||||
QString VContainer::GetNameSpline(const qint64 &firstPoint, const qint64 &secondPoint) const{
|
||||
VPointF first = GetPoint(firstPoint);
|
||||
VPointF second = GetPoint(secondPoint);
|
||||
return QString("Spl_%1_%2").arg(first.name(), second.name());
|
||||
}
|
||||
|
||||
QString VContainer::GetNameArc(const qint64 &firstPoint, const qint64 ¢erPoint,
|
||||
const qint64 &secondPoint) const{
|
||||
VPointF first = GetPoint(firstPoint);
|
||||
VPointF center = GetPoint(centerPoint);
|
||||
VPointF second = GetPoint(secondPoint);
|
||||
return QString("Arc_%1_%2_%3").arg(first.name(), center.name(), second.name());
|
||||
}
|
||||
|
||||
void VContainer::AddLengthLine(const QString &name, const qreal &value){
|
||||
Q_ASSERT(!name.isEmpty());
|
||||
lengthLines[name] = value/PrintDPI*25.4;
|
||||
}
|
||||
|
||||
void VContainer::AddLengthSpline(const qint64 &firstPointId, const qint64 &secondPointId){
|
||||
QString nameLine = GetNameSpline(firstPointId, secondPointId);
|
||||
VPointF firstPoint = GetPoint(firstPointId);
|
||||
VPointF secondPoint = GetPoint(secondPointId);
|
||||
AddLengthSpline(nameLine, QLineF(firstPoint.toQPointF(), secondPoint.toQPointF()).length());
|
||||
}
|
||||
|
||||
void VContainer::AddLengthSpline(const QString &name, const qreal &value){
|
||||
Q_ASSERT(!name.isEmpty());
|
||||
lengthSplines[name] = value/PrintDPI*25.4;
|
||||
}
|
||||
|
||||
void VContainer::AddLengthArc(const qint64 &firstPointId, const qint64 ¢erPoint,
|
||||
const qint64 &secondPointId){
|
||||
QString nameLine = GetNameArc(firstPointId, centerPoint, secondPointId);
|
||||
VPointF firstPoint = GetPoint(firstPointId);
|
||||
VPointF secondPoint = GetPoint(secondPointId);
|
||||
AddLengthArc(nameLine, QLineF(firstPoint.toQPointF(), secondPoint.toQPointF()).length());
|
||||
}
|
||||
|
||||
void VContainer::AddLengthArc(const QString &name, const qreal &value){
|
||||
Q_ASSERT(!name.isEmpty());
|
||||
lengthArcs[name] = value/PrintDPI*25.4;
|
||||
}
|
||||
|
||||
qreal VContainer::GetLine(const QString &name) const{
|
||||
Q_ASSERT(!name.isEmpty());
|
||||
if(lengthLines.contains(name)){
|
||||
|
@ -203,3 +291,28 @@ qreal VContainer::GetLine(const QString &name) const{
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
VSpline VContainer::GetSpline(qint64 id) const{
|
||||
if(splines.contains(id)){
|
||||
return splines.value(id);
|
||||
} else {
|
||||
qCritical()<<"Не можу знайти id = "<<id<<" в таблиці.";
|
||||
throw"Не можу знайти сплайн за id.";
|
||||
}
|
||||
return VSpline();
|
||||
}
|
||||
|
||||
VArc VContainer::GetArc(qint64 id) const{
|
||||
if(arcs.contains(id)){
|
||||
return arcs.value(id);
|
||||
} else {
|
||||
qCritical()<<"Не можу знайти id = "<<id<<" в таблиці.";
|
||||
throw"Не можу знайти дугу за id.";
|
||||
}
|
||||
return VArc();
|
||||
}
|
||||
|
||||
|
||||
const QMap<QString, qreal> *VContainer::DataLengthArcs() const{
|
||||
return &lengthArcs;
|
||||
}
|
||||
|
|
|
@ -3,27 +3,52 @@
|
|||
|
||||
#include <QMap>
|
||||
#include <QTableWidget>
|
||||
|
||||
#include "vpointf.h"
|
||||
#include "vstandarttablecell.h"
|
||||
#include "vincrementtablerow.h"
|
||||
#include "../geometry/vspline.h"
|
||||
#include "../geometry/varc.h"
|
||||
|
||||
/**
|
||||
* @brief The VContainer class
|
||||
*/
|
||||
class VContainer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief VContainer
|
||||
*/
|
||||
VContainer();
|
||||
/**
|
||||
* @brief GetPoint
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
VPointF GetPoint(qint64 id) const;
|
||||
VStandartTableCell GetStandartTableCell(const QString& name) const;
|
||||
VIncrementTableRow GetIncrementTableRow(const QString& name) const;
|
||||
qreal GetLine(const QString &name) const;
|
||||
VSpline GetSpline(qint64 id) const;
|
||||
VArc GetArc(qint64 id) const;
|
||||
qint64 getId();
|
||||
qint64 AddPoint(const VPointF& point);
|
||||
void AddStandartTableCell(const QString& name, const VStandartTableCell& cell);
|
||||
void AddIncrementTableRow(const QString& name, const VIncrementTableRow &cell);
|
||||
void AddLine(const QString &name, const qreal &value);
|
||||
void AddLengthLine(const QString &name, const qreal &value);
|
||||
void AddLengthSpline(const qint64 &firstPointId, const qint64 &secondPointId);
|
||||
void AddLengthSpline(const QString &name, const qreal &value);
|
||||
void AddLengthArc(const qint64 &firstPointId, const qint64 ¢erPoint, const qint64 &secondPointId);
|
||||
void AddLengthArc(const QString &name, const qreal &value);
|
||||
void AddLine(const qint64 &firstPointId, const qint64 &secondPointId);
|
||||
qint64 AddSpline(const VSpline& spl);
|
||||
qint64 AddArc(const VArc& arc);
|
||||
QString GetNameLine(const qint64 &firstPoint, const qint64 &secondPoint) const;
|
||||
QString GetNameSpline(const qint64 &firstPoint, const qint64 &secondPoint) const;
|
||||
QString GetNameArc(const qint64 &firstPoint, const qint64 ¢erPoint,
|
||||
const qint64 &secondPoint) const;
|
||||
void UpdatePoint(qint64 id, const VPointF& point);
|
||||
void UpdateSpline(qint64 id, const VSpline& spl);
|
||||
void UpdateArc(qint64 id, const VArc& arc);
|
||||
void UpdateStandartTableCell(const QString& name, const VStandartTableCell& cell);
|
||||
void UpdateIncrementTableRow(const QString& name, const VIncrementTableRow& cell);
|
||||
qreal GetValueStandartTableCell(const QString& name) const;
|
||||
|
@ -31,6 +56,8 @@ public:
|
|||
void Clear();
|
||||
void ClearIncrementTable();
|
||||
void ClearLengthLines();
|
||||
void ClearLengthSplines();
|
||||
void ClearLengthArcs();
|
||||
void SetSize(qint32 size);
|
||||
void SetGrowth(qint32 growth);
|
||||
qint32 size() const;
|
||||
|
@ -40,10 +67,14 @@ public:
|
|||
qint64 getNextId();
|
||||
void RemoveIncrementTableRow(const QString& name);
|
||||
const QMap<qint64, VPointF> *DataPoints() const;
|
||||
const QMap<qint64, VSpline> *DataSplines() const;
|
||||
const QMap<qint64, VArc> *DataArcs() const;
|
||||
const QMap<QString, qint32> *DataBase() const;
|
||||
const QMap<QString, VStandartTableCell> *DataStandartTable() const;
|
||||
const QMap<QString, VIncrementTableRow> *DataIncrementTable() const;
|
||||
const QMap<QString, qreal> * DataLengthLines() const;
|
||||
const QMap<QString, qreal> *DataLengthLines() const;
|
||||
const QMap<QString, qreal> *DataLengthSplines() const;
|
||||
const QMap<QString, qreal> *DataLengthArcs() const;
|
||||
private:
|
||||
qint64 _id;
|
||||
QMap<QString, qint32> base;
|
||||
|
@ -51,6 +82,10 @@ private:
|
|||
QMap<QString, VStandartTableCell> standartTable;
|
||||
QMap<QString, VIncrementTableRow> incrementTable;
|
||||
QMap<QString, qreal> lengthLines;
|
||||
QMap<qint64, VSpline> splines;
|
||||
QMap<QString, qreal> lengthSplines;
|
||||
QMap<qint64, VArc> arcs;
|
||||
QMap<QString, qreal> lengthArcs;
|
||||
};
|
||||
|
||||
#endif // VCONTAINER_H
|
||||
|
|
|
@ -8,5 +8,6 @@
|
|||
<file>cursor/normal_cursor.png</file>
|
||||
<file>cursor/bisector_cursor.png</file>
|
||||
<file>cursor/intersect_cursor.png</file>
|
||||
<file>cursor/spline_cursor.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
BIN
cursor/spline_cursor.png
Normal file
BIN
cursor/spline_cursor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
|
@ -44,7 +44,7 @@ DialogAlongLine::~DialogAlongLine()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
void DialogAlongLine::ChoosedPoint(qint64 id, Scene::Type type){
|
||||
void DialogAlongLine::ChoosedObject(qint64 id, Scene::Type type){
|
||||
if(type == Scene::Point){
|
||||
VPointF point = data->GetPoint(id);
|
||||
if(number == 0){
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
qint64 getSecondPointId() const;
|
||||
void setSecondPointId(const qint64 &value);
|
||||
public slots:
|
||||
virtual void ChoosedPoint(qint64 id, Scene::Type type);
|
||||
virtual void ChoosedObject(qint64 id, Scene::Type type);
|
||||
virtual void DialogAccepted();
|
||||
private:
|
||||
Ui::DialogAlongLine *ui;
|
||||
|
|
|
@ -44,7 +44,7 @@ DialogBisector::~DialogBisector(){
|
|||
delete ui;
|
||||
}
|
||||
|
||||
void DialogBisector::ChoosedPoint(qint64 id, Scene::Type type){
|
||||
void DialogBisector::ChoosedObject(qint64 id, Scene::Type type){
|
||||
if(type == Scene::Point){
|
||||
VPointF point = data->GetPoint(id);
|
||||
if(number == 0){
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
qint64 getThirdPointId() const;
|
||||
void setThirdPointId(const qint64 &value);
|
||||
public slots:
|
||||
virtual void ChoosedPoint(qint64 id, Scene::Type type);
|
||||
virtual void ChoosedObject(qint64 id, Scene::Type type);
|
||||
virtual void DialogAccepted();
|
||||
private:
|
||||
Ui::DialogBisector *ui;
|
||||
|
|
|
@ -59,7 +59,7 @@ DialogEndLine::DialogEndLine(const VContainer *data, QWidget *parent) :
|
|||
connect(ui->lineEditFormula, &QLineEdit::textChanged, this, &DialogEndLine::FormulaChanged);
|
||||
}
|
||||
|
||||
void DialogEndLine::ChoosedPoint(qint64 id, Scene::Type type){
|
||||
void DialogEndLine::ChoosedObject(qint64 id, Scene::Type type){
|
||||
if(type == Scene::Point){
|
||||
VPointF point = data->GetPoint(id);
|
||||
ChangeCurrentText(ui->comboBoxBasePoint, point.name());
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
qint64 getBasePointId() const;
|
||||
void setBasePointId(const qint64 &value);
|
||||
public slots:
|
||||
virtual void ChoosedPoint(qint64 id, Scene::Type type);
|
||||
virtual void ChoosedObject(qint64 id, Scene::Type type);
|
||||
virtual void DialogAccepted();
|
||||
private:
|
||||
Ui::DialogEndLine *ui;
|
||||
|
|
|
@ -137,7 +137,49 @@ void DialogIncrements::FillLengthLines(){
|
|||
item = new QTableWidgetItem(QString().setNum(length));
|
||||
item->setTextAlignment(Qt::AlignHCenter);
|
||||
ui->tableWidgetLines->setItem(currentRow, 1, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DialogIncrements::FillLengthSplines(){
|
||||
const QMap<QString, qreal> *splinesTable = data->DataLengthSplines();
|
||||
qint32 currentRow = -1;
|
||||
QMapIterator<QString, qreal> i(*splinesTable);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
qreal length = i.value();
|
||||
currentRow++;
|
||||
ui->tableWidgetSplines->setRowCount ( splinesTable->size() );
|
||||
|
||||
QTableWidgetItem *item = new QTableWidgetItem(QString(i.key()));
|
||||
item->setTextAlignment(Qt::AlignHCenter);
|
||||
item->setFont(QFont("Times", 12, QFont::Bold));
|
||||
ui->tableWidgetSplines->setItem(currentRow, 0, item);
|
||||
|
||||
item = new QTableWidgetItem(QString().setNum(length));
|
||||
item->setTextAlignment(Qt::AlignHCenter);
|
||||
ui->tableWidgetSplines->setItem(currentRow, 1, item);
|
||||
}
|
||||
}
|
||||
|
||||
void DialogIncrements::FillLengthArcs(){
|
||||
const QMap<QString, qreal> *arcsTable = data->DataLengthArcs();
|
||||
qint32 currentRow = -1;
|
||||
QMapIterator<QString, qreal> i(*arcsTable);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
qreal length = i.value();
|
||||
currentRow++;
|
||||
ui->tableWidgetArcs->setRowCount ( arcsTable->size() );
|
||||
|
||||
QTableWidgetItem *item = new QTableWidgetItem(QString(i.key()));
|
||||
item->setTextAlignment(Qt::AlignHCenter);
|
||||
item->setFont(QFont("Times", 12, QFont::Bold));
|
||||
ui->tableWidgetArcs->setItem(currentRow, 0, item);
|
||||
|
||||
item = new QTableWidgetItem(QString().setNum(length));
|
||||
item->setTextAlignment(Qt::AlignHCenter);
|
||||
ui->tableWidgetArcs->setItem(currentRow, 1, item);
|
||||
}
|
||||
}
|
||||
|
||||
void DialogIncrements::FullUpdateFromFile(){
|
||||
|
@ -156,6 +198,14 @@ void DialogIncrements::FullUpdateFromFile(){
|
|||
InitialLinesTable();
|
||||
FillLengthLines();
|
||||
|
||||
ui->tableWidgetSplines->clear();
|
||||
InitialSplinesTable();
|
||||
FillLengthSplines();
|
||||
|
||||
ui->tableWidgetArcs->clear();
|
||||
InitialArcsTable();
|
||||
FillLengthArcs();
|
||||
|
||||
connect(ui->tableWidgetIncrement, &QTableWidget::cellChanged, this,
|
||||
&DialogIncrements::cellChanged);
|
||||
}
|
||||
|
@ -367,6 +417,22 @@ void DialogIncrements::InitialLinesTable(){
|
|||
ui->tableWidgetLines->setHorizontalHeaderItem(1, new QTableWidgetItem("Довжина"));
|
||||
}
|
||||
|
||||
void DialogIncrements::InitialSplinesTable(){
|
||||
ui->tableWidgetSplines->resizeColumnsToContents();
|
||||
ui->tableWidgetSplines->resizeRowsToContents();
|
||||
ui->tableWidgetSplines->verticalHeader()->setDefaultSectionSize(20);
|
||||
ui->tableWidgetSplines->setHorizontalHeaderItem(0, new QTableWidgetItem("Лінія"));
|
||||
ui->tableWidgetSplines->setHorizontalHeaderItem(1, new QTableWidgetItem("Довжина"));
|
||||
}
|
||||
|
||||
void DialogIncrements::InitialArcsTable(){
|
||||
ui->tableWidgetArcs->resizeColumnsToContents();
|
||||
ui->tableWidgetArcs->resizeRowsToContents();
|
||||
ui->tableWidgetArcs->verticalHeader()->setDefaultSectionSize(20);
|
||||
ui->tableWidgetArcs->setHorizontalHeaderItem(0, new QTableWidgetItem("Лінія"));
|
||||
ui->tableWidgetArcs->setHorizontalHeaderItem(1, new QTableWidgetItem("Довжина"));
|
||||
}
|
||||
|
||||
void DialogIncrements::DialogAccepted(){
|
||||
emit DialogClosed(QDialog::Accepted);
|
||||
}
|
||||
|
|
|
@ -33,9 +33,13 @@ private:
|
|||
void InitialStandartTable();
|
||||
void InitialIncrementTable();
|
||||
void InitialLinesTable();
|
||||
void InitialSplinesTable();
|
||||
void InitialArcsTable();
|
||||
void FillStandartTable();
|
||||
void FillIncrementTable();
|
||||
void FillLengthLines();
|
||||
void FillLengthSplines();
|
||||
void FillLengthArcs();
|
||||
void AddIncrementToFile(quint64 id, QString name, qint32 base, qreal ksize, qreal kgrowth,
|
||||
QString description);
|
||||
};
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<enum>QTabWidget::North</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabStandart">
|
||||
<attribute name="title">
|
||||
|
@ -245,7 +245,7 @@
|
|||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTableWidget" name="tableWidget_2">
|
||||
<widget class="QTableWidget" name="tableWidgetSplines">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
|
@ -281,7 +281,7 @@
|
|||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTableWidget" name="tableWidget_3">
|
||||
<widget class="QTableWidget" name="tableWidgetArcs">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
|
|
|
@ -55,7 +55,7 @@ void DialogLine::DialogAccepted(){
|
|||
DialogClosed(QDialog::Accepted);
|
||||
}
|
||||
|
||||
void DialogLine::ChoosedPoint(qint64 id, Scene::Type type){
|
||||
void DialogLine::ChoosedObject(qint64 id, Scene::Type type){
|
||||
if(type == Scene::Point){
|
||||
VPointF point = data->GetPoint(id);
|
||||
if(number == 0){
|
||||
|
|
|
@ -21,7 +21,7 @@ public:
|
|||
qint64 getSecondPoint() const;
|
||||
void setSecondPoint(const qint64 &value);
|
||||
public slots:
|
||||
void ChoosedPoint(qint64 id, Scene::Type type);
|
||||
void ChoosedObject(qint64 id, Scene::Type type);
|
||||
virtual void DialogAccepted();
|
||||
private:
|
||||
Ui::DialogLine *ui;
|
||||
|
|
|
@ -25,7 +25,7 @@ DialogLineIntersect::~DialogLineIntersect()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
void DialogLineIntersect::ChoosedPoint(qint64 id, Scene::Type type){
|
||||
void DialogLineIntersect::ChoosedObject(qint64 id, Scene::Type type){
|
||||
if(type == Scene::Point){
|
||||
VPointF point = data->GetPoint(id);
|
||||
if(number == 0){
|
||||
|
|
|
@ -24,7 +24,7 @@ public:
|
|||
QString getPointName() const;
|
||||
void setPointName(const QString &value);
|
||||
public slots:
|
||||
virtual void ChoosedPoint(qint64 id, Scene::Type type);
|
||||
virtual void ChoosedObject(qint64 id, Scene::Type type);
|
||||
virtual void DialogAccepted();
|
||||
void P1Line1Changed( int index);
|
||||
void P2Line1Changed( int index);
|
||||
|
|
|
@ -62,7 +62,7 @@ DialogNormal::~DialogNormal()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
void DialogNormal::ChoosedPoint(qint64 id, Scene::Type type){
|
||||
void DialogNormal::ChoosedObject(qint64 id, Scene::Type type){
|
||||
if(type == Scene::Point){
|
||||
VPointF point = data->GetPoint(id);
|
||||
if(number == 0){
|
||||
|
|
|
@ -33,7 +33,7 @@ public:
|
|||
qint64 getSecondPointId() const;
|
||||
void setSecondPointId(const qint64 &value);
|
||||
public slots:
|
||||
virtual void ChoosedPoint(qint64 id, Scene::Type type);
|
||||
virtual void ChoosedObject(qint64 id, Scene::Type type);
|
||||
virtual void DialogAccepted();
|
||||
private:
|
||||
Ui::DialogNormal *ui;
|
||||
|
|
|
@ -45,7 +45,7 @@ DialogShoulderPoint::~DialogShoulderPoint()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
void DialogShoulderPoint::ChoosedPoint(qint64 id, Scene::Type type){
|
||||
void DialogShoulderPoint::ChoosedObject(qint64 id, Scene::Type type){
|
||||
if(type == Scene::Point){
|
||||
VPointF point = data->GetPoint(id);
|
||||
if(number == 0){
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
qint64 getPShoulder() const;
|
||||
void setPShoulder(const qint64 &value);
|
||||
public slots:
|
||||
virtual void ChoosedPoint(qint64 id, Scene::Type type);
|
||||
virtual void ChoosedObject(qint64 id, Scene::Type type);
|
||||
virtual void DialogAccepted();
|
||||
private:
|
||||
Ui::DialogShoulderPoint *ui;
|
||||
|
|
127
dialogs/dialogspline.cpp
Normal file
127
dialogs/dialogspline.cpp
Normal file
|
@ -0,0 +1,127 @@
|
|||
#include "dialogspline.h"
|
||||
#include "ui_dialogspline.h"
|
||||
|
||||
DialogSpline::DialogSpline(const VContainer *data, QWidget *parent) :
|
||||
DialogTool(data, parent), ui(new Ui::DialogSpline)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
number = 0;
|
||||
bOk = ui->buttonBox->button(QDialogButtonBox::Ok);
|
||||
connect(bOk, &QPushButton::clicked, this, &DialogSpline::DialogAccepted);
|
||||
|
||||
QPushButton *bCansel = ui->buttonBox->button(QDialogButtonBox::Cancel);
|
||||
connect(bCansel, &QPushButton::clicked, this, &DialogSpline::DialogRejected);
|
||||
FillComboBoxPoints(ui->comboBoxP1);
|
||||
FillComboBoxPoints(ui->comboBoxP4);
|
||||
}
|
||||
|
||||
DialogSpline::~DialogSpline()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void DialogSpline::ChoosedObject(qint64 id, Scene::Type type){
|
||||
if(type == Scene::Point){
|
||||
VPointF point = data->GetPoint(id);
|
||||
if(number == 0){
|
||||
qint32 index = ui->comboBoxP1->findText(point.name());
|
||||
if ( index != -1 ) { // -1 for not found
|
||||
ui->comboBoxP1->setCurrentIndex(index);
|
||||
number++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(number == 1){
|
||||
qint32 index = ui->comboBoxP4->findText(point.name());
|
||||
if ( index != -1 ) { // -1 for not found
|
||||
ui->comboBoxP4->setCurrentIndex(index);
|
||||
number = 0;
|
||||
index = ui->comboBoxP1->currentIndex();
|
||||
qint64 p1Id = qvariant_cast<qint64>(ui->comboBoxP1->itemData(index));
|
||||
QPointF p1 = data->GetPoint(p1Id);
|
||||
QPointF p4 = data->GetPoint(id);
|
||||
ui->spinBoxAngle1->setValue(QLineF(p1, p4).angle());
|
||||
ui->spinBoxAngle2->setValue(QLineF(p4, p1).angle());
|
||||
}
|
||||
if(!isInitialized){
|
||||
this->show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DialogSpline::DialogAccepted(){
|
||||
qint32 index = ui->comboBoxP1->currentIndex();
|
||||
p1 = qvariant_cast<qint64>(ui->comboBoxP1->itemData(index));
|
||||
index = ui->comboBoxP4->currentIndex();
|
||||
p4 = qvariant_cast<qint64>(ui->comboBoxP4->itemData(index));
|
||||
angle1 = ui->spinBoxAngle1->value();
|
||||
angle2 = ui->spinBoxAngle2->value();
|
||||
kAsm1 = ui->doubleSpinBoxKasm1->value();
|
||||
kAsm2 = ui->doubleSpinBoxKasm2->value();
|
||||
kCurve = ui->doubleSpinBoxKcurve->value();
|
||||
emit DialogClosed(QDialog::Accepted);
|
||||
}
|
||||
|
||||
qreal DialogSpline::getKCurve() const{
|
||||
return kCurve;
|
||||
}
|
||||
|
||||
void DialogSpline::setKCurve(const qreal &value){
|
||||
kCurve = value;
|
||||
ui->doubleSpinBoxKcurve->setValue(value);
|
||||
}
|
||||
|
||||
qreal DialogSpline::getKAsm2() const{
|
||||
return kAsm2;
|
||||
}
|
||||
|
||||
void DialogSpline::setKAsm2(const qreal &value){
|
||||
kAsm2 = value;
|
||||
ui->doubleSpinBoxKasm2->setValue(value);
|
||||
}
|
||||
|
||||
qreal DialogSpline::getKAsm1() const{
|
||||
return kAsm1;
|
||||
}
|
||||
|
||||
void DialogSpline::setKAsm1(const qreal &value){
|
||||
kAsm1 = value;
|
||||
ui->doubleSpinBoxKasm1->setValue(value);
|
||||
}
|
||||
|
||||
qreal DialogSpline::getAngle2() const{
|
||||
return angle2;
|
||||
}
|
||||
|
||||
void DialogSpline::setAngle2(const qreal &value){
|
||||
angle2 = value;
|
||||
ui->spinBoxAngle2->setValue(value);
|
||||
}
|
||||
|
||||
qreal DialogSpline::getAngle1() const{
|
||||
return angle1;
|
||||
}
|
||||
|
||||
void DialogSpline::setAngle1(const qreal &value){
|
||||
angle1 = value;
|
||||
ui->spinBoxAngle1->setValue(value);
|
||||
}
|
||||
|
||||
qint64 DialogSpline::getP4() const{
|
||||
return p4;
|
||||
}
|
||||
|
||||
void DialogSpline::setP4(const qint64 &value){
|
||||
p4 = value;
|
||||
ChangeCurrentData(ui->comboBoxP4, value);
|
||||
}
|
||||
|
||||
qint64 DialogSpline::getP1() const{
|
||||
return p1;
|
||||
}
|
||||
|
||||
void DialogSpline::setP1(const qint64 &value){
|
||||
p1 = value;
|
||||
ChangeCurrentData(ui->comboBoxP1, value);
|
||||
}
|
46
dialogs/dialogspline.h
Normal file
46
dialogs/dialogspline.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
#ifndef DIALOGSPLINE_H
|
||||
#define DIALOGSPLINE_H
|
||||
|
||||
#include "dialogtool.h"
|
||||
#include "../container/vcontainer.h"
|
||||
|
||||
namespace Ui {
|
||||
class DialogSpline;
|
||||
}
|
||||
|
||||
class DialogSpline : public DialogTool
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DialogSpline(const VContainer *data, QWidget *parent = 0);
|
||||
~DialogSpline();
|
||||
qint64 getP1() const;
|
||||
void setP1(const qint64 &value);
|
||||
qint64 getP4() const;
|
||||
void setP4(const qint64 &value);
|
||||
qreal getAngle1() const;
|
||||
void setAngle1(const qreal &value);
|
||||
qreal getAngle2() const;
|
||||
void setAngle2(const qreal &value);
|
||||
qreal getKAsm1() const;
|
||||
void setKAsm1(const qreal &value);
|
||||
qreal getKAsm2() const;
|
||||
void setKAsm2(const qreal &value);
|
||||
qreal getKCurve() const;
|
||||
void setKCurve(const qreal &value);
|
||||
public slots:
|
||||
virtual void ChoosedObject(qint64 id, Scene::Type type);
|
||||
virtual void DialogAccepted();
|
||||
private:
|
||||
Ui::DialogSpline *ui;
|
||||
qint32 number;
|
||||
qint64 p1; // перша точка
|
||||
qint64 p4; // четверта точка
|
||||
qreal angle1; // кут нахилу дотичної в першій точці
|
||||
qreal angle2; // кут нахилу дотичної в другій точці
|
||||
qreal kAsm1;
|
||||
qreal kAsm2;
|
||||
qreal kCurve;
|
||||
};
|
||||
|
||||
#endif // DIALOGSPLINE_H
|
230
dialogs/dialogspline.ui
Normal file
230
dialogs/dialogspline.ui
Normal file
|
@ -0,0 +1,230 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DialogSpline</class>
|
||||
<widget class="QDialog" name="DialogSpline">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>524</width>
|
||||
<height>254</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Перша точка </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBoxP1"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Коефіцієнт довжини першої контрольної точки</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxKasm1">
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Кут першої контрольної точки</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBoxAngle1">
|
||||
<property name="maximum">
|
||||
<number>360</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Друга точка</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBoxP4"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Коефіцієнт довжини другої контрольної точки</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxKasm2">
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Кут другої контрольної точки</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBoxAngle2">
|
||||
<property name="maximum">
|
||||
<number>360</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Коефіцієнт кривизни сплайну</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxKcurve">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>72</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>DialogSpline</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>DialogSpline</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
|
@ -170,7 +170,7 @@ void DialogTool::CheckState(){
|
|||
}
|
||||
|
||||
|
||||
void DialogTool::ChoosedPoint(qint64 id, Scene::Type type){
|
||||
void DialogTool::ChoosedObject(qint64 id, Scene::Type type){
|
||||
Q_UNUSED(id);
|
||||
Q_UNUSED(type);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
signals:
|
||||
void DialogClosed(int result);
|
||||
public slots:
|
||||
virtual void ChoosedPoint(qint64 id, Scene::Type type);
|
||||
virtual void ChoosedObject(qint64 id, Scene::Type type);
|
||||
void NamePointChanged();
|
||||
virtual void DialogAccepted();
|
||||
virtual void DialogRejected();
|
||||
|
|
1792
docs/Doxyfile
Normal file
1792
docs/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
294
geometry/varc.cpp
Normal file
294
geometry/varc.cpp
Normal file
|
@ -0,0 +1,294 @@
|
|||
#define _USE_MATH_DEFINES
|
||||
#include <cmath>
|
||||
#include "varc.h"
|
||||
#include <QDebug>
|
||||
|
||||
VArc::VArc (){
|
||||
f1 = 0;
|
||||
f2 = 0;
|
||||
length = 0;
|
||||
radius = 0;
|
||||
center = 0;
|
||||
p1 = QPointF( 0, 0 );
|
||||
p2 = QPointF( 0, 0 );
|
||||
points = 0;
|
||||
}
|
||||
|
||||
VArc::VArc (const QMap<qint64, VPointF> *points, qint64 center, qreal radius, qreal f1, qreal f2 ){
|
||||
this->points = points;
|
||||
ModifiArc( center, radius, f1, f2 );
|
||||
}
|
||||
|
||||
qreal VArc::GetF1 () const{
|
||||
return f1;
|
||||
}
|
||||
|
||||
qreal VArc::GetF2 () const{
|
||||
return f2;
|
||||
}
|
||||
|
||||
qreal VArc::GetLength () const{
|
||||
return length;
|
||||
}
|
||||
|
||||
qreal VArc::GetRadius () const{
|
||||
return radius;
|
||||
}
|
||||
|
||||
qint64 VArc::GetCenter() const{
|
||||
return center;
|
||||
}
|
||||
|
||||
QPointF VArc::GetCenterPoint() const{
|
||||
if(points->contains(center)){
|
||||
return points->value(center);
|
||||
} else {
|
||||
qCritical()<<"Не можу знайти id = "<<center<<" в таблиці.";
|
||||
throw"Не можу знайти точку за id.";
|
||||
}
|
||||
return QPointF();
|
||||
}
|
||||
|
||||
QPointF VArc::GetP1() const{
|
||||
return p1;
|
||||
}
|
||||
|
||||
QPointF VArc::GetP2 () const{
|
||||
return p2;
|
||||
}
|
||||
|
||||
const QMap<qint64, VPointF> *VArc::GetDataPoints() const{
|
||||
return points;
|
||||
}
|
||||
|
||||
void VArc::ModifiArc (qint64 center, qreal radius, qreal f1, qreal f2 ){
|
||||
this->f1 = f1;
|
||||
this->f2 = f2;
|
||||
this->radius = radius;
|
||||
this->center = center;
|
||||
QPointF p1 ( GetCenterPoint().x () + radius, GetCenterPoint().y () );
|
||||
QLineF centerP1(GetCenterPoint(), p1);
|
||||
centerP1.setAngle(f1);
|
||||
p1 = centerP1.p2();
|
||||
QPointF p2 ( GetCenterPoint().x () + radius, GetCenterPoint().y () );
|
||||
QLineF centerP2(GetCenterPoint(), p2);
|
||||
centerP2.setAngle(f2);
|
||||
p2 = centerP2.p2();
|
||||
this->p1 = p1;
|
||||
this->p2 = p2;
|
||||
// визначимо довжину дуги за формулою.
|
||||
// МОЖЛИВО НЕ ПРАВИЛЬНО. ПОТРІБНО ПЕРЕВІРИТИ ФОРМУЛУ, ОСКІЛЬКИ КУТ ПОВЕРТАЄТЬСЯ В ГРАДУСАХ!!!!!
|
||||
//qreal ang = AngleArc ( f1, f2 ) ;
|
||||
qreal ang = centerP1.angleTo(centerP2);
|
||||
this->length = ang * radius * M_PI/180;
|
||||
//qDebug()<<"ang = "<<ang<<"length ="<<length;
|
||||
}
|
||||
|
||||
//void VArc::BiasArc ( qreal mx, qreal my ){
|
||||
// this->center = QPointF( center.x()+mx, center.y()+my );
|
||||
// this->p1 = QPointF( p1.x()+mx, p1.y()+my );
|
||||
// this->p2 = QPointF( p2.x()+mx, p2.y()+my );
|
||||
//}
|
||||
|
||||
//void VArc::RotationArc (QPointF pRotate, qreal angle ){
|
||||
// QLineF pRotateCenter( pRotate, center );
|
||||
// pRotateCenter.setAngle( angle );
|
||||
// center = pRotateCenter.p2();
|
||||
// QLineF pRotateP1( pRotate, p1 );
|
||||
// pRotateP1.setAngle( angle );
|
||||
// p1 = pRotateP1.p2();
|
||||
// QLineF pRotateP2( pRotate, p2 );
|
||||
// pRotateP2.setAngle( angle );
|
||||
// p2 = pRotateP2.p2();
|
||||
// QLineF centerP1 ( center, p1 );
|
||||
// QLineF centerP2 ( center, p2 );
|
||||
// f1 = centerP1.angle();
|
||||
// f2 = centerP2.angle();
|
||||
//}
|
||||
|
||||
VSpline VArc::SplOfArc ( qint32 number ) const{
|
||||
qint32 n = NumberSplOfArc ();
|
||||
if( number > n ){
|
||||
throw "Дуга не складається з такої кількості сплайнів.";
|
||||
}
|
||||
qreal f1 = GetF1 ();
|
||||
qreal f2 = GetF2 ();
|
||||
qint32 i;
|
||||
for ( i = 0; i < n; ++i ){
|
||||
if ( i == n - 1 ){
|
||||
f2 = GetF2 ();
|
||||
} else {
|
||||
if ( f1 + 90 > 360 ){
|
||||
f2 = f1 + 90 - 360;
|
||||
} else {
|
||||
f2 = f1 + 90;
|
||||
}
|
||||
}
|
||||
qreal anglF1, anglF2;
|
||||
if ( f1 + 90 > 360 ){
|
||||
anglF1 = f1 + 90 - 360 ;
|
||||
} else {
|
||||
anglF1 = f1 + 90 ;
|
||||
}
|
||||
if ( f2 - 90 < 0 ){
|
||||
anglF2 = 360 + f2 - 90 ;
|
||||
} else {
|
||||
anglF2 = f2 - 90 ;
|
||||
}
|
||||
if ( i + 1 == number ){
|
||||
// return VSpline (GetDataPoints(), GetP1 (), GetP2 (), anglF1, anglF2, 1., 1., 1. );
|
||||
f1 = f2;
|
||||
}
|
||||
}
|
||||
return VSpline();
|
||||
}
|
||||
|
||||
//void VArc::CutArc ( qreal length, VArc &arcFir, VArc &arcSec ) const{
|
||||
// if ( length > GetLength () ){
|
||||
// qDebug()<<"Не правильна довжина дуги/n";
|
||||
// exit(-1);
|
||||
// }
|
||||
// qreal angle;
|
||||
// angle = GetF1 () + (length * 180) / (radius * M_PI);
|
||||
// arcFir.ModifiArc ( GetCenter (), GetRadius (), GetF1 (), angle );
|
||||
// arcSec.ModifiArc ( GetCenter (), GetRadius (), angle, GetF2 () );
|
||||
//}
|
||||
|
||||
//void VArc::CutArc ( QPointF point, VArc &arcFir, VArc &arcSec ) const{
|
||||
// VArc arc = VArc(center,radius, f1, QLineF(center, point).angle());
|
||||
// if(this->length<arc.GetLength()){
|
||||
// throw"Не можу розрізати дугу. Не правильна точка.";
|
||||
// } else {
|
||||
// CutArc ( arc.GetLength(), arcFir, arcSec );
|
||||
// }
|
||||
//}
|
||||
|
||||
QLineF::IntersectType VArc::CrossingArcLine ( const QLineF &line, QPointF *intersectionPoint ) const{
|
||||
qint32 i, n;
|
||||
QLineF::IntersectType type = QLineF::NoIntersection;
|
||||
n = NumberSplOfArc ();
|
||||
for ( i = 0; i < n; ++i ){
|
||||
VSpline curve = SplOfArc ( i + 1 );
|
||||
QPointF crosPoint;
|
||||
type = curve.CrossingSplLine ( line, &crosPoint );
|
||||
if ( type == QLineF::BoundedIntersection ){
|
||||
*intersectionPoint = crosPoint;
|
||||
return type;
|
||||
} else{
|
||||
if ( type == QLineF::NoIntersection || type == QLineF::UnboundedIntersection ){
|
||||
throw "Не можу знайти точку перетину сплайну з лінією.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qint32 VArc::NumberSplOfArc () const{
|
||||
qint32 angArc = ( qint32 ) AngleArc ( GetF1 (), GetF2 () );
|
||||
switch( angArc ){
|
||||
case 0:
|
||||
throw "Кут дуги не може бути 0 градусів.";
|
||||
break;
|
||||
case 90:
|
||||
return 1;
|
||||
case 180:
|
||||
return 2;
|
||||
case 270:
|
||||
return 3;
|
||||
case 360:
|
||||
return 4;
|
||||
default :
|
||||
return ( qint32 ) AngleArc ( GetF1 (), GetF2 () ) / 90 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
qreal VArc::AngleArc( qreal f1, qreal f2 ) const{
|
||||
QLineF normal = QLineF( 0, 0, 100, 0 );
|
||||
normal.setAngle(f1);
|
||||
QLineF normal2 = QLineF( 0, 0, 100, 0 );
|
||||
normal2.setAngle(f2);
|
||||
return normal.angleTo(normal2);
|
||||
}
|
||||
|
||||
QPainterPath VArc::GetPath() const{
|
||||
QPainterPath Path;
|
||||
qint32 numberSpl = NumberSplOfArc();
|
||||
for(qint32 i = 1; i <= numberSpl; ++i){
|
||||
VSpline spl = SplOfArc ( i );
|
||||
Path.addPath( spl.GetPath() );
|
||||
}
|
||||
return Path;
|
||||
}
|
||||
|
||||
QVector<QPointF> VArc::GetPoints () const{
|
||||
QVector<QPointF> points;
|
||||
qint32 numberSpl = NumberSplOfArc();
|
||||
for(qint32 i = 1; i <= numberSpl; ++i){
|
||||
VSpline spl = SplOfArc ( i );
|
||||
points<<spl.GetPoints();
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
QPointF VArc::Tangent(const QPointF P, Tangent_e tan)const{
|
||||
QLineF CP = QLineF(GetCenterPoint(),P);
|
||||
CP.setLength(CP.length()/2);
|
||||
QPointF O = CP.p2();
|
||||
QLineF CO = QLineF(GetCenterPoint(),O);
|
||||
qreal d = CO.length();
|
||||
if ( d > GetRadius() + CO.length() ){
|
||||
throw"Немає перетину кіл для знаходження дотичних.";
|
||||
}
|
||||
if ( d < qAbs(GetRadius() - CO.length()) ){
|
||||
throw"Не можу знайти дотичну. Одне коло знаходиться в іншому.";
|
||||
}
|
||||
qreal a = (pow(GetRadius(),2) - pow(CO.length(),2) + pow(d,2) ) / (2*d);
|
||||
qreal h = sqrt(pow(GetRadius(),2) - pow(a,2));
|
||||
qreal x2 = GetCenterPoint().x() + a * (O.x() - GetCenterPoint().x())/d;
|
||||
qreal y2 = GetCenterPoint().y() + a * (O.y() - GetCenterPoint().y())/d;
|
||||
if(tan == VArc::FirstTangent){
|
||||
qreal x3 = x2 - h * ( O.y() - GetCenterPoint().y() ) / d;
|
||||
qreal y3 = y2 + h * ( O.x() - GetCenterPoint().x() ) / d;
|
||||
return QPointF(x3,y3);
|
||||
} else {
|
||||
qreal x3 = x2 + h * ( O.y() - GetCenterPoint().y() ) / d;
|
||||
qreal y3 = y2 - h * ( O.x() - GetCenterPoint().x() ) / d;
|
||||
return QPointF(x3,y3);
|
||||
}
|
||||
}
|
||||
|
||||
bool VArc::Contains(const QPointF P)const{
|
||||
QVector<QPointF> points = GetPoints ();
|
||||
for(qint32 i=0; i< points.size();++i){
|
||||
if((qint32)points[i].x()==(qint32)P.x() && (qint32)points[i].y()==(qint32)P.y()){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QPointF VArc::PutAlongArc(qreal length) const{
|
||||
if(GetLength()<length){
|
||||
throw"Довжина дуги менше заданої довжини";
|
||||
} else {
|
||||
qreal n = (length*180)/(M_PI*GetRadius());
|
||||
QLineF CP1 = QLineF(GetCenterPoint(),GetP1());
|
||||
CP1.setAngle(CP1.angle()+n);
|
||||
return CP1.p2();
|
||||
}
|
||||
}
|
||||
|
||||
//void VArc::Mirror(const QPointF Pmirror){
|
||||
// QPointF Center = center;
|
||||
// Center = QPointF(Center.x() - Pmirror.x(), Center.y() - Pmirror.y());
|
||||
// Center = QPointF(Center.x() * -1.0, Center.y() * 1.0);
|
||||
// Center = QPointF(Center.x() + Pmirror.x(), Center.y() + Pmirror.y());
|
||||
// QPointF P1 = p1;
|
||||
// P1 = QPointF(P1.x() - Pmirror.x(), P1.y() - Pmirror.y());
|
||||
// P1 = QPointF(P1.x() * -1.0, P1.y() * 1.0);
|
||||
// P1 = QPointF(P1.x() + Pmirror.x(), P1.y() + Pmirror.y());
|
||||
// QPointF P2 = p2;
|
||||
// P2 = QPointF(P2.x() - Pmirror.x(), P2.y() - Pmirror.y());
|
||||
// P2 = QPointF(P2.x() * -1.0, P2.y() * 1.0);
|
||||
// P2 = QPointF(P2.x() + Pmirror.x(), P2.y() + Pmirror.y());
|
||||
// this->ModifiArc ( Center, radius, QLineF(Center,P2).angle(), QLineF(Center,P1).angle() );
|
||||
//}
|
192
geometry/varc.h
Normal file
192
geometry/varc.h
Normal file
|
@ -0,0 +1,192 @@
|
|||
#ifndef VARC_H
|
||||
#define VARC_H
|
||||
|
||||
#include "vspline.h"
|
||||
#include <QPainterPath>
|
||||
#include <QVector>
|
||||
#include <QMap>
|
||||
#include "container/vpointf.h"
|
||||
|
||||
/**
|
||||
* @brief VArc клас, що реалізує дугу. Дуга розраховується за годиниковою стрілкою.
|
||||
*/
|
||||
class VArc{
|
||||
public:
|
||||
enum Tangent_e { FirstTangent, SecondTangent };
|
||||
/**
|
||||
* @brief VArc конструктор по замовчуванню.
|
||||
*/
|
||||
VArc ();
|
||||
/**
|
||||
* @brief VArc конструктор.
|
||||
* @param center точка центру.
|
||||
* @param radius радіус.
|
||||
* @param f1 початковий кут в градусах.
|
||||
* @param f2 кінцевий кут в градусах.
|
||||
*/
|
||||
VArc ( const QMap<qint64, VPointF> *points, qint64 center, qreal radius, qreal f1,
|
||||
qreal f2 );
|
||||
/**
|
||||
* @brief GetF1 повертає початковий кут дуги.
|
||||
* @return повертає кут в градусах.
|
||||
*/
|
||||
qreal GetF1 () const;
|
||||
/**
|
||||
* @brief GetF2 повертає кінцевий кут дуги.
|
||||
* @return повертає кут в градусах.
|
||||
*/
|
||||
qreal GetF2 () const;
|
||||
/**
|
||||
* @brief GetLength повертає довжину дуги.
|
||||
* @return повертає довжину дуги.
|
||||
*/
|
||||
qreal GetLength () const;
|
||||
/**
|
||||
* @brief GetRadius повертає радіус дуги.
|
||||
* @return повертає радіус дуги.
|
||||
*/
|
||||
qreal GetRadius () const;
|
||||
/**
|
||||
* @brief GetCenter повертає точку центра дуги.
|
||||
* @return повертає точку центра дуги.
|
||||
*/
|
||||
qint64 GetCenter () const;
|
||||
QPointF GetCenterPoint() const;
|
||||
/**
|
||||
* @brief GetP1 повертає першу точку з якої починається дуга.
|
||||
* @return точку початку дуги.
|
||||
*/
|
||||
QPointF GetP1 () const;
|
||||
/**
|
||||
* @brief GetP2 повертає другу точку в якій закінчується дуга.
|
||||
* @return точку кінця дуги.
|
||||
*/
|
||||
QPointF GetP2 () const;
|
||||
const QMap<qint64, VPointF> *GetDataPoints() const;
|
||||
/**
|
||||
* @brief ModifiArc змінює параметри дуги.
|
||||
* @param center новий центр дуги.
|
||||
* @param radius новий радіус дуги.
|
||||
* @param f1 новий початковий кут в градусах.
|
||||
* @param f2 новий кінцевий кут в градусах.
|
||||
*/
|
||||
void ModifiArc (qint64 center, qreal radius, qreal f1, qreal f2 );
|
||||
/**
|
||||
* @brief BiasArc зміщує дугу.
|
||||
* @param mx зміщення по х координаті.
|
||||
* @param my зміщення по у координаті.
|
||||
*/
|
||||
// void BiasArc ( qreal mx, qreal my );
|
||||
/**
|
||||
* @brief RotationArc повертає дугу на кут проти годиникової стрілки відносно точки.
|
||||
* @param pRotate точка відносно якої повертається.
|
||||
* @param angle кут в градусах на який повертається в градусах.
|
||||
*/
|
||||
// void RotationArc ( QPointF pRotate, qreal angle );
|
||||
/**
|
||||
* @brief SplOfArc повертає сплайн дуги за номером.
|
||||
* @param number номер сплайна в дузі.
|
||||
* @return сплайн.
|
||||
*/
|
||||
VSpline SplOfArc ( qint32 number ) const;
|
||||
/**
|
||||
* @brief CutArc розрізає дугу на дві дуги.
|
||||
* @param length довжина першої дуги.
|
||||
* @param arcFir перша дуга.
|
||||
* @param arcSec друга дуга.
|
||||
*/
|
||||
// void CutArc ( qreal length, VArc &arcFir, VArc &arcSec ) const;
|
||||
/**
|
||||
* @brief CutArc розрізає дугу на дві дуги.
|
||||
* @param point точка яка ділить дугу.
|
||||
* @param arcFir перша дуга.
|
||||
* @param arcSec друга дуга.
|
||||
*/
|
||||
// void CutArc ( QPointF point, VArc &arcFir, VArc &arcSec ) const;
|
||||
/**
|
||||
* @brief CrossingArcLine перевіряє перетин дуги і лінії.
|
||||
* @param line лінія з якою шукаємо перетин.
|
||||
* @param intersectionPoint точка перетину.
|
||||
* @return результат перевірки на перетин.
|
||||
*/
|
||||
QLineF::IntersectType CrossingArcLine(const QLineF &line, QPointF *intersectionPoint) const;
|
||||
/**
|
||||
* @brief NumberSplOfArc метод шукає кілкість сплайнів які необхідні для відтворення такої дуги.
|
||||
* @return кількість сплайнів.
|
||||
*/
|
||||
qint32 NumberSplOfArc () const;
|
||||
/**
|
||||
* @brief GetPath будує шлях по даній дузі.
|
||||
* @return повертає шлях.
|
||||
*/
|
||||
QPainterPath GetPath() const;
|
||||
/**
|
||||
* @brief GetPoints повертає набір точок по яких можна побудувати дугу.
|
||||
* @return набір точок дуги.
|
||||
*/
|
||||
QVector<QPointF>
|
||||
GetPoints () const;
|
||||
/**
|
||||
* @brief Tangent розраховує дотичну до дуги.
|
||||
* @param P точка через, що не належить дузі, через яку проходить дотична.
|
||||
* @param tan перша чи друга дотична.
|
||||
* @return точку дотичної на дузі.
|
||||
*/
|
||||
QPointF Tangent(const QPointF P,VArc::Tangent_e tan = VArc::FirstTangent)const;
|
||||
/**
|
||||
* @brief Contains перевіряє чи точка належить дузі.
|
||||
* @param P точка що перевіряється.
|
||||
* @return true - належить дузі, false - не належить дузі.
|
||||
*/
|
||||
bool Contains(const QPointF P)const;
|
||||
/**
|
||||
* @brief PutAlongArc розміщує точку на дузі.
|
||||
* @param length довжина від початку дуги.
|
||||
* @return точка що лежить на дузі.
|
||||
*/
|
||||
QPointF PutAlongArc(qreal length) const;
|
||||
/**
|
||||
* @brief Mirror дзеркальне відображення дуги.
|
||||
* @param Pmirror точка відносно якої відбувається дзеркалення.
|
||||
*/
|
||||
// void Mirror(const QPointF Pmirror);
|
||||
private:
|
||||
/**
|
||||
* @brief f1 початковий кут в градусах
|
||||
*/
|
||||
qreal f1; // початковий кут нахилу дуги (градуси)
|
||||
/**
|
||||
* @brief f2 кінцевий кут в градусах
|
||||
*/
|
||||
qreal f2; // кінцевий кут нахилу дуги (градуси)
|
||||
/**
|
||||
* @brief length довжина дуги.
|
||||
*/
|
||||
qreal length; // довжина дуги
|
||||
/**
|
||||
* @brief radius радіус дуги.
|
||||
*/
|
||||
qreal radius;
|
||||
/**
|
||||
* @brief center центральна точка дуги.
|
||||
*/
|
||||
qint64 center;
|
||||
/**
|
||||
* @brief p1 точка початку побудови дуги.
|
||||
*/
|
||||
QPointF p1;
|
||||
/**
|
||||
* @brief p2 кінцева точка побудови дуги.
|
||||
*/
|
||||
QPointF p2;
|
||||
const QMap<qint64, VPointF> *points;
|
||||
/**
|
||||
* @brief AngleArc визначає кут дуги.
|
||||
* @param f1 початковий кут дуги в градусах.
|
||||
* @param f2 кінцевий кут в градусах.
|
||||
* @return повертає кут в градусах.
|
||||
*/
|
||||
qreal AngleArc(qreal f1, qreal f2 ) const;
|
||||
};
|
||||
|
||||
#endif // VARC_H
|
729
geometry/vspline.cpp
Normal file
729
geometry/vspline.cpp
Normal file
|
@ -0,0 +1,729 @@
|
|||
#define _USE_MATH_DEFINES
|
||||
#include <cmath>
|
||||
#include "vspline.h"
|
||||
#include <QDebug>
|
||||
|
||||
VSpline::VSpline(){
|
||||
p1 = 0;
|
||||
p2 = QPointF();
|
||||
p3 = QPointF();
|
||||
p4 = 0;
|
||||
angle1 = 0;
|
||||
angle2 = 0;
|
||||
points = 0;
|
||||
kAsm1 = 1;
|
||||
kAsm2 = 1;
|
||||
kCurve = 1;
|
||||
}
|
||||
|
||||
VSpline::VSpline ( const VSpline & spline ){
|
||||
p1 = spline.GetP1 ();
|
||||
p2 = spline.GetP2 ();
|
||||
p3 = spline.GetP3 ();
|
||||
p4 = spline.GetP4 ();
|
||||
angle1 = spline.GetAngle1 ();
|
||||
angle2 = spline.GetAngle2 ();
|
||||
points = spline.GetDataPoints();
|
||||
kAsm1 = spline.GetKasm1();
|
||||
kAsm2 = spline.GetKasm2();
|
||||
kCurve = spline.GetKcurve();
|
||||
}
|
||||
|
||||
VSpline::VSpline (const QMap<qint64, VPointF> *points, qint64 p1, qint64 p4, qreal angle1, qreal angle2,
|
||||
qreal kAsm1, qreal kAsm2 , qreal kCurve){
|
||||
this->points = points;
|
||||
ModifiSpl ( p1, p4, angle1, angle2, kAsm1, kAsm2, kCurve );
|
||||
}
|
||||
|
||||
VSpline::VSpline (const QMap<qint64, VPointF> *points, qint64 p1, QPointF p2, QPointF p3, qint64 p4,
|
||||
qreal kCurve){
|
||||
this->points = points;
|
||||
ModifiSpl ( p1, p2, p3, p4, kCurve);
|
||||
}
|
||||
|
||||
void VSpline::ModifiSpl ( qint64 p1, qint64 p4, qreal angle1, qreal angle2,
|
||||
qreal kAsm1, qreal kAsm2, qreal kCurve){
|
||||
this->p1 = p1;
|
||||
this->p4 = p4;
|
||||
this->angle1 = angle1;
|
||||
this->angle2 = angle2;
|
||||
this->kAsm1 = kAsm1;
|
||||
this->kAsm2 = kAsm2;
|
||||
this->kCurve = kCurve;
|
||||
QLineF p1pX(GetPointP1().x(), GetPointP1().y(), GetPointP1().x() + 100, GetPointP1().y());
|
||||
p1pX.setAngle( angle1 );
|
||||
qreal L = 0, radius = 0, angle = 90;
|
||||
// angle = QLineF(GetPointP1(), p1pX.p2()).angleTo(QLineF(GetPointP1(), GetPointP4()));
|
||||
// if ( angle > 180 ){
|
||||
// angle = 360 - angle;
|
||||
// }
|
||||
QPointF point1 = GetPointP1();
|
||||
QPointF point4 = GetPointP4();
|
||||
radius = QLineF(QPointF(point1.x(), point4.y()),point4).length();
|
||||
// radius = QLineF(GetPointP1(), GetPointP4()).length() / 2 / sin( angle * M_PI / 180.0 );
|
||||
L = kCurve * radius * 4 / 3 * tan( angle * M_PI / 180.0 / 4 );
|
||||
QLineF p1p2(GetPointP1().x(), GetPointP1().y(), GetPointP1().x() + L * kAsm1, GetPointP1().y());
|
||||
p1p2.setAngle(angle1);
|
||||
QLineF p4p3(GetPointP4().x(), GetPointP4().y(), GetPointP4().x() + L * kAsm2, GetPointP4().y());
|
||||
p4p3.setAngle(angle2);
|
||||
this->p2 = p1p2.p2();
|
||||
this->p3 = p4p3.p2();
|
||||
}
|
||||
|
||||
void VSpline::ModifiSpl (qint64 p1, QPointF p2, QPointF p3, qint64 p4, qreal kCurve){
|
||||
this->p1 = p1;
|
||||
this->p2 = p2;
|
||||
this->p3 = p3;
|
||||
this->p4 = p4;
|
||||
this->angle1 = QLineF ( GetPointP1(), p2 ).angle();
|
||||
this->angle2 = QLineF ( GetPointP4(), p3 ).angle();
|
||||
|
||||
QLineF p1pX(GetPointP1().x(), GetPointP1().y(), GetPointP1().x() + 100, GetPointP1().y());
|
||||
p1pX.setAngle( angle1 );
|
||||
qreal L = 0, radius = 0, angle = 90;
|
||||
// angle = QLineF(GetPointP1(), p1pX.p2()).angleTo(QLineF(GetPointP1(), GetPointP4()));
|
||||
// if ( angle >= 180 ){
|
||||
// angle = 360 - angle;
|
||||
// }
|
||||
QPointF point1 = GetPointP1();
|
||||
QPointF point4 = GetPointP4();
|
||||
radius = QLineF(QPointF(point1.x(), point4.y()),point4).length();
|
||||
// radius = QLineF(GetPointP1(), GetPointP4()).length() / 2 / sin( angle * M_PI / 180.0 );
|
||||
L = kCurve * radius * 4 / 3 * tan( angle * M_PI / 180.0 / 4 );
|
||||
|
||||
this->kCurve = kCurve;
|
||||
this->kAsm1 = QLineF ( GetPointP1(), p2 ).length()/L;
|
||||
this->kAsm2 = QLineF ( GetPointP4(), p3 ).length()/L;
|
||||
}
|
||||
|
||||
//void VSpline::RotationSpl (QPointF pRotate, qreal angle ){
|
||||
// QLineF pRotateP1 (pRotate, p1);
|
||||
// pRotateP1.setAngle(angle);
|
||||
// p1 = pRotateP1.p2();
|
||||
// QLineF pRotateP2 (pRotate, p2);
|
||||
// pRotateP2.setAngle(angle);
|
||||
// p2 = pRotateP2.p2();
|
||||
// QLineF pRotateP3 (pRotate, p3);
|
||||
// pRotateP3.setAngle(angle);
|
||||
// p3 = pRotateP3.p2();
|
||||
// QLineF pRotateP4 (pRotate, p4);
|
||||
// pRotateP4.setAngle(angle);
|
||||
// p4 = pRotateP4.p2();
|
||||
// angle1 = QLineF(p1, p2).angle();
|
||||
// angle2 = QLineF(p4, p2).angle();
|
||||
//}
|
||||
|
||||
//void VSpline::BiasSpl ( qreal mx, qreal my ){
|
||||
// p1 = QPointF(p1.x()+mx, p1.y()+my);
|
||||
// p2 = QPointF(p2.x()+mx, p2.y()+my);
|
||||
// p3 = QPointF(p3.x()+mx, p3.y()+my);
|
||||
// p4 = QPointF(p4.x()+mx, p4.y()+my);
|
||||
//}
|
||||
|
||||
qint64 VSpline::GetP1 () const{
|
||||
return p1;
|
||||
}
|
||||
|
||||
VPointF VSpline::GetPointP1() const{
|
||||
if(points->contains(p1)){
|
||||
return points->value(p1);
|
||||
} else {
|
||||
qCritical()<<"Не можу знайти id = "<<p1<<" в таблиці.";
|
||||
throw"Не можу знайти точку за id.";
|
||||
}
|
||||
return VPointF();
|
||||
}
|
||||
|
||||
QPointF VSpline::GetP2 () const{
|
||||
return p2;
|
||||
}
|
||||
|
||||
QPointF VSpline::GetP3 () const{
|
||||
return p3;
|
||||
}
|
||||
|
||||
qint64 VSpline::GetP4() const{
|
||||
return p4;
|
||||
}
|
||||
|
||||
VPointF VSpline::GetPointP4() const{
|
||||
if(points->contains(p4)){
|
||||
return points->value(p4);
|
||||
} else {
|
||||
qCritical()<<"Не можу знайти id = "<<p4<<" в таблиці.";
|
||||
throw"Не можу знайти точку за id.";
|
||||
}
|
||||
return VPointF();
|
||||
}
|
||||
|
||||
qreal VSpline::GetAngle1() const{
|
||||
return angle1;
|
||||
}
|
||||
|
||||
qreal VSpline::GetAngle2 () const{
|
||||
return angle2;
|
||||
}
|
||||
|
||||
qreal VSpline::GetLength () const{
|
||||
return LengthBezier ( GetPointP1(), this->p2, this->p3, GetPointP4());
|
||||
}
|
||||
|
||||
QString VSpline::GetName() const{
|
||||
VPointF first = GetPointP1();
|
||||
VPointF second = GetPointP4();
|
||||
return QString("Spl_%1_%2").arg(first.name(), second.name());
|
||||
}
|
||||
|
||||
qreal VSpline::GetKasm1() const{
|
||||
return kAsm1;
|
||||
}
|
||||
|
||||
qreal VSpline::GetKasm2() const{
|
||||
return kAsm2;
|
||||
}
|
||||
|
||||
qreal VSpline::GetKcurve() const{
|
||||
return kCurve;
|
||||
}
|
||||
|
||||
const QMap<qint64, VPointF> *VSpline::GetDataPoints() const{
|
||||
return points;
|
||||
}
|
||||
|
||||
QLineF::IntersectType VSpline::CrossingSplLine ( const QLineF &line, QPointF *intersectionPoint ) const{
|
||||
QVector<qreal> px;
|
||||
QVector<qreal> py;
|
||||
px.append ( GetPointP1 ().x () );
|
||||
py.append ( GetPointP1 ().y () );
|
||||
QVector<qreal>& wpx = px;
|
||||
QVector<qreal>& wpy = py;
|
||||
PointBezier_r ( GetPointP1 ().x (), GetPointP1 ().y (), GetP2 ().x (), GetP2 ().y (),
|
||||
GetP3 ().x (), GetP3 ().y (), GetPointP4 ().x (), GetPointP4 ().y (),
|
||||
0, wpx, wpy);
|
||||
px.append ( GetPointP4 ().x () );
|
||||
py.append ( GetPointP4 ().y () );
|
||||
qint32 i = 0;
|
||||
QPointF crosPoint;
|
||||
QLineF::IntersectType type = QLineF::NoIntersection;
|
||||
for ( i = 0; i < px.count()-1; ++i ){
|
||||
type = line.intersect(QLineF ( QPointF ( px[i], py[i] ),
|
||||
QPointF ( px[i+1], py[i+1] )), &crosPoint);
|
||||
if ( type == QLineF::BoundedIntersection ){
|
||||
*intersectionPoint = crosPoint;
|
||||
return type;
|
||||
}
|
||||
}
|
||||
throw "Не можу знайти точку перетину сплайну з лінією.";
|
||||
}
|
||||
|
||||
//void VSpline::CutSpline ( qreal length, VSpline* curFir, VSpline* curSec ) const{
|
||||
// if ( length > GetLength()){
|
||||
// throw"Не правильна довжина нового сплайну\n";
|
||||
// }
|
||||
// qreal parT = length / GetLength();
|
||||
// QLineF seg1_2 ( GetPointP1 (), GetP2 () );
|
||||
// seg1_2.setLength(seg1_2.length () * parT);
|
||||
// QPointF p12 = seg1_2.p2();
|
||||
// QLineF seg2_3 ( GetP2 (), GetP3 () );
|
||||
// seg2_3.setLength(seg2_3.length () * parT);
|
||||
// QPointF p23 = seg2_3.p2();
|
||||
// QLineF seg12_23 ( p12, p23 );
|
||||
// seg12_23.setLength(seg12_23.length () * parT);
|
||||
// QPointF p123 = seg12_23.p2();
|
||||
// QLineF seg3_4 ( GetP3 (), GetPointP4 () );
|
||||
// seg3_4.setLength(seg3_4.length () * parT);
|
||||
// QPointF p34 = seg3_4.p2();
|
||||
// QLineF seg23_34 ( p23, p34 );
|
||||
// seg23_34.setLength(seg23_34.length () * parT);
|
||||
// QPointF p234 = seg23_34.p2();
|
||||
// QLineF seg123_234 ( p123, p234 );
|
||||
// seg123_234.setLength(seg123_234.length () * parT);
|
||||
// QPointF p1234 = seg123_234.p2();
|
||||
// curFir->ModifiSpl ( GetPointP1 (), p12, p123, p1234 );
|
||||
// curSec->ModifiSpl ( p1234, p234, p34, GetPointP4 () );
|
||||
//}
|
||||
|
||||
//void VSpline::CutSpline ( QPointF point, VSpline* curFir, VSpline* curSec ) const{
|
||||
// qreal t = param_t (point);
|
||||
// qreal length = t*this->GetLength();
|
||||
// CutSpline ( length, curFir, curSec );
|
||||
//}
|
||||
|
||||
void VSpline::PutAlongSpl (QPointF &moveP, qreal move ) const{
|
||||
if ( GetLength () < move ){
|
||||
qDebug()<<"Довжина більше довжини сплайну.";
|
||||
qDebug()<<GetLength()<<"<"<<move;
|
||||
throw "Довжина більше довжини сплайну.";
|
||||
}
|
||||
if ( move <= 0 ){
|
||||
qDebug()<<"Довжина менше дорівнює нулю.";
|
||||
throw "Довжина менше дорівнює нулю.";
|
||||
}
|
||||
qreal t = 0;
|
||||
if ( move == 0 ){
|
||||
t = 0;
|
||||
} else {
|
||||
t = move / GetLength ();
|
||||
moveP.setX ( pow ( 1 - t, 3 ) * GetPointP1 ().x () + 3 * t * pow ( 1 - t, 2 ) *
|
||||
GetP2 ().x () + 3 * t * t * ( 1 - t ) * GetP3 ().x () +
|
||||
pow ( t, 3 ) * GetPointP4 ().x () );
|
||||
moveP.setY ( pow ( 1 - t, 3 ) * GetPointP1 ().y () + 3 * t * pow ( 1 - t, 2 ) *
|
||||
GetP2 ().y () + 3 * t * t * ( 1 - t ) * GetP3 ().y () +
|
||||
pow ( t, 3 ) * GetPointP4 ().y () );
|
||||
}
|
||||
}
|
||||
|
||||
QVector<QPointF> VSpline::GetPoints () const{
|
||||
return GetPoints(GetPointP1(), p2, p3, GetPointP4());
|
||||
}
|
||||
|
||||
QVector<QPointF> VSpline::GetPoints (QPointF p1, QPointF p2, QPointF p3, QPointF p4) const{
|
||||
QVector<QPointF> pvector;
|
||||
QVector<qreal> x;
|
||||
QVector<qreal> y;
|
||||
QVector<qreal>& wx = x;
|
||||
QVector<qreal>& wy = y;
|
||||
x.append ( p1.x () );
|
||||
y.append ( p1.y () );
|
||||
PointBezier_r ( p1.x (), p1.y (), p2.x (), p2.y (),
|
||||
p3.x (), p3.y (), p4.x (), p4.y (), 0, wx, wy );
|
||||
x.append ( p4.x () );
|
||||
y.append ( p4.y () );
|
||||
for ( qint32 i = 0; i < x.count(); ++i ){
|
||||
pvector.append( QPointF ( x[i], y[i] ) );
|
||||
}
|
||||
return pvector;
|
||||
}
|
||||
|
||||
qreal VSpline::LengthBezier ( QPointF p1, QPointF p2, QPointF p3, QPointF p4 ) const{
|
||||
/*QVector<qreal> px;
|
||||
QVector<qreal> py;
|
||||
QVector<qreal>& wpx = px;
|
||||
QVector<qreal>& wpy = py;
|
||||
px.append ( p1.x () );
|
||||
py.append ( p1.y () );
|
||||
PointBezier_r ( p1.x (), p1.y (), p2.x (), p2.y (),
|
||||
p3.x (), p3.y (), p4.x (), p4.y (), 0, wpx, wpy);
|
||||
px.append ( p4.x () );
|
||||
py.append ( p4.y () );
|
||||
qint32 i = 0;
|
||||
qreal length = 0.0;
|
||||
/*
|
||||
* Наприклад маємо 10 точок. Від 0 до 9 і останню точку не опрацьовуємо.
|
||||
* Тому від 0 до 8(<10-1).
|
||||
*
|
||||
for ( i = 0; i < px.count() - 1; ++i ){
|
||||
length += QLineF ( QPointF ( px[i], py[i] ), QPointF ( px[i+1], py[i+1] ) ).length ();
|
||||
}*/
|
||||
QPainterPath splinePath;
|
||||
QVector<QPointF> points = GetPoints (p1, p2, p3, p4);
|
||||
splinePath.moveTo(points[0]);
|
||||
for (qint32 i = 1; i < points.count(); ++i){
|
||||
splinePath.lineTo(points[i]);
|
||||
}
|
||||
return splinePath.length();
|
||||
}
|
||||
|
||||
void VSpline::PointBezier_r ( qreal x1, qreal y1, qreal x2, qreal y2,
|
||||
qreal x3, qreal y3, qreal x4, qreal y4,
|
||||
qint16 level, QVector<qreal> &px, QVector<qreal> &py) const{
|
||||
const double curve_collinearity_epsilon = 1e-30;
|
||||
const double curve_angle_tolerance_epsilon = 0.01;
|
||||
const double m_angle_tolerance = 0.0;
|
||||
enum curve_recursion_limit_e { curve_recursion_limit = 32 };
|
||||
const double m_cusp_limit = 0.0;
|
||||
double m_approximation_scale = 1.0;
|
||||
double m_distance_tolerance_square;
|
||||
|
||||
m_distance_tolerance_square = 0.5 / m_approximation_scale;
|
||||
m_distance_tolerance_square *= m_distance_tolerance_square;
|
||||
|
||||
if(level > curve_recursion_limit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate all the mid-points of the line segments
|
||||
//----------------------
|
||||
double x12 = (x1 + x2) / 2;
|
||||
double y12 = (y1 + y2) / 2;
|
||||
double x23 = (x2 + x3) / 2;
|
||||
double y23 = (y2 + y3) / 2;
|
||||
double x34 = (x3 + x4) / 2;
|
||||
double y34 = (y3 + y4) / 2;
|
||||
double x123 = (x12 + x23) / 2;
|
||||
double y123 = (y12 + y23) / 2;
|
||||
double x234 = (x23 + x34) / 2;
|
||||
double y234 = (y23 + y34) / 2;
|
||||
double x1234 = (x123 + x234) / 2;
|
||||
double y1234 = (y123 + y234) / 2;
|
||||
|
||||
|
||||
// Try to approximate the full cubic curve by a single straight line
|
||||
//------------------
|
||||
double dx = x4-x1;
|
||||
double dy = y4-y1;
|
||||
|
||||
double d2 = fabs(((x2 - x4) * dy - (y2 - y4) * dx));
|
||||
double d3 = fabs(((x3 - x4) * dy - (y3 - y4) * dx));
|
||||
double da1, da2, k;
|
||||
|
||||
switch(((int)(d2 > curve_collinearity_epsilon) << 1) +
|
||||
(int)(d3 > curve_collinearity_epsilon))
|
||||
{
|
||||
case 0:
|
||||
// All collinear OR p1==p4
|
||||
//----------------------
|
||||
k = dx*dx + dy*dy;
|
||||
if(k == 0)
|
||||
{
|
||||
d2 = CalcSqDistance(x1, y1, x2, y2);
|
||||
d3 = CalcSqDistance(x4, y4, x3, y3);
|
||||
}
|
||||
else
|
||||
{
|
||||
k = 1 / k;
|
||||
da1 = x2 - x1;
|
||||
da2 = y2 - y1;
|
||||
d2 = k * (da1*dx + da2*dy);
|
||||
da1 = x3 - x1;
|
||||
da2 = y3 - y1;
|
||||
d3 = k * (da1*dx + da2*dy);
|
||||
if(d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1)
|
||||
{
|
||||
// Simple collinear case, 1---2---3---4
|
||||
// We can leave just two endpoints
|
||||
return;
|
||||
}
|
||||
if(d2 <= 0)
|
||||
d2 = this->CalcSqDistance(x2, y2, x1, y1);
|
||||
else if(d2 >= 1)
|
||||
d2 = CalcSqDistance(x2, y2, x4, y4);
|
||||
else
|
||||
d2 = CalcSqDistance(x2, y2, x1 + d2*dx, y1 + d2*dy);
|
||||
|
||||
if(d3 <= 0)
|
||||
d3 = this->CalcSqDistance(x3, y3, x1, y1);
|
||||
else if(d3 >= 1)
|
||||
d3 = this->CalcSqDistance(x3, y3, x4, y4);
|
||||
else
|
||||
d3 = CalcSqDistance(x3, y3, x1 + d3*dx, y1 + d3*dy);
|
||||
}
|
||||
if(d2 > d3)
|
||||
{
|
||||
if(d2 < m_distance_tolerance_square)
|
||||
{
|
||||
|
||||
px.append(x2);
|
||||
py.append(y2);
|
||||
//m_points.add(point_d(x2, y2));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(d3 < m_distance_tolerance_square)
|
||||
{
|
||||
|
||||
px.append(x3);
|
||||
py.append(y3);
|
||||
//m_points.add(point_d(x3, y3));
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// p1,p2,p4 are collinear, p3 is significant
|
||||
//----------------------
|
||||
if(d3 * d3 <= m_distance_tolerance_square * (dx*dx + dy*dy))
|
||||
{
|
||||
if(m_angle_tolerance < curve_angle_tolerance_epsilon)
|
||||
{
|
||||
|
||||
px.append(x23);
|
||||
py.append(y23);
|
||||
//m_points.add(point_d(x23, y23));
|
||||
return;
|
||||
}
|
||||
|
||||
// Angle Condition
|
||||
//----------------------
|
||||
da1 = fabs(atan2(y4 - y3, x4 - x3) - atan2(y3 - y2, x3 - x2));
|
||||
if(da1 >= M_PI)
|
||||
da1 = 2*M_PI - da1;
|
||||
|
||||
if(da1 < m_angle_tolerance)
|
||||
{
|
||||
|
||||
px.append(x2);
|
||||
py.append(y2);
|
||||
|
||||
px.append(x3);
|
||||
py.append(y3);
|
||||
//m_points.add(point_d(x2, y2));
|
||||
//m_points.add(point_d(x3, y3));
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_cusp_limit != 0.0)
|
||||
{
|
||||
if(da1 > m_cusp_limit)
|
||||
{
|
||||
|
||||
px.append(x3);
|
||||
py.append(y3);
|
||||
//m_points.add(point_d(x3, y3));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// p1,p3,p4 are collinear, p2 is significant
|
||||
//----------------------
|
||||
if(d2 * d2 <= m_distance_tolerance_square * (dx*dx + dy*dy))
|
||||
{
|
||||
if(m_angle_tolerance < curve_angle_tolerance_epsilon)
|
||||
{
|
||||
|
||||
px.append(x23);
|
||||
py.append(y23);
|
||||
//m_points.add(point_d(x23, y23));
|
||||
return;
|
||||
}
|
||||
|
||||
// Angle Condition
|
||||
//----------------------
|
||||
da1 = fabs(atan2(y3 - y2, x3 - x2) - atan2(y2 - y1, x2 - x1));
|
||||
if(da1 >= M_PI) da1 = 2*M_PI - da1;
|
||||
|
||||
if(da1 < m_angle_tolerance)
|
||||
{
|
||||
|
||||
px.append(x2);
|
||||
py.append(y2);
|
||||
|
||||
px.append(x3);
|
||||
py.append(y3);
|
||||
//m_points.add(point_d(x2, y2));
|
||||
//m_points.add(point_d(x3, y3));
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_cusp_limit != 0.0)
|
||||
{
|
||||
if(da1 > m_cusp_limit)
|
||||
{
|
||||
px.append(x2);
|
||||
py.append(y2);
|
||||
|
||||
//m_points.add(point_d(x2, y2));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// Regular case
|
||||
//-----------------
|
||||
if((d2 + d3)*(d2 + d3) <= m_distance_tolerance_square * (dx*dx + dy*dy))
|
||||
{
|
||||
// If the curvature doesn't exceed the distance_tolerance value
|
||||
// we tend to finish subdivisions.
|
||||
//----------------------
|
||||
if(m_angle_tolerance < curve_angle_tolerance_epsilon)
|
||||
{
|
||||
|
||||
px.append(x23);
|
||||
py.append(y23);
|
||||
//m_points.add(point_d(x23, y23));
|
||||
return;
|
||||
}
|
||||
|
||||
// Angle & Cusp Condition
|
||||
//----------------------
|
||||
k = atan2(y3 - y2, x3 - x2);
|
||||
da1 = fabs(k - atan2(y2 - y1, x2 - x1));
|
||||
da2 = fabs(atan2(y4 - y3, x4 - x3) - k);
|
||||
if(da1 >= M_PI) da1 = 2*M_PI - da1;
|
||||
if(da2 >= M_PI) da2 = 2*M_PI - da2;
|
||||
|
||||
if(da1 + da2 < m_angle_tolerance)
|
||||
{
|
||||
// Finally we can stop the recursion
|
||||
//----------------------
|
||||
|
||||
px.append(x23);
|
||||
py.append(y23);
|
||||
//m_points.add(point_d(x23, y23));
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_cusp_limit != 0.0)
|
||||
{
|
||||
if(da1 > m_cusp_limit)
|
||||
{
|
||||
px.append(x2);
|
||||
py.append(y2);
|
||||
return;
|
||||
}
|
||||
|
||||
if(da2 > m_cusp_limit)
|
||||
{
|
||||
px.append(x3);
|
||||
py.append(y3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Continue subdivision
|
||||
//----------------------
|
||||
PointBezier_r(x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1, px, py);
|
||||
PointBezier_r(x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1, px, py);
|
||||
}
|
||||
|
||||
qreal VSpline::CalcSqDistance (qreal x1, qreal y1, qreal x2, qreal y2) const{
|
||||
qreal dx = x2 - x1;
|
||||
qreal dy = y2 - y1;
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
QPainterPath VSpline::GetPath() const{
|
||||
QPainterPath splinePath;
|
||||
QVector<QPointF> points = GetPoints ();
|
||||
splinePath.moveTo(points[0]);
|
||||
for (qint32 i = 1; i < points.count(); ++i){
|
||||
splinePath.lineTo(points[i]);
|
||||
}
|
||||
return splinePath;
|
||||
}
|
||||
|
||||
/* Cubic equation solution. Real coefficients case.
|
||||
|
||||
int Cubic(double *x,double a,double b,double c);
|
||||
Parameters:
|
||||
x - solution array (size 3). On output:
|
||||
3 real roots -> then x is filled with them;
|
||||
1 real + 2 complex -> x[0] is real, x[1] is real part of
|
||||
complex roots, x[2] - non-negative
|
||||
imaginary part.
|
||||
a, b, c - coefficients, as described
|
||||
Returns: 3 - 3 real roots;
|
||||
1 - 1 real root + 2 complex;
|
||||
2 - 1 real root + complex roots imaginary part is zero
|
||||
(i.e. 2 real roots).
|
||||
*/
|
||||
qint32 VSpline::Cubic(qreal *x, qreal a, qreal b, qreal c)const{
|
||||
qreal q,r,r2,q3;
|
||||
|
||||
q = (a*a - 3.*b)/9.;
|
||||
r = (a*(2.*a*a - 9.*b) + 27.*c)/54.;
|
||||
r2 = r*r;
|
||||
q3 = pow(q,3);
|
||||
if(r2<q3) {
|
||||
qreal t = acos(r/sqrt(q3));
|
||||
a/=3.;
|
||||
q = -2.*sqrt(q);
|
||||
x[0] = q*cos(t/3.)-a;
|
||||
x[1] = q*cos((t + M_2PI)/3.) - a;
|
||||
x[2] = q*cos((t - M_2PI)/3.) - a;
|
||||
return(3);
|
||||
} else {
|
||||
qreal aa,bb;
|
||||
if(r<=0.){
|
||||
r=-r;
|
||||
}
|
||||
aa = -pow(r + sqrt(r2-q3),1./3.);
|
||||
if(aa!=0.){
|
||||
bb=q/aa;
|
||||
} else {
|
||||
bb=0.;
|
||||
}
|
||||
a/=3.;
|
||||
q = aa+bb;
|
||||
r = aa-bb;
|
||||
x[0] = q-a;
|
||||
x[1] = (-0.5)*q-a;
|
||||
x[2] = (sqrt(3.)*0.5)*fabs(r);
|
||||
if(x[2]==0.){
|
||||
return(2);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
qreal VSpline::calc_t (qreal curve_coord1, qreal curve_coord2, qreal curve_coord3,
|
||||
qreal curve_coord4, qreal point_coord) const{
|
||||
qreal P1, P2, P3, P4, Bt;
|
||||
qreal a, b, c, d, ret_t;
|
||||
|
||||
qreal *t = (qreal *)malloc(3*sizeof(qreal));
|
||||
P1 = curve_coord1;
|
||||
P2 = curve_coord2;
|
||||
P3 = curve_coord3;
|
||||
P4 = curve_coord4;
|
||||
Bt = point_coord;
|
||||
|
||||
a = -P1 + 3*P2 - 3*P3 + P4;
|
||||
b = 3*P1 - 6*P2 + 3*P3;
|
||||
c = -3*P1 + 3*P2;
|
||||
d = -Bt + P1;
|
||||
|
||||
if(Cubic(t, b/a, c/a, d/a) == 3){
|
||||
ret_t = t[2];
|
||||
} else {
|
||||
ret_t = t[0];
|
||||
}
|
||||
/*
|
||||
* Повертається три значення, але експереминтально знайдено що шукане
|
||||
* значення знаходиться в третьому.
|
||||
*/
|
||||
|
||||
free(t);
|
||||
if(ret_t<0 || ret_t>1){
|
||||
qDebug()<<"Неправильне значення параметра. фунція calc_t";
|
||||
throw"Неправильне значення параметра. фунція calc_t";
|
||||
}
|
||||
return ret_t;
|
||||
}
|
||||
/*
|
||||
* Функція знаходить підходяще значення параметна t якому відповідає точка на сплайні.
|
||||
*/
|
||||
qreal VSpline::param_t (QPointF pBt)const{
|
||||
qreal t_x, t_y;
|
||||
t_x = calc_t (GetPointP1().x(), p2.x(), p3.x(), GetPointP4().x(), pBt.x());
|
||||
t_y = calc_t (GetPointP1().y(), p2.y(), p3.y(), GetPointP4().y(), pBt.y());
|
||||
/*
|
||||
* Порівнюємо значення по х і по у і визначаємо найбільше. Це значення і
|
||||
* буде шуканим.
|
||||
*/
|
||||
if(t_x>t_y)
|
||||
return t_x;
|
||||
else
|
||||
return t_y;
|
||||
}
|
||||
|
||||
//void VSpline::Mirror(const QPointF Pmirror){
|
||||
// QPointF P1 = p1;
|
||||
// P1 = QPointF(P1.x() - Pmirror.x(), P1.y() - Pmirror.y());
|
||||
// P1 = QPointF(P1.x() * -1.0, P1.y() * 1.0);
|
||||
// P1 = QPointF(P1.x() + Pmirror.x(), P1.y() + Pmirror.y());
|
||||
// QPointF P2 = p2;
|
||||
// P2 = QPointF(P2.x() - Pmirror.x(), P2.y() - Pmirror.y());
|
||||
// P2 = QPointF(P2.x() * -1.0, P2.y() * 1.0);
|
||||
// P2 = QPointF(P2.x() + Pmirror.x(), P2.y() + Pmirror.y());
|
||||
// QPointF P3 = p3;
|
||||
// P3 = QPointF(P3.x() - Pmirror.x(), P3.y() - Pmirror.y());
|
||||
// P3 = QPointF(P3.x() * -1.0, P3.y() * 1.0);
|
||||
// P3 = QPointF(P3.x() + Pmirror.x(), P3.y() + Pmirror.y());
|
||||
// QPointF P4 = p4;
|
||||
// P4 = QPointF(P4.x() - Pmirror.x(), P4.y() - Pmirror.y());
|
||||
// P4 = QPointF(P4.x() * -1.0, P4.y() * 1.0);
|
||||
// P4 = QPointF(P4.x() + Pmirror.x(), P4.y() + Pmirror.y());
|
||||
// this->ModifiSpl(P1, P2, P3, P4);
|
||||
//}
|
261
geometry/vspline.h
Normal file
261
geometry/vspline.h
Normal file
|
@ -0,0 +1,261 @@
|
|||
#ifndef VSPLINE_H
|
||||
#define VSPLINE_H
|
||||
|
||||
#define M_2PI 6.28318530717958647692528676655900576
|
||||
|
||||
#include <QPainterPath>
|
||||
#include <QVector>
|
||||
#include <QMap>
|
||||
#include "container/vpointf.h"
|
||||
|
||||
/**
|
||||
* @brief VSpline клас, що реалізує сплайн.
|
||||
*/
|
||||
class VSpline{
|
||||
public:
|
||||
VSpline();
|
||||
/**
|
||||
* @brief VSpline конструктор.
|
||||
* @param spline сплайн з якого копіюємо.
|
||||
*/
|
||||
VSpline (const VSpline &spline );
|
||||
/**
|
||||
* @brief VSpline конструктор.
|
||||
* @param p1 початкова точка сплайна.
|
||||
* @param p4 кінцева точка сплайна.
|
||||
* @param angle1 кут в градусах першої напрямної.
|
||||
* @param angle2 кут в градусах другої напрямної.
|
||||
* @param kCurve коефіцієнт кривизни сплайна.
|
||||
* @param kAsm1 коефіцієнт довжини першої напрямної.
|
||||
* @param kAsm2 коефіцієнт довжини другої напрямної.
|
||||
*/
|
||||
VSpline (const QMap<qint64, VPointF> *points, qint64 p1, qint64 p4, qreal angle1,
|
||||
qreal angle2, qreal kAsm1, qreal kAsm2, qreal kCurve);
|
||||
/**
|
||||
* @brief VSpline конструктор.
|
||||
* @param p1 початкова точка сплайну.
|
||||
* @param p2 перша контролююча точка сплайну.
|
||||
* @param p3 друга контролююча точка сплайну.
|
||||
* @param p4 кінцева точка сплайну.
|
||||
*/
|
||||
VSpline (const QMap<qint64, VPointF> *points, qint64 p1, QPointF p2, QPointF p3,
|
||||
qint64 p4, qreal kCurve);
|
||||
/**
|
||||
* @brief ModifiSpl модифікує сплайн.
|
||||
* @param p1 початкова точка сплайну.
|
||||
* @param p4 кінцева точка сплайну.
|
||||
* @param angle1 кут в градусах першої напрямної.
|
||||
* @param angle2 кут в градусах другої напрямної.
|
||||
* @param kCurve коефіцієнт кривизни сплайну.
|
||||
* @param kAsm1 коефіцієнт довжини першої напрямної.
|
||||
* @param kAsm2 коефіцієнт довжини другої напрямної.
|
||||
*/
|
||||
void ModifiSpl ( qint64 p1, qint64 p4, qreal angle1, qreal angle2, qreal kAsm1, qreal kAsm2,
|
||||
qreal kCurve);
|
||||
/**
|
||||
* @brief ModifiSpl модифікує сплайн.
|
||||
* @param p1 початкова точка сплайну.
|
||||
* @param p2 перша контролююча точка сплайну.
|
||||
* @param p3 друга контролююча точка сплайну.
|
||||
* @param p4 кінцева точка сплайну.
|
||||
*/
|
||||
void ModifiSpl (qint64 p1, QPointF p2, QPointF p3, qint64 p4, qreal kCurve);
|
||||
/**
|
||||
* @brief RotationSpl поворот сплайна навколо точки на кут в градусах проти годиникової стрілки.
|
||||
* @param pRotate точка навколо якої повертаємо.
|
||||
* @param angle кут в градусах.
|
||||
*/
|
||||
// void RotationSpl ( QPointF pRotate, qreal angle );
|
||||
/**
|
||||
* @brief BiasSpl зміщує сплайн.
|
||||
* @param mx зміщення по х координаті.
|
||||
* @param my зміщення по у координаті.
|
||||
*/
|
||||
// void BiasSpl ( qreal mx, qreal my );
|
||||
/**
|
||||
* @brief GetP1 повертає першу точку сплайну.
|
||||
* @return перша точка сплайну.
|
||||
*/
|
||||
qint64 GetP1 () const;
|
||||
VPointF GetPointP1() const;
|
||||
/**
|
||||
* @brief GetP2 повертує першу контрольну точку сплайну.
|
||||
* @return перша контрольна точка сплайну.
|
||||
*/
|
||||
QPointF GetP2 () const;
|
||||
/**
|
||||
* @brief GetP3 повертає другу контрольну точку сплайну.
|
||||
* @return друга контрольна точка сплайну.
|
||||
*/
|
||||
QPointF GetP3 () const;
|
||||
/**
|
||||
* @brief GetP4 повертає останню точку сплайну.
|
||||
* @return остання точка сплайну.
|
||||
*/
|
||||
qint64 GetP4 () const;
|
||||
VPointF GetPointP4 () const;
|
||||
/**
|
||||
* @brief GetAngle1 повертає кут першої напрямної.
|
||||
* @return кут в градусах.
|
||||
*/
|
||||
qreal GetAngle1 () const;
|
||||
/**
|
||||
* @brief GetAngle2 повертає кут другої напрямної.
|
||||
* @return кут в градусах.
|
||||
*/
|
||||
qreal GetAngle2() const;
|
||||
/**
|
||||
* @brief GetLength повертає довжину сплайну.
|
||||
* @return довжина сплайну.
|
||||
*/
|
||||
qreal GetLength () const;
|
||||
QString GetName () const;
|
||||
qreal GetKasm1() const;
|
||||
qreal GetKasm2() const;
|
||||
qreal GetKcurve() const;
|
||||
const QMap<qint64, VPointF> *GetDataPoints() const;
|
||||
/**
|
||||
* @brief CrossingSplLine перевіряє перетин сплайну з лінією.
|
||||
* @param line лінія з якою перевіряється перетин.
|
||||
* @param intersectionPoint точка перетину.
|
||||
* @return результат перевірки.
|
||||
*/
|
||||
QLineF::IntersectType CrossingSplLine(const QLineF &line, QPointF *intersectionPoint ) const;
|
||||
/**
|
||||
* @brief CutSpline розрізає сплайн.
|
||||
* @param length дожина першого сплайну.
|
||||
* @param curFir перший сплайн.
|
||||
* @param curSec другий сплайн.
|
||||
*/
|
||||
// void CutSpline ( qreal length, VSpline* curFir, VSpline* curSec ) const;
|
||||
/**
|
||||
* @brief CutSpline розрізає сплайн.
|
||||
* @param point точка що ділить сплайн.
|
||||
* @param curFir перший сплайн.
|
||||
* @param curSec другий сплайн.
|
||||
*/
|
||||
// void CutSpline (QPointF point, VSpline* curFir, VSpline* curSec ) const;
|
||||
/**
|
||||
* @brief PutAlongSpl розміщає точку на сплайні.
|
||||
* @param moveP точка яка розміщується на сплайні.
|
||||
* @param move довжина від початку сплайну.
|
||||
*/
|
||||
void PutAlongSpl ( QPointF &moveP, qreal move ) const;
|
||||
/**
|
||||
* @brief GetPoints повертає точки з яких складається сплайн.
|
||||
* @return список точок.
|
||||
*/
|
||||
QVector<QPointF> GetPoints () const;
|
||||
/**
|
||||
* @brief GetPath повертає шлях сплайну.
|
||||
* @return шлях.
|
||||
*/
|
||||
QPainterPath GetPath() const;
|
||||
/**
|
||||
* @brief Mirror вертикальне дзеркалення сплайну відносно точки.
|
||||
* @param Pmirror точка відносно якої відбувається вертикальне дзеркалення сплайну.
|
||||
*/
|
||||
// void Mirror(const QPointF Pmirror);
|
||||
protected:
|
||||
/**
|
||||
* @brief GetPoints повертає точки з яких складається сплайн.
|
||||
* @param p1 початкова точка сплайну.
|
||||
* @param p2 перша контролююча точка сплайну.
|
||||
* @param p3 друга контролююча точка сплайну.
|
||||
* @param p4 кінцева точка сплайну.
|
||||
* @return список точок.
|
||||
*/
|
||||
QVector<QPointF> GetPoints ( QPointF p1, QPointF p2, QPointF p3, QPointF p4 ) const;
|
||||
private:
|
||||
/**
|
||||
* @brief p1 початкова точка сплайну
|
||||
*/
|
||||
qint64 p1; // перша точка
|
||||
/**
|
||||
* @brief p2 перша контрольна точка сплайну.
|
||||
*/
|
||||
QPointF p2; // друга точка
|
||||
/**
|
||||
* @brief p3 друга контрольна точка сплайну.
|
||||
*/
|
||||
QPointF p3; // третя точка
|
||||
/**
|
||||
* @brief p4 кінцеві точка сплайну.
|
||||
*/
|
||||
qint64 p4; // четверта точка
|
||||
/**
|
||||
* @brief angle1 кут в градусах першої напрямної.
|
||||
*/
|
||||
qreal angle1; // кут нахилу дотичної в першій точці
|
||||
/**
|
||||
* @brief angle2 кут в градусах другої напрямної.
|
||||
*/
|
||||
qreal angle2; // кут нахилу дотичної в другій точці
|
||||
qreal kAsm1;
|
||||
qreal kAsm2;
|
||||
qreal kCurve;
|
||||
const QMap<qint64, VPointF> *points;
|
||||
/**
|
||||
* @brief LengthBezier повертає дожину сплайну за його чотирьма точками.
|
||||
* @param p1 початкова точка сплайну.
|
||||
* @param p2 перша контролююча точка сплайну.
|
||||
* @param p3 друга контролююча точка сплайну.
|
||||
* @param p4 кінцева точка сплайну.
|
||||
* @return дожина сплайну.
|
||||
*/
|
||||
qreal LengthBezier ( QPointF p1, QPointF p2, QPointF p3, QPointF p4 ) const;
|
||||
/**
|
||||
* @brief PointBezier_r знаходить точки сплайну по його чотирьом точках.
|
||||
* @param x1 х координата першої точки сплайну.
|
||||
* @param y1 у координата другої точки сплайну.
|
||||
* @param x2 х координата першої контрольної точки сплайну.
|
||||
* @param y2 у координата першої контрольної точки сплайну.
|
||||
* @param x3 х координата другої контрольної точки сплайну.
|
||||
* @param y3 у координата другої контрольної точки сплайну.
|
||||
* @param x4 х координата кінцевої точки сплайну.
|
||||
* @param y4 у координата кінцевої точки сплайну.
|
||||
* @param level рівень рекурсії. Напочатку повинен дорівнювати 0.
|
||||
* @param px список х координат точок сплайну.
|
||||
* @param py список у коодринат сплайну.
|
||||
*/
|
||||
void PointBezier_r ( qreal x1, qreal y1, qreal x2, qreal y2,
|
||||
qreal x3, qreal y3, qreal x4, qreal y4,
|
||||
qint16 level, QVector<qreal> &px, QVector<qreal> &py) const;
|
||||
/**
|
||||
* @brief CalcSqDistance розраховує довжину між точками.
|
||||
* @param x1 х координата першої точки.
|
||||
* @param y1 у координата другої точки.
|
||||
* @param x2 х координата першої точки.
|
||||
* @param y2 у координата другої точки.
|
||||
* @return довжину.
|
||||
*/
|
||||
qreal CalcSqDistance ( qreal x1, qreal y1, qreal x2, qreal y2) const;
|
||||
/**
|
||||
* @brief Cubic знаходить розв'язок кубічного рівняння.
|
||||
* @param x коефіцієнт.
|
||||
* @param a коефіцієнт.
|
||||
* @param b коефіцієнт.
|
||||
* @param c коефіцієнт.
|
||||
* @return повертає корені рівняння.
|
||||
*/
|
||||
qint32 Cubic(qreal *x, qreal a, qreal b, qreal c)const;
|
||||
/**
|
||||
* @brief calc_t знаходить параметр t якому відповідає точка на сплайні.
|
||||
* @param curve_coord1 координата Х або У кривої.
|
||||
* @param curve_coord2 координата Х або У кривої.
|
||||
* @param curve_coord3 координата Х або У кривої.
|
||||
* @param curve_coord4 координата Х або У кривої.
|
||||
* @param point_coord координата Х або У точки на кривій.
|
||||
* @return
|
||||
*/
|
||||
qreal calc_t (qreal curve_coord1, qreal curve_coord2, qreal curve_coord3,
|
||||
qreal curve_coord4, qreal point_coord)const;
|
||||
/**
|
||||
* @brief param_t знаходить підходяще значення параметра t якому відповідає точка на сплайні
|
||||
* @param pBt точка для якої шукається значення параметра t.
|
||||
* @return підходяще значення t.
|
||||
*/
|
||||
qreal param_t (QPointF pBt)const;
|
||||
};
|
||||
|
||||
#endif // VSPLINE_H
|
1
icon.qrc
1
icon.qrc
|
@ -25,5 +25,6 @@
|
|||
<file>icon/32x32/normal.png</file>
|
||||
<file>icon/32x32/bisector.png</file>
|
||||
<file>icon/32x32/intersect.png</file>
|
||||
<file>icon/32x32/spline.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
BIN
icon/32x32/spline.png
Normal file
BIN
icon/32x32/spline.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 375 B |
|
@ -18,6 +18,8 @@
|
|||
#include "tools/vtoolnormal.h"
|
||||
#include "tools/vtoolbisector.h"
|
||||
#include "tools/vtoollineintersect.h"
|
||||
#include "tools/vtoolspline.h"
|
||||
#include "geometry/vspline.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent), ui(new Ui::MainWindow)
|
||||
|
@ -61,6 +63,8 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
&MainWindow::ToolBisector);
|
||||
connect(ui->toolButtonLineIntersect, &QToolButton::clicked, this,
|
||||
&MainWindow::ToolLineIntersect);
|
||||
connect(ui->toolButtonSpline, &QToolButton::clicked, this,
|
||||
&MainWindow::ToolSpline);
|
||||
|
||||
data = new VContainer;
|
||||
CreateManTableIGroup ();
|
||||
|
@ -181,7 +185,7 @@ void MainWindow::ToolEndLine(bool checked){
|
|||
helpLabel->setText("Заповніть усі поля.");
|
||||
dialogEndLine = new DialogEndLine(data, this);
|
||||
connect(scene, &VMainGraphicsScene::ChoosedObject, dialogEndLine,
|
||||
&DialogEndLine::ChoosedPoint);
|
||||
&DialogEndLine::ChoosedObject);
|
||||
connect(dialogEndLine, &DialogEndLine::DialogClosed, this,
|
||||
&MainWindow::ClosedDialogEndLine);
|
||||
connect(doc, &VDomDocument::FullUpdateFromFile, dialogEndLine, &DialogEndLine::UpdateList);
|
||||
|
@ -211,7 +215,7 @@ void MainWindow::ClosedDialogEndLine(int result){
|
|||
VToolEndLine *point = new VToolEndLine(doc, data, id, typeLine, formula, angle, basePointId,
|
||||
Tool::FromGui);
|
||||
scene->addItem(point);
|
||||
connect(point, &VToolPoint::ChoosedPoint, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
connect(point, &VToolPoint::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -227,7 +231,7 @@ void MainWindow::ToolLine(bool checked){
|
|||
ui->graphicsView->setCursor(cur);
|
||||
helpLabel->setText("Виберіть точки.");
|
||||
dialogLine = new DialogLine(data, this);
|
||||
connect(scene, &VMainGraphicsScene::ChoosedObject, dialogLine, &DialogLine::ChoosedPoint);
|
||||
connect(scene, &VMainGraphicsScene::ChoosedObject, dialogLine, &DialogLine::ChoosedObject);
|
||||
connect(dialogLine, &DialogLine::DialogClosed, this, &MainWindow::ClosedDialogLine);
|
||||
} else {
|
||||
ui->toolButtonLine->setChecked(true);
|
||||
|
@ -243,7 +247,7 @@ void MainWindow::ClosedDialogLine(int result){
|
|||
qint64 id = data->getNextId();
|
||||
VToolLine *line = new VToolLine(doc, data, id, firstPoint, secondPoint, Tool::FromGui);
|
||||
scene->addItem(line);
|
||||
connect(line, &VToolLine::ChoosedPoint, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
connect(line, &VToolLine::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
|
||||
}
|
||||
ArrowTool();
|
||||
|
@ -258,7 +262,7 @@ void MainWindow::ToolAlongLine(bool checked){
|
|||
ui->graphicsView->setCursor(cur);
|
||||
helpLabel->setText("Виберіть точки.");
|
||||
dialogAlongLine = new DialogAlongLine(data, this);
|
||||
connect(scene, &VMainGraphicsScene::ChoosedObject, dialogAlongLine, &DialogAlongLine::ChoosedPoint);
|
||||
connect(scene, &VMainGraphicsScene::ChoosedObject, dialogAlongLine, &DialogAlongLine::ChoosedObject);
|
||||
connect(dialogAlongLine, &DialogLine::DialogClosed, this, &MainWindow::ClosedDialogAlongLine);
|
||||
} else {
|
||||
ui->toolButtonAlongLine->setChecked(true);
|
||||
|
@ -287,7 +291,7 @@ void MainWindow::ClosedDialogAlongLine(int result){
|
|||
VToolAlongLine *point = new VToolAlongLine(doc, data, id, formula, firstPointId, secondPointId,
|
||||
typeLine, Tool::FromGui);
|
||||
scene->addItem(point);
|
||||
connect(point, &VToolAlongLine::ChoosedPoint, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
connect(point, &VToolAlongLine::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
}
|
||||
}
|
||||
ArrowTool();
|
||||
|
@ -303,7 +307,7 @@ void MainWindow::ToolShoulderPoint(bool checked){
|
|||
helpLabel->setText("Виберіть точки.");
|
||||
dialogShoulderPoint = new DialogShoulderPoint(data, this);
|
||||
connect(scene, &VMainGraphicsScene::ChoosedObject, dialogShoulderPoint,
|
||||
&DialogShoulderPoint::ChoosedPoint);
|
||||
&DialogShoulderPoint::ChoosedObject);
|
||||
connect(dialogShoulderPoint, &DialogShoulderPoint::DialogClosed, this,
|
||||
&MainWindow::ClosedDialogShoulderPoint);
|
||||
} else {
|
||||
|
@ -336,7 +340,7 @@ void MainWindow::ClosedDialogShoulderPoint(int result){
|
|||
VToolShoulderPoint *point = new VToolShoulderPoint(doc, data, id, typeLine, formula, p1Line,
|
||||
p2Line, pShoulder, Tool::FromGui);
|
||||
scene->addItem(point);
|
||||
connect(point, &VToolShoulderPoint::ChoosedPoint, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
connect(point, &VToolShoulderPoint::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
}
|
||||
}
|
||||
ArrowTool();
|
||||
|
@ -352,7 +356,7 @@ void MainWindow::ToolNormal(bool checked){
|
|||
helpLabel->setText("Виберіть точки.");
|
||||
dialogNormal = new DialogNormal(data, this);
|
||||
connect(scene, &VMainGraphicsScene::ChoosedObject, dialogNormal,
|
||||
&DialogNormal::ChoosedPoint);
|
||||
&DialogNormal::ChoosedObject);
|
||||
connect(dialogNormal, &DialogNormal::DialogClosed, this,
|
||||
&MainWindow::ClosedDialogNormal);
|
||||
} else {
|
||||
|
@ -383,7 +387,7 @@ void MainWindow::ClosedDialogNormal(int result){
|
|||
VToolNormal *point = new VToolNormal(doc, data, id, typeLine, formula, angle, firstPointId,
|
||||
secondPointId, Tool::FromGui);
|
||||
scene->addItem(point);
|
||||
connect(point, &VToolNormal::ChoosedPoint, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
connect(point, &VToolNormal::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
}
|
||||
}
|
||||
ArrowTool();
|
||||
|
@ -399,7 +403,7 @@ void MainWindow::ToolBisector(bool checked){
|
|||
helpLabel->setText("Виберіть точки.");
|
||||
dialogBisector = new DialogBisector(data, this);
|
||||
connect(scene, &VMainGraphicsScene::ChoosedObject, dialogBisector,
|
||||
&DialogBisector::ChoosedPoint);
|
||||
&DialogBisector::ChoosedObject);
|
||||
connect(dialogBisector, &DialogBisector::DialogClosed, this,
|
||||
&MainWindow::ClosedDialogBisector);
|
||||
} else {
|
||||
|
@ -431,7 +435,7 @@ void MainWindow::ClosedDialogBisector(int result){
|
|||
VToolBisector *point = new VToolBisector(doc, data, id, typeLine, formula, firstPointId,
|
||||
secondPointId, thirdPointId, Tool::FromGui);
|
||||
scene->addItem(point);
|
||||
connect(point, &VToolBisector::ChoosedPoint, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
connect(point, &VToolBisector::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
}
|
||||
}
|
||||
ArrowTool();
|
||||
|
@ -447,7 +451,7 @@ void MainWindow::ToolLineIntersect(bool checked){
|
|||
helpLabel->setText("Виберіть точки.");
|
||||
dialogLineIntersect = new DialogLineIntersect(data, this);
|
||||
connect(scene, &VMainGraphicsScene::ChoosedObject, dialogLineIntersect,
|
||||
&DialogLineIntersect::ChoosedPoint);
|
||||
&DialogLineIntersect::ChoosedObject);
|
||||
connect(dialogLineIntersect, &DialogLineIntersect::DialogClosed, this,
|
||||
&MainWindow::ClosedDialogLineIntersect);
|
||||
} else {
|
||||
|
@ -480,14 +484,52 @@ void MainWindow::ClosedDialogLineIntersect(int result){
|
|||
data->AddLine(id, p2Line2Id);
|
||||
VToolLineIntersect *point = new VToolLineIntersect(doc, data, id, p1Line1Id,
|
||||
p2Line1Id, p1Line2Id,
|
||||
p2Line2Id, Tool::FromFile);
|
||||
p2Line2Id, Tool::FromGui);
|
||||
scene->addItem(point);
|
||||
connect(point, &VToolLineIntersect::ChoosedPoint, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
connect(point, &VToolLineIntersect::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
}
|
||||
}
|
||||
ArrowTool();
|
||||
}
|
||||
|
||||
void MainWindow::ToolSpline(bool checked){
|
||||
if(checked){
|
||||
CanselTool();
|
||||
tool = Tools::SplineTool;
|
||||
QPixmap pixmap(":/cursor/spline_cursor.png");
|
||||
QCursor cur(pixmap, 2, 3);
|
||||
ui->graphicsView->setCursor(cur);
|
||||
helpLabel->setText("Виберіть точки.");
|
||||
dialogSpline = new DialogSpline(data, this);
|
||||
connect(scene, &VMainGraphicsScene::ChoosedObject, dialogSpline,
|
||||
&DialogSpline::ChoosedObject);
|
||||
connect(dialogSpline, &DialogSpline::DialogClosed, this,
|
||||
&MainWindow::ClosedDialogSpline);
|
||||
} else {
|
||||
ui->toolButtonSpline->setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::ClosedDialogSpline(int result){
|
||||
if(result == QDialog::Accepted){
|
||||
qint64 p1 = dialogSpline->getP1();
|
||||
qint64 p4 = dialogSpline->getP4();
|
||||
qreal kAsm1 = dialogSpline->getKAsm1();
|
||||
qreal kAsm2 = dialogSpline->getKAsm2();
|
||||
qreal angle1 = dialogSpline->getAngle1();
|
||||
qreal angle2 = dialogSpline->getAngle2();
|
||||
qreal kCurve = dialogSpline->getKCurve();
|
||||
|
||||
VSpline spline = VSpline(data->DataPoints(), p1, p4, angle1, angle2, kAsm1, kAsm2, kCurve);
|
||||
qint64 id = data->AddSpline(spline);
|
||||
data->AddLengthSpline(data->GetNameSpline(p1, p4), spline.GetLength());
|
||||
VToolSpline *spl = new VToolSpline(doc, data, id, Tool::FromGui);
|
||||
scene->addItem(spl);
|
||||
connect(spl, &VToolSpline::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
}
|
||||
ArrowTool();
|
||||
}
|
||||
|
||||
void MainWindow::showEvent( QShowEvent *event ){
|
||||
QMainWindow::showEvent( event );
|
||||
if( event->spontaneous() ){
|
||||
|
@ -638,6 +680,12 @@ void MainWindow::CanselTool(){
|
|||
scene->setFocus(Qt::OtherFocusReason);
|
||||
scene->clearSelection();
|
||||
break;
|
||||
case Tools::SplineTool:
|
||||
delete dialogSpline;
|
||||
ui->toolButtonSpline->setChecked(false);
|
||||
scene->setFocus(Qt::OtherFocusReason);
|
||||
scene->clearSelection();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -668,9 +716,9 @@ void MainWindow::ClosedDialogSinglePoint(int result){
|
|||
QPointF point = dialogSinglePoint->getPoint();
|
||||
QString name = dialogSinglePoint->getName();
|
||||
qint64 id = data->AddPoint(VPointF(point.x(), point.y(), name, 5, 10));
|
||||
VToolSimplePoint *spoint = new VToolSimplePoint(doc, data, id, Tool::FromGui);
|
||||
VToolSinglePoint *spoint = new VToolSinglePoint(doc, data, id, Tool::FromGui);
|
||||
scene->addItem(spoint);
|
||||
connect(spoint, &VToolPoint::ChoosedPoint, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
connect(spoint, &VToolPoint::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
ArrowTool();
|
||||
ui->toolButtonSinglePoint->setEnabled(false);
|
||||
qint32 index = comboBoxDraws->currentIndex();
|
||||
|
@ -900,6 +948,7 @@ void MainWindow::SetEnableTool(bool enable){
|
|||
ui->toolButtonNormal->setEnabled(enable);
|
||||
ui->toolButtonBisector->setEnabled(enable);
|
||||
ui->toolButtonLineIntersect->setEnabled(enable);
|
||||
ui->toolButtonSpline->setEnabled(enable);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow(){
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
#include "dialogs/dialognormal.h"
|
||||
#include "dialogs/dialogbisector.h"
|
||||
#include "dialogs/dialoglineintersect.h"
|
||||
#include "tools/vtoolsimplepoint.h"
|
||||
#include "dialogs/dialogspline.h"
|
||||
#include "tools/vtoolsinglepoint.h"
|
||||
#include "xml/vdomdocument.h"
|
||||
#include "container/vcontainer.h"
|
||||
|
||||
|
@ -36,7 +37,8 @@ namespace Tools{
|
|||
ShoulderPointTool,
|
||||
NormalTool,
|
||||
BisectorTool,
|
||||
LineIntersectTool
|
||||
LineIntersectTool,
|
||||
SplineTool
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -79,6 +81,8 @@ public slots:
|
|||
void ClosedDialogBisector(int result);
|
||||
void ToolLineIntersect(bool checked);
|
||||
void ClosedDialogLineIntersect(int result);
|
||||
void ToolSpline(bool checked);
|
||||
void ClosedDialogSpline(int result);
|
||||
protected:
|
||||
virtual void keyPressEvent ( QKeyEvent * event );
|
||||
virtual void showEvent( QShowEvent *event );
|
||||
|
@ -98,6 +102,7 @@ private:
|
|||
DialogNormal *dialogNormal;
|
||||
DialogBisector *dialogBisector;
|
||||
DialogLineIntersect *dialogLineIntersect;
|
||||
DialogSpline *dialogSpline;
|
||||
VDomDocument *doc;
|
||||
VContainer *data;
|
||||
QComboBox *comboBoxDraws;
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
</sizepolicy>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page">
|
||||
<property name="geometry">
|
||||
|
@ -297,7 +297,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>154</width>
|
||||
<height>45</height>
|
||||
<height>58</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
@ -311,9 +311,25 @@
|
|||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="pushButton_7">
|
||||
<widget class="QToolButton" name="toolButtonSpline">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="icon.qrc">
|
||||
<normaloff>:/icon/32x32/spline.png</normaloff>:/icon/32x32/spline.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -27,7 +27,7 @@ public slots:
|
|||
virtual void FullUpdateFromGui(int result)=0;
|
||||
signals:
|
||||
void haveLiteChange();
|
||||
void ChoosedPoint(qint64 id, Scene::Type type);
|
||||
void ChoosedTool(qint64 id, Scene::Type type);
|
||||
void FullUpdateTree();
|
||||
protected:
|
||||
VDomDocument *doc;
|
||||
|
|
|
@ -52,7 +52,7 @@ void VToolAlongLine::contextMenuEvent(QGraphicsSceneContextMenuEvent *event){
|
|||
dialogAlongLine = QSharedPointer<DialogAlongLine>(new DialogAlongLine(VAbstractTool::data));
|
||||
|
||||
connect(qobject_cast< VMainGraphicsScene * >(this->scene()), &VMainGraphicsScene::ChoosedObject,
|
||||
dialogAlongLine.data(), &DialogAlongLine::ChoosedPoint);
|
||||
dialogAlongLine.data(), &DialogAlongLine::ChoosedObject);
|
||||
connect(dialogAlongLine.data(), &DialogAlongLine::DialogClosed, this,
|
||||
&VToolAlongLine::FullUpdateFromGui);
|
||||
connect(doc, &VDomDocument::FullUpdateFromFile, dialogAlongLine.data(),
|
||||
|
|
|
@ -63,7 +63,7 @@ void VToolBisector::contextMenuEvent(QGraphicsSceneContextMenuEvent *event){
|
|||
dialogBisector = QSharedPointer<DialogBisector>(new DialogBisector(VAbstractTool::data));
|
||||
|
||||
connect(qobject_cast< VMainGraphicsScene * >(this->scene()), &VMainGraphicsScene::ChoosedObject,
|
||||
dialogBisector.data(), &DialogBisector::ChoosedPoint);
|
||||
dialogBisector.data(), &DialogBisector::ChoosedObject);
|
||||
connect(dialogBisector.data(), &DialogBisector::DialogClosed, this,
|
||||
&VToolBisector::FullUpdateFromGui);
|
||||
connect(doc, &VDomDocument::FullUpdateFromFile, dialogBisector.data(),
|
||||
|
|
|
@ -34,7 +34,7 @@ void VToolEndLine::contextMenuEvent(QGraphicsSceneContextMenuEvent *event){
|
|||
dialogEndLine = QSharedPointer<DialogEndLine>(new DialogEndLine(VAbstractTool::data));
|
||||
|
||||
connect(qobject_cast< VMainGraphicsScene * >(this->scene()), &VMainGraphicsScene::ChoosedObject,
|
||||
dialogEndLine.data(), &DialogEndLine::ChoosedPoint);
|
||||
dialogEndLine.data(), &DialogEndLine::ChoosedObject);
|
||||
connect(dialogEndLine.data(), &DialogEndLine::DialogClosed, this,
|
||||
&VToolEndLine::FullUpdateFromGui);
|
||||
connect(doc, &VDomDocument::FullUpdateFromFile, dialogEndLine.data(), &DialogEndLine::UpdateList);
|
||||
|
@ -84,3 +84,4 @@ void VToolEndLine::AddToFile(){
|
|||
|
||||
AddToCalculation(domElement);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ void VToolLine::contextMenuEvent(QGraphicsSceneContextMenuEvent *event){
|
|||
dialogLine = QSharedPointer<DialogLine>(new DialogLine(VAbstractTool::data));
|
||||
|
||||
connect(qobject_cast< VMainGraphicsScene * >(this->scene()), &VMainGraphicsScene::ChoosedObject,
|
||||
dialogLine.data(), &DialogLine::ChoosedPoint);
|
||||
dialogLine.data(), &DialogLine::ChoosedObject);
|
||||
connect(dialogLine.data(), &DialogLine::DialogClosed, this, &VToolLine::FullUpdateFromGui);
|
||||
|
||||
dialogLine->setFirstPoint(firstPoint);
|
||||
|
|
|
@ -49,7 +49,7 @@ void VToolLineIntersect::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
|
|||
dialogLineIntersect = QSharedPointer<DialogLineIntersect>(new DialogLineIntersect(VAbstractTool::data));
|
||||
|
||||
connect(qobject_cast< VMainGraphicsScene * >(this->scene()), &VMainGraphicsScene::ChoosedObject,
|
||||
dialogLineIntersect.data(), &DialogLineIntersect::ChoosedPoint);
|
||||
dialogLineIntersect.data(), &DialogLineIntersect::ChoosedObject);
|
||||
connect(dialogLineIntersect.data(), &DialogLineIntersect::DialogClosed, this,
|
||||
&VToolLineIntersect::FullUpdateFromGui);
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ void VToolNormal::contextMenuEvent(QGraphicsSceneContextMenuEvent *event){
|
|||
dialogNormal = QSharedPointer<DialogNormal>(new DialogNormal(VAbstractTool::data));
|
||||
|
||||
connect(qobject_cast< VMainGraphicsScene * >(this->scene()), &VMainGraphicsScene::ChoosedObject,
|
||||
dialogNormal.data(), &DialogNormal::ChoosedPoint);
|
||||
dialogNormal.data(), &DialogNormal::ChoosedObject);
|
||||
connect(dialogNormal.data(), &DialogNormal::DialogClosed, this,
|
||||
&VToolNormal::FullUpdateFromGui);
|
||||
connect(doc, &VDomDocument::FullUpdateFromFile, dialogNormal.data(), &DialogNormal::UpdateList);
|
||||
|
|
|
@ -52,66 +52,6 @@ void VToolPoint::NameChangePosition(const QPointF pos){
|
|||
VAbstractTool::data->UpdatePoint(id, point);
|
||||
}
|
||||
|
||||
/*
|
||||
* Взято з сайту http://hardfire.ru/cross_line_circle
|
||||
*/
|
||||
qint32 VToolPoint::LineIntersectCircle(QPointF center, qreal radius, QLineF line, QPointF &p1,
|
||||
QPointF &p2) const{
|
||||
const qreal eps = 1e-8;
|
||||
//коефіцієнти для рівняння відрізку
|
||||
qreal a = line.p2().y() - line.p1().y();
|
||||
qreal b = line.p1().x() - line.p2().x();
|
||||
// В даному випадку не використовується.
|
||||
//qreal c = - a * line.p1().x() - b * line.p1().y();
|
||||
// проекция центра окружности на прямую
|
||||
QPointF p = ClosestPoint (line, center);
|
||||
// сколько всего решений?
|
||||
qint32 flag = 0;
|
||||
qreal d = QLineF (center, p).length();
|
||||
if (qAbs (d - radius) <= eps){
|
||||
flag = 1;
|
||||
} else {
|
||||
if (radius > d){
|
||||
flag = 2;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// находим расстояние от проекции до точек пересечения
|
||||
qreal k = sqrt (radius * radius - d * d);
|
||||
qreal t = QLineF (QPointF (0, 0), QPointF (b, - a)).length();
|
||||
// добавляем к проекции векторы направленные к точкам пеерсечения
|
||||
p1 = add_vector (p, QPointF (0, 0), QPointF (- b, a), k / t);
|
||||
p2 = add_vector (p, QPointF (0, 0), QPointF (b, - a), k / t);
|
||||
return flag;
|
||||
}
|
||||
|
||||
/*
|
||||
* Добавление вектора к точке
|
||||
* Взято з сайту http://hardfire.ru/add_vector
|
||||
*/
|
||||
QPointF VToolPoint::add_vector (QPointF p, QPointF p1, QPointF p2, qreal k) const{
|
||||
return QPointF (p.x() + (p2.x() - p1.x()) * k, p.y() + (p2.y() - p1.y()) * k);
|
||||
}
|
||||
|
||||
QPointF VToolPoint::ClosestPoint(QLineF line, QPointF p) const{
|
||||
QLineF lineP2pointFrom = QLineF(line.p2(), p);
|
||||
qreal angle = 180-line.angleTo(lineP2pointFrom)-90;
|
||||
QLineF pointFromlineP2 = QLineF(p, line.p2());
|
||||
pointFromlineP2.setAngle(pointFromlineP2.angle()+angle);
|
||||
QPointF point;
|
||||
QLineF::IntersectType type = pointFromlineP2.intersect(line,&point);
|
||||
if ( type == QLineF::BoundedIntersection ){
|
||||
return point;
|
||||
} else{
|
||||
if ( type == QLineF::NoIntersection || type == QLineF::UnboundedIntersection ){
|
||||
Q_ASSERT_X(type != QLineF::BoundedIntersection, Q_FUNC_INFO, "Немає точки перетину.");
|
||||
return point;
|
||||
}
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
QPointF VToolPoint::LineIntersectRect(QRectF rec, QLineF line) const{
|
||||
qreal x1, y1, x2, y2;
|
||||
rec.getCoords(&x1, &y1, &x2, &y2);
|
||||
|
@ -150,6 +90,59 @@ void VToolPoint::RefreshLine(){
|
|||
}
|
||||
}
|
||||
|
||||
qint32 VToolPoint::LineIntersectCircle(QPointF center, qreal radius, QLineF line, QPointF &p1,
|
||||
QPointF &p2) const{
|
||||
const qreal eps = 1e-8;
|
||||
//коефіцієнти для рівняння відрізку
|
||||
qreal a = line.p2().y() - line.p1().y();
|
||||
qreal b = line.p1().x() - line.p2().x();
|
||||
// В даному випадку не використовується.
|
||||
//qreal c = - a * line.p1().x() - b * line.p1().y();
|
||||
// проекция центра окружности на прямую
|
||||
QPointF p = ClosestPoint (line, center);
|
||||
// сколько всего решений?
|
||||
qint32 flag = 0;
|
||||
qreal d = QLineF (center, p).length();
|
||||
if (qAbs (d - radius) <= eps){
|
||||
flag = 1;
|
||||
} else {
|
||||
if (radius > d){
|
||||
flag = 2;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// находим расстояние от проекции до точек пересечения
|
||||
qreal k = sqrt (radius * radius - d * d);
|
||||
qreal t = QLineF (QPointF (0, 0), QPointF (b, - a)).length();
|
||||
// добавляем к проекции векторы направленные к точкам пеерсечения
|
||||
p1 = addVector (p, QPointF (0, 0), QPointF (- b, a), k / t);
|
||||
p2 = addVector (p, QPointF (0, 0), QPointF (b, - a), k / t);
|
||||
return flag;
|
||||
}
|
||||
|
||||
QPointF VToolPoint::ClosestPoint(QLineF line, QPointF p) const{
|
||||
QLineF lineP2pointFrom = QLineF(line.p2(), p);
|
||||
qreal angle = 180-line.angleTo(lineP2pointFrom)-90;
|
||||
QLineF pointFromlineP2 = QLineF(p, line.p2());
|
||||
pointFromlineP2.setAngle(pointFromlineP2.angle()+angle);
|
||||
QPointF point;
|
||||
QLineF::IntersectType type = pointFromlineP2.intersect(line,&point);
|
||||
if ( type == QLineF::BoundedIntersection ){
|
||||
return point;
|
||||
} else{
|
||||
if ( type == QLineF::NoIntersection || type == QLineF::UnboundedIntersection ){
|
||||
Q_ASSERT_X(type != QLineF::BoundedIntersection, Q_FUNC_INFO, "Немає точки перетину.");
|
||||
return point;
|
||||
}
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
QPointF VToolPoint::addVector(QPointF p, QPointF p1, QPointF p2, qreal k) const{
|
||||
return QPointF (p.x() + (p2.x() - p1.x()) * k, p.y() + (p2.y() - p1.y()) * k);
|
||||
}
|
||||
|
||||
void VToolPoint::LiteUpdateFromGui(qreal mx, qreal my){
|
||||
QDomElement domElement = doc->elementById(QString().setNum(id));
|
||||
if(domElement.isElement()){
|
||||
|
@ -163,35 +156,28 @@ void VToolPoint::ChangedActivDraw(const QString newName){
|
|||
if(nameActivDraw == newName){
|
||||
this->setPen(QPen(Qt::black, widthHairLine));
|
||||
this->setFlag(QGraphicsItem::ItemIsSelectable, true);
|
||||
this->setAcceptHoverEvents(true);
|
||||
namePoint->setFlag(QGraphicsItem::ItemIsMovable, true);
|
||||
namePoint->setFlag(QGraphicsItem::ItemIsSelectable, true);
|
||||
namePoint->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
|
||||
namePoint->setBrush(QBrush(Qt::black));
|
||||
namePoint->setAcceptHoverEvents(true);
|
||||
lineName->setPen(QPen(Qt::black, widthHairLine));
|
||||
this->setAcceptHoverEvents(true);
|
||||
VAbstractTool::ChangedActivDraw(newName);
|
||||
} else {
|
||||
this->setPen(QPen(Qt::gray, widthHairLine));
|
||||
this->setFlag(QGraphicsItem::ItemIsSelectable, false);
|
||||
this->setAcceptHoverEvents (false);
|
||||
namePoint->setFlag(QGraphicsItem::ItemIsMovable, false);
|
||||
namePoint->setFlag(QGraphicsItem::ItemIsSelectable, false);
|
||||
namePoint->setFlag(QGraphicsItem::ItemSendsGeometryChanges, false);
|
||||
namePoint->setBrush(QBrush(Qt::gray));
|
||||
namePoint->setAcceptHoverEvents(false);
|
||||
lineName->setPen(QPen(Qt::gray, widthHairLine));
|
||||
this->setAcceptHoverEvents (false);
|
||||
VAbstractTool::ChangedActivDraw(newName);
|
||||
}
|
||||
}
|
||||
|
||||
void VToolPoint::mouseReleaseEvent ( QGraphicsSceneMouseEvent * event ){
|
||||
if(event->button() == Qt::LeftButton){
|
||||
emit ChoosedPoint(id, Scene::Point);
|
||||
}
|
||||
QGraphicsItem::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void VToolPoint::RefreshGeometry(){
|
||||
VPointF point = VAbstractTool::data->GetPoint(id);
|
||||
QRectF rec = QRectF(point.x(), point.y(), radius*2, radius*2);
|
||||
|
@ -205,6 +191,13 @@ void VToolPoint::RefreshGeometry(){
|
|||
RefreshLine();
|
||||
}
|
||||
|
||||
void VToolPoint::mouseReleaseEvent(QGraphicsSceneMouseEvent *event){
|
||||
if(event->button() == Qt::LeftButton){
|
||||
emit ChoosedTool(id, Scene::Point);
|
||||
}
|
||||
QGraphicsItem::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void VToolPoint::hoverMoveEvent(QGraphicsSceneHoverEvent *event){
|
||||
Q_UNUSED(event);
|
||||
this->setPen(QPen(Qt::black, widthMainLine));
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
#ifndef VTOOLPOINT_H
|
||||
#define VTOOLPOINT_H
|
||||
|
||||
#include <QGraphicsEllipseItem>
|
||||
#include <QGraphicsLineItem>
|
||||
|
||||
#include <QGraphicsEllipseItem>
|
||||
#include "../widgets/vgraphicssimpletextitem.h"
|
||||
#include "../options.h"
|
||||
#include "vabstracttool.h"
|
||||
|
@ -22,18 +21,18 @@ protected:
|
|||
qreal radius;
|
||||
VGraphicsSimpleTextItem *namePoint;
|
||||
QGraphicsLineItem *lineName;
|
||||
virtual void RefreshGeometry();
|
||||
virtual void mouseReleaseEvent ( QGraphicsSceneMouseEvent * event );
|
||||
virtual void RefreshGeometry();
|
||||
virtual void hoverMoveEvent ( QGraphicsSceneHoverEvent * event );
|
||||
virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event );
|
||||
private:
|
||||
qint32 LineIntersectCircle(QPointF center, qreal radius, QLineF line, QPointF &p1,
|
||||
QPointF &p2) const;
|
||||
QPointF LineIntersectRect(QRectF rec, QLineF line) const;
|
||||
QPointF ClosestPoint(QLineF line, QPointF p) const;
|
||||
QPointF add_vector (QPointF p, QPointF p1, QPointF p2, qreal k) const;
|
||||
void LiteUpdateFromGui(qreal mx, qreal my);
|
||||
void RefreshLine();
|
||||
qint32 LineIntersectCircle(QPointF center, qreal radius, QLineF line, QPointF &p1,
|
||||
QPointF &p2) const;
|
||||
QPointF ClosestPoint(QLineF line, QPointF p) const;
|
||||
QPointF addVector (QPointF p, QPointF p1, QPointF p2, qreal k) const;
|
||||
};
|
||||
|
||||
#endif // VTOOLPOINT_H
|
||||
|
|
|
@ -75,7 +75,7 @@ void VToolShoulderPoint::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
|
|||
QSharedPointer<DialogShoulderPoint>(new DialogShoulderPoint(VAbstractTool::data));
|
||||
|
||||
connect(qobject_cast< VMainGraphicsScene * >(this->scene()), &VMainGraphicsScene::ChoosedObject,
|
||||
dialogShoulderPoint.data(), &DialogShoulderPoint::ChoosedPoint);
|
||||
dialogShoulderPoint.data(), &DialogShoulderPoint::ChoosedObject);
|
||||
connect(dialogShoulderPoint.data(), &DialogShoulderPoint::DialogClosed, this,
|
||||
&VToolShoulderPoint::FullUpdateFromGui);
|
||||
connect(doc, &VDomDocument::FullUpdateFromFile, dialogShoulderPoint.data(),
|
||||
|
|
|
@ -1,67 +1,9 @@
|
|||
#include "vtoolsimplepoint.h"
|
||||
#include <QPen>
|
||||
#include <QBrush>
|
||||
#include <QDebug>
|
||||
#include <QGraphicsItem>
|
||||
#include <cmath>
|
||||
#include <QMenu>
|
||||
#include <QGraphicsSceneContextMenuEvent>
|
||||
|
||||
#include "../options.h"
|
||||
#include "../container/vpointf.h"
|
||||
|
||||
VToolSimplePoint::VToolSimplePoint (VDomDocument *doc, VContainer *data, qint64 id, Tool::Enum typeCreation,
|
||||
QGraphicsItem * parent ):VToolPoint(doc, data, id, parent){
|
||||
if(typeCreation == Tool::FromGui){
|
||||
AddToFile();
|
||||
}
|
||||
VToolSimplePoint::VToolSimplePoint(VDomDocument *doc, VContainer *data, qint64 id,
|
||||
QGraphicsItem *parent):VAbstractTool(doc, data, id),
|
||||
QGraphicsEllipseItem(parent){
|
||||
|
||||
}
|
||||
|
||||
void VToolSimplePoint::AddToFile(){
|
||||
VPointF point = VAbstractTool::data->GetPoint(id);
|
||||
QDomElement domElement = doc->createElement("point");
|
||||
|
||||
AddAttribute(domElement, "id", id);
|
||||
AddAttribute(domElement, "type", "simple");
|
||||
AddAttribute(domElement, "name", point.name());
|
||||
AddAttribute(domElement, "x", point.x()/PrintDPI*25.4);
|
||||
AddAttribute(domElement, "y", point.y()/PrintDPI*25.4);
|
||||
AddAttribute(domElement, "mx", point.mx()/PrintDPI*25.4);
|
||||
AddAttribute(domElement, "my", point.my()/PrintDPI*25.4);
|
||||
|
||||
AddToCalculation(domElement);
|
||||
}
|
||||
|
||||
void VToolSimplePoint::FullUpdateFromGui(int result){
|
||||
if(result == QDialog::Accepted){
|
||||
QPointF p = dialogSinglePoint->getPoint();
|
||||
QDomElement domElement = doc->elementById(QString().setNum(id));
|
||||
if(domElement.isElement()){
|
||||
domElement.setAttribute("name", dialogSinglePoint->getName());
|
||||
domElement.setAttribute("x", QString().setNum(p.x()/PrintDPI*25.4));
|
||||
domElement.setAttribute("y", QString().setNum(p.y()/PrintDPI*25.4));
|
||||
emit FullUpdateTree();
|
||||
}
|
||||
}
|
||||
dialogSinglePoint.clear();
|
||||
}
|
||||
|
||||
void VToolSimplePoint::contextMenuEvent ( QGraphicsSceneContextMenuEvent * event ){
|
||||
if(!ignoreContextMenuEvent){
|
||||
QMenu menu;
|
||||
QAction *actionOption = menu.addAction("Властивості");
|
||||
QAction *selectedAction = menu.exec(event->screenPos());
|
||||
if(selectedAction == actionOption){
|
||||
dialogSinglePoint = QSharedPointer<DialogSinglePoint>(new DialogSinglePoint(VAbstractTool::data));
|
||||
connect(dialogSinglePoint.data(), &DialogSinglePoint::DialogClosed, this,
|
||||
&VToolSimplePoint::FullUpdateFromGui);
|
||||
VPointF p = VAbstractTool::data->GetPoint(id);
|
||||
dialogSinglePoint->setData(p.name(), p.toQPointF());
|
||||
dialogSinglePoint->exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VToolSimplePoint::FullUpdateFromFile(){
|
||||
RefreshGeometry();
|
||||
}
|
||||
|
|
|
@ -1,25 +1,21 @@
|
|||
#ifndef VTOOLSIMPLEPOINT_H
|
||||
#define VTOOLSIMPLEPOINT_H
|
||||
|
||||
#include "../container/vcontainer.h"
|
||||
#include "../xml/vdomdocument.h"
|
||||
#include "vtoolpoint.h"
|
||||
#include "../dialogs/dialogsinglepoint.h"
|
||||
#include <QGraphicsEllipseItem>
|
||||
#include <QGraphicsLineItem>
|
||||
|
||||
class VToolSimplePoint : public VToolPoint
|
||||
#include "../options.h"
|
||||
#include "vabstracttool.h"
|
||||
|
||||
class VToolSimplePoint: public VAbstractTool, public QGraphicsEllipseItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VToolSimplePoint (VDomDocument *doc, VContainer *data, qint64 id,
|
||||
Tool::Enum typeCreation, QGraphicsItem * parent = 0 );
|
||||
VToolSimplePoint(VDomDocument *doc, VContainer *data, qint64 id, QGraphicsItem * parent = 0);
|
||||
public slots:
|
||||
virtual void FullUpdateFromFile();
|
||||
virtual void FullUpdateFromGui(int result);
|
||||
virtual void ChangedActivDraw(const QString newName);
|
||||
protected:
|
||||
virtual void contextMenuEvent ( QGraphicsSceneContextMenuEvent * event );
|
||||
virtual void AddToFile();
|
||||
private:
|
||||
QSharedPointer<DialogSinglePoint> dialogSinglePoint;
|
||||
virtual void RefreshGeometry();
|
||||
};
|
||||
|
||||
#endif // VTOOLSIMPLEPOINT_H
|
||||
|
|
68
tools/vtoolsinglepoint.cpp
Normal file
68
tools/vtoolsinglepoint.cpp
Normal file
|
@ -0,0 +1,68 @@
|
|||
#include "vtoolsinglepoint.h"
|
||||
#include <QPen>
|
||||
#include <QBrush>
|
||||
#include <QDebug>
|
||||
#include <QGraphicsItem>
|
||||
#include <cmath>
|
||||
#include <QMenu>
|
||||
#include <QGraphicsSceneContextMenuEvent>
|
||||
|
||||
#include "../options.h"
|
||||
#include "../container/vpointf.h"
|
||||
|
||||
VToolSinglePoint::VToolSinglePoint (VDomDocument *doc, VContainer *data, qint64 id, Tool::Enum typeCreation,
|
||||
QGraphicsItem * parent ):VToolPoint(doc, data, id, parent){
|
||||
if(typeCreation == Tool::FromGui){
|
||||
AddToFile();
|
||||
}
|
||||
}
|
||||
|
||||
void VToolSinglePoint::AddToFile(){
|
||||
VPointF point = VAbstractTool::data->GetPoint(id);
|
||||
QDomElement domElement = doc->createElement("point");
|
||||
|
||||
AddAttribute(domElement, "id", id);
|
||||
AddAttribute(domElement, "type", "single");
|
||||
AddAttribute(domElement, "name", point.name());
|
||||
AddAttribute(domElement, "x", point.x()/PrintDPI*25.4);
|
||||
AddAttribute(domElement, "y", point.y()/PrintDPI*25.4);
|
||||
AddAttribute(domElement, "mx", point.mx()/PrintDPI*25.4);
|
||||
AddAttribute(domElement, "my", point.my()/PrintDPI*25.4);
|
||||
|
||||
AddToCalculation(domElement);
|
||||
}
|
||||
|
||||
void VToolSinglePoint::contextMenuEvent ( QGraphicsSceneContextMenuEvent * event ){
|
||||
if(!ignoreContextMenuEvent){
|
||||
QMenu menu;
|
||||
QAction *actionOption = menu.addAction("Властивості");
|
||||
QAction *selectedAction = menu.exec(event->screenPos());
|
||||
if(selectedAction == actionOption){
|
||||
dialogSinglePoint = QSharedPointer<DialogSinglePoint>(new DialogSinglePoint(VAbstractTool::data));
|
||||
VPointF p = VAbstractTool::data->GetPoint(id);
|
||||
dialogSinglePoint->setData(p.name(), p.toQPointF());
|
||||
connect(dialogSinglePoint.data(), &DialogSinglePoint::DialogClosed, this,
|
||||
&VToolSinglePoint::FullUpdateFromGui);
|
||||
dialogSinglePoint->exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VToolSinglePoint::FullUpdateFromFile(){
|
||||
RefreshGeometry();
|
||||
}
|
||||
|
||||
void VToolSinglePoint::FullUpdateFromGui(int result){
|
||||
if(result == QDialog::Accepted){
|
||||
QPointF p = dialogSinglePoint->getPoint();
|
||||
QString name = dialogSinglePoint->getName();
|
||||
QDomElement domElement = doc->elementById(QString().setNum(id));
|
||||
if(domElement.isElement()){
|
||||
domElement.setAttribute("name", name);
|
||||
domElement.setAttribute("x", QString().setNum(p.x()/PrintDPI*25.4));
|
||||
domElement.setAttribute("y", QString().setNum(p.y()/PrintDPI*25.4));
|
||||
emit FullUpdateTree();
|
||||
}
|
||||
}
|
||||
dialogSinglePoint.clear();
|
||||
}
|
27
tools/vtoolsinglepoint.h
Normal file
27
tools/vtoolsinglepoint.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef VTOOLSINGLEPOINT_H
|
||||
#define VTOOLSINGLEPOINT_H
|
||||
|
||||
#include "../container/vcontainer.h"
|
||||
#include "../xml/vdomdocument.h"
|
||||
#include "vtoolpoint.h"
|
||||
#include "../dialogs/dialogsinglepoint.h"
|
||||
|
||||
class VToolSinglePoint : public VToolPoint
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VToolSinglePoint (VDomDocument *doc, VContainer *data, qint64 id,
|
||||
Tool::Enum typeCreation, QGraphicsItem * parent = 0 );
|
||||
public slots:
|
||||
virtual void FullUpdateFromFile();
|
||||
virtual void FullUpdateFromGui(int result);
|
||||
signals:
|
||||
void FullUpdateTree();
|
||||
protected:
|
||||
virtual void contextMenuEvent ( QGraphicsSceneContextMenuEvent * event );
|
||||
virtual void AddToFile();
|
||||
private:
|
||||
QSharedPointer<DialogSinglePoint> dialogSinglePoint;
|
||||
};
|
||||
|
||||
#endif // VTOOLSINGLEPOINT_H
|
202
tools/vtoolspline.cpp
Normal file
202
tools/vtoolspline.cpp
Normal file
|
@ -0,0 +1,202 @@
|
|||
#include "vtoolspline.h"
|
||||
#include "../geometry/vspline.h"
|
||||
#include <QMenu>
|
||||
#include <QDebug>
|
||||
|
||||
VToolSpline::VToolSpline(VDomDocument *doc, VContainer *data, qint64 id, Tool::Enum typeCreation,
|
||||
QGraphicsItem *parent):VAbstractTool(doc, data, id), QGraphicsPathItem(parent){
|
||||
|
||||
VSpline spl = data->GetSpline(id);
|
||||
QPainterPath path;
|
||||
path.addPath(spl.GetPath());
|
||||
path.setFillRule( Qt::WindingFill );
|
||||
this->setPath(path);
|
||||
this->setPen(QPen(Qt::black, widthHairLine));
|
||||
this->setFlag(QGraphicsItem::ItemIsSelectable, true);
|
||||
this->setAcceptHoverEvents(true);
|
||||
|
||||
controlPoint1 = new VControlPointSpline(spl.GetP2(), spl.GetPointP1(), this);
|
||||
connect(controlPoint1, &VControlPointSpline::ControlPointChangePosition, this,
|
||||
&VToolSpline::ControlPoint1ChangePosition);
|
||||
|
||||
controlPoint2 = new VControlPointSpline(spl.GetP3(), spl.GetPointP4(), this);
|
||||
connect(controlPoint2, &VControlPointSpline::ControlPointChangePosition, this,
|
||||
&VToolSpline::ControlPoint2ChangePosition);
|
||||
|
||||
if(typeCreation == Tool::FromGui){
|
||||
AddToFile();
|
||||
}
|
||||
}
|
||||
|
||||
void VToolSpline::FullUpdateFromFile(){
|
||||
RefreshGeometry();
|
||||
}
|
||||
|
||||
void VToolSpline::FullUpdateFromGui(int result){
|
||||
if(result == QDialog::Accepted){
|
||||
VSpline spl = VSpline (VAbstractTool::data->DataPoints(), dialogSpline->getP1(),
|
||||
dialogSpline->getP4(), dialogSpline->getAngle1(), dialogSpline->getAngle2(),
|
||||
dialogSpline->getKAsm1(), dialogSpline->getKAsm2(), dialogSpline->getKCurve());
|
||||
|
||||
disconnect(controlPoint1, &VControlPointSpline::ControlPointChangePosition, this,
|
||||
&VToolSpline::ControlPoint1ChangePosition);
|
||||
disconnect(controlPoint2, &VControlPointSpline::ControlPointChangePosition, this,
|
||||
&VToolSpline::ControlPoint2ChangePosition);
|
||||
controlPoint1->setPos(spl.GetP2());
|
||||
controlPoint2->setPos(spl.GetP3());
|
||||
connect(controlPoint1, &VControlPointSpline::ControlPointChangePosition, this,
|
||||
&VToolSpline::ControlPoint1ChangePosition);
|
||||
connect(controlPoint2, &VControlPointSpline::ControlPointChangePosition, this,
|
||||
&VToolSpline::ControlPoint2ChangePosition);
|
||||
|
||||
spl = VSpline (VAbstractTool::data->DataPoints(), dialogSpline->getP1(), controlPoint1->pos(),
|
||||
controlPoint2->pos(), dialogSpline->getP4(), dialogSpline->getKCurve());
|
||||
QDomElement domElement = doc->elementById(QString().setNum(id));
|
||||
if(domElement.isElement()){
|
||||
domElement.setAttribute("point1", QString().setNum(spl.GetP1()));
|
||||
domElement.setAttribute("point4", QString().setNum(spl.GetP4()));
|
||||
domElement.setAttribute("angle1", QString().setNum(spl.GetAngle1()));
|
||||
domElement.setAttribute("angle2", QString().setNum(spl.GetAngle2()));
|
||||
domElement.setAttribute("kAsm1", QString().setNum(spl.GetKasm1()));
|
||||
domElement.setAttribute("kAsm2", QString().setNum(spl.GetKasm2()));
|
||||
domElement.setAttribute("kCurve", QString().setNum(spl.GetKcurve()));
|
||||
emit FullUpdateTree();
|
||||
}
|
||||
}
|
||||
dialogSpline.clear();
|
||||
}
|
||||
|
||||
void VToolSpline::ControlPoint1ChangePosition(const QPointF pos){
|
||||
VSpline spl = VAbstractTool::data->GetSpline(id);
|
||||
spl.ModifiSpl (spl.GetP1(), pos, spl.GetP3(), spl.GetP4(), spl.GetKcurve());
|
||||
QDomElement domElement = doc->elementById(QString().setNum(id));
|
||||
if(domElement.isElement()){
|
||||
domElement.setAttribute("angle1", QString().setNum(spl.GetAngle1()));
|
||||
domElement.setAttribute("angle2", QString().setNum(spl.GetAngle2()));
|
||||
domElement.setAttribute("kAsm1", QString().setNum(spl.GetKasm1()));
|
||||
domElement.setAttribute("kAsm2", QString().setNum(spl.GetKasm2()));
|
||||
domElement.setAttribute("kCurve", QString().setNum(spl.GetKcurve()));
|
||||
emit FullUpdateTree();
|
||||
}
|
||||
}
|
||||
|
||||
void VToolSpline::ControlPoint2ChangePosition(const QPointF pos){
|
||||
VSpline spl = VAbstractTool::data->GetSpline(id);
|
||||
spl.ModifiSpl (spl.GetP1(), spl.GetP2(), pos, spl.GetP4(), spl.GetKcurve());
|
||||
QDomElement domElement = doc->elementById(QString().setNum(id));
|
||||
if(domElement.isElement()){
|
||||
domElement.setAttribute("angle1", QString().setNum(spl.GetAngle1()));
|
||||
domElement.setAttribute("angle2", QString().setNum(spl.GetAngle2()));
|
||||
domElement.setAttribute("kAsm1", QString().setNum(spl.GetKasm1()));
|
||||
domElement.setAttribute("kAsm2", QString().setNum(spl.GetKasm2()));
|
||||
domElement.setAttribute("kCurve", QString().setNum(spl.GetKcurve()));
|
||||
emit FullUpdateTree();
|
||||
}
|
||||
}
|
||||
|
||||
void VToolSpline::contextMenuEvent(QGraphicsSceneContextMenuEvent *event){
|
||||
if(!ignoreContextMenuEvent){
|
||||
QMenu menu;
|
||||
QAction *actionOption = menu.addAction("Властивості");
|
||||
QAction *selectedAction = menu.exec(event->screenPos());
|
||||
if(selectedAction == actionOption){
|
||||
dialogSpline = QSharedPointer<DialogSpline>(new DialogSpline(VAbstractTool::data));
|
||||
|
||||
connect(qobject_cast< VMainGraphicsScene * >(this->scene()), &VMainGraphicsScene::ChoosedObject,
|
||||
dialogSpline.data(), &DialogSpline::ChoosedObject);
|
||||
connect(dialogSpline.data(), &DialogSpline::DialogClosed, this,
|
||||
&VToolSpline::FullUpdateFromGui);
|
||||
|
||||
VSpline spl = VAbstractTool::data->GetSpline(id);
|
||||
|
||||
dialogSpline->setP1(spl.GetP1());
|
||||
dialogSpline->setP4(spl.GetP4());
|
||||
dialogSpline->setAngle1(spl.GetAngle1());
|
||||
dialogSpline->setAngle2(spl.GetAngle2());
|
||||
dialogSpline->setKAsm1(spl.GetKasm1());
|
||||
dialogSpline->setKAsm2(spl.GetKasm2());
|
||||
dialogSpline->setKCurve(spl.GetKcurve());
|
||||
|
||||
dialogSpline->show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VToolSpline::AddToFile(){
|
||||
VSpline spl = VAbstractTool::data->GetSpline(id);
|
||||
QDomElement domElement = doc->createElement("spline");
|
||||
|
||||
AddAttribute(domElement, "id", id);
|
||||
AddAttribute(domElement, "type", "simple");
|
||||
AddAttribute(domElement, "point1", spl.GetP1());
|
||||
AddAttribute(domElement, "point4", spl.GetP4());
|
||||
AddAttribute(domElement, "angle1", spl.GetAngle1());
|
||||
AddAttribute(domElement, "angle2", spl.GetAngle2());
|
||||
AddAttribute(domElement, "kAsm1", spl.GetKasm1());
|
||||
AddAttribute(domElement, "kAsm2", spl.GetKasm2());
|
||||
AddAttribute(domElement, "kCurve", spl.GetKcurve());
|
||||
|
||||
AddToCalculation(domElement);
|
||||
}
|
||||
|
||||
void VToolSpline::mouseReleaseEvent(QGraphicsSceneMouseEvent *event){
|
||||
if(event->button() == Qt::LeftButton){
|
||||
emit ChoosedTool(id, Scene::Spline);
|
||||
}
|
||||
QGraphicsItem::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void VToolSpline::hoverMoveEvent(QGraphicsSceneHoverEvent *event){
|
||||
Q_UNUSED(event);
|
||||
this->setPen(QPen(Qt::black, widthMainLine));
|
||||
}
|
||||
|
||||
void VToolSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event){
|
||||
Q_UNUSED(event);
|
||||
this->setPen(QPen(Qt::black, widthHairLine));
|
||||
}
|
||||
|
||||
void VToolSpline::RefreshGeometry(){
|
||||
VSpline spl = VAbstractTool::data->GetSpline(id);
|
||||
QPainterPath path;
|
||||
path.addPath(spl.GetPath());
|
||||
path.setFillRule( Qt::WindingFill );
|
||||
this->setPath(path);
|
||||
QPointF splinePoint = VAbstractTool::data->GetPoint(spl.GetP1());
|
||||
QPointF controlPoint = spl.GetP2();
|
||||
controlPoint1->RefreshLine(controlPoint, splinePoint);
|
||||
splinePoint = VAbstractTool::data->GetPoint(spl.GetP4());
|
||||
controlPoint = spl.GetP3();
|
||||
controlPoint2->RefreshLine(controlPoint, splinePoint);
|
||||
}
|
||||
|
||||
|
||||
void VToolSpline::ChangedActivDraw(const QString newName){
|
||||
if(nameActivDraw == newName){
|
||||
this->setPen(QPen(Qt::black, widthHairLine));
|
||||
this->setFlag(QGraphicsItem::ItemIsSelectable, true);
|
||||
this->setAcceptHoverEvents(true);
|
||||
controlPoint1->setPen(QPen(Qt::black, widthHairLine));
|
||||
controlPoint1->setFlag(QGraphicsItem::ItemIsSelectable, true);
|
||||
controlPoint1->setFlag(QGraphicsItem::ItemIsMovable, true);
|
||||
controlPoint1->setAcceptHoverEvents(true);
|
||||
controlPoint2->setPen(QPen(Qt::black, widthHairLine));
|
||||
controlPoint2->setFlag(QGraphicsItem::ItemIsSelectable, true);
|
||||
controlPoint2->setFlag(QGraphicsItem::ItemIsMovable, true);
|
||||
controlPoint2->setAcceptHoverEvents(true);
|
||||
VAbstractTool::ChangedActivDraw(newName);
|
||||
} else {
|
||||
this->setPen(QPen(Qt::gray, widthHairLine));
|
||||
this->setFlag(QGraphicsItem::ItemIsSelectable, false);
|
||||
this->setAcceptHoverEvents (false);
|
||||
controlPoint1->setPen(QPen(Qt::gray, widthHairLine));
|
||||
controlPoint1->setFlag(QGraphicsItem::ItemIsSelectable, false);
|
||||
controlPoint1->setFlag(QGraphicsItem::ItemIsMovable, false);
|
||||
controlPoint1->setAcceptHoverEvents(false);
|
||||
controlPoint2->setPen(QPen(Qt::gray, widthHairLine));
|
||||
controlPoint2->setFlag(QGraphicsItem::ItemIsSelectable, false);
|
||||
controlPoint2->setFlag(QGraphicsItem::ItemIsMovable, false);
|
||||
controlPoint2->setAcceptHoverEvents(false);
|
||||
VAbstractTool::ChangedActivDraw(newName);
|
||||
}
|
||||
}
|
36
tools/vtoolspline.h
Normal file
36
tools/vtoolspline.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#ifndef VTOOLSPLINE_H
|
||||
#define VTOOLSPLINE_H
|
||||
|
||||
#include "vabstracttool.h"
|
||||
#include "../container/vcontainer.h"
|
||||
#include "../xml/vdomdocument.h"
|
||||
#include <QGraphicsPathItem>
|
||||
#include "../dialogs/dialogspline.h"
|
||||
#include "../widgets/vcontrolpointspline.h"
|
||||
|
||||
class VToolSpline:public VAbstractTool, public QGraphicsPathItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VToolSpline(VDomDocument *doc, VContainer *data, qint64 id,
|
||||
Tool::Enum typeCreation, QGraphicsItem * parent = 0);
|
||||
public slots:
|
||||
virtual void FullUpdateFromFile();
|
||||
virtual void FullUpdateFromGui(int result);
|
||||
void ControlPoint1ChangePosition(const QPointF pos);
|
||||
void ControlPoint2ChangePosition(const QPointF pos);
|
||||
virtual void ChangedActivDraw(const QString newName);
|
||||
protected:
|
||||
virtual void contextMenuEvent ( QGraphicsSceneContextMenuEvent * event );
|
||||
virtual void AddToFile();
|
||||
virtual void mouseReleaseEvent ( QGraphicsSceneMouseEvent * event );
|
||||
virtual void hoverMoveEvent ( QGraphicsSceneHoverEvent * event );
|
||||
virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event );
|
||||
private:
|
||||
QSharedPointer<DialogSpline> dialogSpline;
|
||||
VControlPointSpline *controlPoint1;
|
||||
VControlPointSpline *controlPoint2;
|
||||
void RefreshGeometry();
|
||||
};
|
||||
|
||||
#endif // VTOOLSPLINE_H
|
119
widgets/vcontrolpointspline.cpp
Normal file
119
widgets/vcontrolpointspline.cpp
Normal file
|
@ -0,0 +1,119 @@
|
|||
#include "vcontrolpointspline.h"
|
||||
#include <QPen>
|
||||
#include <QBrush>
|
||||
#include <QGraphicsScene>
|
||||
#include <QDebug>
|
||||
|
||||
VControlPointSpline::VControlPointSpline(const QPointF &controlPoint, const QPointF &splinePoint,
|
||||
QGraphicsItem *parent):QGraphicsEllipseItem(parent){
|
||||
radius = 1.5*PrintDPI/25.4;
|
||||
//create circle
|
||||
QRectF rec = QRectF(0, 0, radius*2, radius*2);
|
||||
rec.translate(-rec.center().x(), -rec.center().y());
|
||||
this->setRect(rec);
|
||||
this->setPen(QPen(Qt::black, widthHairLine));
|
||||
this->setBrush(QBrush(Qt::NoBrush));
|
||||
this->setFlag(QGraphicsItem::ItemIsSelectable, true);
|
||||
this->setFlag(QGraphicsItem::ItemIsMovable, true);
|
||||
this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
|
||||
this->setAcceptHoverEvents(true);
|
||||
this->setPos(controlPoint);
|
||||
|
||||
//Лінія, що з'єднує дві точки
|
||||
QPointF p1, p2;
|
||||
LineIntersectCircle(QPointF(), radius, QLineF( QPointF(), splinePoint-controlPoint), p1, p2);
|
||||
controlLine = new QGraphicsLineItem(QLineF(splinePoint-controlPoint, p1), this);
|
||||
controlLine->setPen(QPen(Qt::red, widthHairLine));
|
||||
controlLine->setFlag(QGraphicsItem::ItemStacksBehindParent, true);
|
||||
}
|
||||
|
||||
void VControlPointSpline::hoverMoveEvent(QGraphicsSceneHoverEvent *event){
|
||||
Q_UNUSED(event);
|
||||
this->setPen(QPen(Qt::black, widthMainLine));
|
||||
}
|
||||
|
||||
void VControlPointSpline::hoverLeaveEvent(QGraphicsSceneHoverEvent *event){
|
||||
Q_UNUSED(event);
|
||||
this->setPen(QPen(Qt::black, widthHairLine));
|
||||
}
|
||||
|
||||
QVariant VControlPointSpline::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value){
|
||||
if (change == ItemPositionChange && scene()) {
|
||||
// value - это новое положение.
|
||||
QPointF newPos = value.toPointF();
|
||||
qDebug()<<this->rect();
|
||||
QRectF rect = scene()->sceneRect();
|
||||
if (!rect.contains(newPos)) {
|
||||
// Сохраняем элемент внутри прямоугольника сцены.
|
||||
newPos.setX(qMin(rect.right(), qMax(newPos.x(), rect.left())));
|
||||
newPos.setY(qMin(rect.bottom(), qMax(newPos.y(), rect.top())));
|
||||
|
||||
emit ControlPointChangePosition(newPos);
|
||||
return newPos;
|
||||
}
|
||||
emit ControlPointChangePosition(newPos);
|
||||
}
|
||||
return QGraphicsItem::itemChange(change, value);
|
||||
}
|
||||
|
||||
qint32 VControlPointSpline::LineIntersectCircle(QPointF center, qreal radius, QLineF line, QPointF &p1,
|
||||
QPointF &p2) const{
|
||||
const qreal eps = 1e-8;
|
||||
//коефіцієнти для рівняння відрізку
|
||||
qreal a = line.p2().y() - line.p1().y();
|
||||
qreal b = line.p1().x() - line.p2().x();
|
||||
// В даному випадку не використовується.
|
||||
//qreal c = - a * line.p1().x() - b * line.p1().y();
|
||||
// проекция центра окружности на прямую
|
||||
QPointF p = ClosestPoint (line, center);
|
||||
// сколько всего решений?
|
||||
qint32 flag = 0;
|
||||
qreal d = QLineF (center, p).length();
|
||||
if (qAbs (d - radius) <= eps){
|
||||
flag = 1;
|
||||
} else {
|
||||
if (radius > d){
|
||||
flag = 2;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// находим расстояние от проекции до точек пересечения
|
||||
qreal k = sqrt (radius * radius - d * d);
|
||||
qreal t = QLineF (QPointF (0, 0), QPointF (b, - a)).length();
|
||||
// добавляем к проекции векторы направленные к точкам пеерсечения
|
||||
p1 = addVector (p, QPointF (0, 0), QPointF (- b, a), k / t);
|
||||
p2 = addVector (p, QPointF (0, 0), QPointF (b, - a), k / t);
|
||||
return flag;
|
||||
}
|
||||
|
||||
QPointF VControlPointSpline::ClosestPoint(QLineF line, QPointF p) const{
|
||||
QLineF lineP2pointFrom = QLineF(line.p2(), p);
|
||||
qreal angle = 180-line.angleTo(lineP2pointFrom)-90;
|
||||
QLineF pointFromlineP2 = QLineF(p, line.p2());
|
||||
pointFromlineP2.setAngle(pointFromlineP2.angle()+angle);
|
||||
QPointF point;
|
||||
QLineF::IntersectType type = pointFromlineP2.intersect(line,&point);
|
||||
if ( type == QLineF::BoundedIntersection ){
|
||||
return point;
|
||||
} else{
|
||||
if ( type == QLineF::NoIntersection || type == QLineF::UnboundedIntersection ){
|
||||
Q_ASSERT_X(type != QLineF::BoundedIntersection, Q_FUNC_INFO, "Немає точки перетину.");
|
||||
return point;
|
||||
}
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
QPointF VControlPointSpline::addVector(QPointF p, QPointF p1, QPointF p2, qreal k) const{
|
||||
return QPointF (p.x() + (p2.x() - p1.x()) * k, p.y() + (p2.y() - p1.y()) * k);
|
||||
}
|
||||
|
||||
void VControlPointSpline::RefreshLine(const QPointF &controlPoint, const QPointF &splinePoint){
|
||||
// QRectF rec = QRectF(0, 0, radius*2, radius*2);
|
||||
// rec.translate(0-rec.center().x(), 0-rec.center().y());
|
||||
// this->setRect(rec);
|
||||
QPointF p1, p2;
|
||||
LineIntersectCircle(QPointF(), radius, QLineF( QPointF(), splinePoint-controlPoint), p1, p2);
|
||||
controlLine->setLine(QLineF(splinePoint-controlPoint, p1));
|
||||
}
|
30
widgets/vcontrolpointspline.h
Normal file
30
widgets/vcontrolpointspline.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef VCONTROLPOINTSPLINE_H
|
||||
#define VCONTROLPOINTSPLINE_H
|
||||
|
||||
#include <QGraphicsEllipseItem>
|
||||
#include <QGraphicsLineItem>
|
||||
#include <QObject>
|
||||
#include "../options.h"
|
||||
class VControlPointSpline : public QObject, public QGraphicsEllipseItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VControlPointSpline(const QPointF &controlPoint, const QPointF &splinePoint, QGraphicsItem * parent = 0);
|
||||
void RefreshLine(const QPointF &controlPoint, const QPointF &splinePoint);
|
||||
signals:
|
||||
void ControlPointChangePosition(const QPointF pos);
|
||||
protected:
|
||||
qreal radius;
|
||||
QGraphicsLineItem *controlLine;
|
||||
virtual void hoverMoveEvent ( QGraphicsSceneHoverEvent * event );
|
||||
virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event );
|
||||
QVariant itemChange ( GraphicsItemChange change, const QVariant &value );
|
||||
private:
|
||||
qint32 LineIntersectCircle(QPointF center, qreal radius, QLineF line, QPointF &p1,
|
||||
QPointF &p2) const;
|
||||
QPointF ClosestPoint(QLineF line, QPointF p) const;
|
||||
QPointF addVector (QPointF p, QPointF p1, QPointF p2, qreal k) const;
|
||||
|
||||
};
|
||||
|
||||
#endif // VCONTROLPOINTSPLINE_H
|
|
@ -1,7 +1,7 @@
|
|||
#include "vdomdocument.h"
|
||||
#include <QDebug>
|
||||
|
||||
#include "../tools/vtoolsimplepoint.h"
|
||||
#include "../tools/vtoolsinglepoint.h"
|
||||
#include "../tools/vtoolendline.h"
|
||||
#include "../tools/vtoolline.h"
|
||||
#include "../tools/vtoolalongline.h"
|
||||
|
@ -9,6 +9,7 @@
|
|||
#include "../tools/vtoolnormal.h"
|
||||
#include "../tools/vtoolbisector.h"
|
||||
#include "../tools/vtoollineintersect.h"
|
||||
#include "../tools/vtoolspline.h"
|
||||
#include "../options.h"
|
||||
#include "../container/calculator.h"
|
||||
|
||||
|
@ -225,6 +226,8 @@ void VDomDocument::Parse(Document::Enum parse, VMainGraphicsScene *scene, QCombo
|
|||
comboBoxDraws->clear();
|
||||
} else {
|
||||
data->ClearLengthLines();
|
||||
data->ClearLengthArcs();
|
||||
data->ClearLengthSplines();
|
||||
}
|
||||
QDomElement rootElement = this->documentElement();
|
||||
QDomNode domNode = rootElement.firstChild();
|
||||
|
@ -292,7 +295,7 @@ void VDomDocument::AddNewDraw(const QDomElement& node, QComboBox *comboBoxDraws)
|
|||
QDomElement domElementPoint = domCal.toElement();
|
||||
if(!domElementPoint.isNull()){
|
||||
if(domElementPoint.tagName() == "point"){
|
||||
if(domElementPoint.attribute("type","") == "simple"){
|
||||
if(domElementPoint.attribute("type","") == "single"){
|
||||
comboBoxDraws->addItem(name, false);
|
||||
return;
|
||||
} else {
|
||||
|
@ -345,13 +348,16 @@ void VDomDocument::ParseCalculationElement(VMainGraphicsScene *scene, const QDom
|
|||
if(domElement.tagName() == "line"){
|
||||
ParseLineElement(scene, domElement, parse);
|
||||
}
|
||||
if(domElement.tagName() == "spline"){
|
||||
ParseSplineElement(scene, domElement, parse, domElement.attribute("type", ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElement& domElement,
|
||||
Document::Enum parse, const QString& type){
|
||||
if(type == "simple"){
|
||||
if(type == "single"){
|
||||
if(!domElement.isNull()){
|
||||
QString name;
|
||||
qreal mx=5, my=10, x, y;
|
||||
|
@ -366,9 +372,9 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen
|
|||
|
||||
data->UpdatePoint(id, VPointF(x, y, name, mx, my));
|
||||
if(parse == Document::FullParse){
|
||||
VToolSimplePoint *spoint = new VToolSimplePoint(this, data, id, Tool::FromFile);
|
||||
VToolSinglePoint *spoint = new VToolSinglePoint(this, data, id, Tool::FromFile);
|
||||
scene->addItem(spoint);
|
||||
connect(spoint, &VToolSimplePoint::ChoosedPoint, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
connect(spoint, &VToolSinglePoint::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -405,7 +411,7 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen
|
|||
VToolEndLine *point = new VToolEndLine(this, data, id, typeLine, formula, angle,
|
||||
basePointId, Tool::FromFile);
|
||||
scene->addItem(point);
|
||||
connect(point, &VToolPoint::ChoosedPoint, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
connect(point, &VToolPoint::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -443,7 +449,7 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen
|
|||
VToolAlongLine *point = new VToolAlongLine(this, data, id, formula, firstPointId,
|
||||
secondPointId, typeLine, Tool::FromGui);
|
||||
scene->addItem(point);
|
||||
connect(point, &VToolAlongLine::ChoosedPoint, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
connect(point, &VToolAlongLine::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -485,7 +491,7 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen
|
|||
p1Line, p2Line, pShoulder,
|
||||
Tool::FromGui);
|
||||
scene->addItem(point);
|
||||
connect(point, &VToolShoulderPoint::ChoosedPoint, scene,
|
||||
connect(point, &VToolShoulderPoint::ChoosedTool, scene,
|
||||
&VMainGraphicsScene::ChoosedItem);
|
||||
}
|
||||
}
|
||||
|
@ -524,7 +530,7 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen
|
|||
VToolNormal *point = new VToolNormal(this, data, id, typeLine, formula, angle,
|
||||
firstPointId, secondPointId, Tool::FromFile);
|
||||
scene->addItem(point);
|
||||
connect(point, &VToolNormal::ChoosedPoint, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
connect(point, &VToolNormal::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -565,7 +571,7 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen
|
|||
firstPointId, secondPointId, thirdPointId,
|
||||
Tool::FromFile);
|
||||
scene->addItem(point);
|
||||
connect(point, &VToolBisector::ChoosedPoint, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
connect(point, &VToolBisector::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -606,9 +612,9 @@ void VDomDocument::ParsePointElement(VMainGraphicsScene *scene, const QDomElemen
|
|||
if(parse == Document::FullParse){
|
||||
VToolLineIntersect *point = new VToolLineIntersect(this, data, id, p1Line1Id,
|
||||
p2Line1Id, p1Line2Id,
|
||||
p2Line2Id, Tool::FromGui);
|
||||
p2Line2Id, Tool::FromFile);
|
||||
scene->addItem(point);
|
||||
connect(point, &VToolLineIntersect::ChoosedPoint, scene,
|
||||
connect(point, &VToolLineIntersect::ChoosedTool, scene,
|
||||
&VMainGraphicsScene::ChoosedItem);
|
||||
}
|
||||
}
|
||||
|
@ -631,12 +637,42 @@ void VDomDocument::ParseLineElement(VMainGraphicsScene *scene, const QDomElement
|
|||
qint64 id = data->getNextId();
|
||||
VToolLine *line = new VToolLine(this, data, id, firstPoint, secondPoint, Tool::FromFile);
|
||||
scene->addItem(line);
|
||||
connect(line, &VToolLine::ChoosedPoint, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
connect(line, &VToolLine::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VDomDocument::ParseSplineElement(VMainGraphicsScene *scene, const QDomElement &domElement,
|
||||
Document::Enum parse, const QString &type){
|
||||
if(type == "simple"){
|
||||
if(!domElement.isNull()){
|
||||
qreal angle1, angle2, kAsm1, kAsm2, kCurve;
|
||||
qint64 id, point1, point4;
|
||||
if(!domElement.isNull()){
|
||||
id = domElement.attribute("id", "").toLongLong();
|
||||
point1 = domElement.attribute("point1", "").toLongLong();
|
||||
point4 = domElement.attribute("point4", "").toLongLong();
|
||||
angle1 = domElement.attribute("angle1","").toDouble();
|
||||
angle2 = domElement.attribute("angle2","").toDouble();
|
||||
kAsm1 = domElement.attribute("kAsm1","").toDouble();
|
||||
kAsm2 = domElement.attribute("kAsm2","").toDouble();
|
||||
kCurve = domElement.attribute("kCurve","").toDouble();
|
||||
|
||||
VSpline spline = VSpline(data->DataPoints(), point1, point4, angle1, angle2, kAsm1, kAsm2, kCurve);
|
||||
data->UpdateSpline(id, spline);
|
||||
data->AddLengthSpline(data->GetNameSpline(point1, point4), spline.GetLength());
|
||||
if(parse == Document::FullParse){
|
||||
VToolSpline *spl = new VToolSpline(this, data, id, Tool::FromFile);
|
||||
scene->addItem(spl);
|
||||
connect(spl, &VToolSpline::ChoosedTool, scene, &VMainGraphicsScene::ChoosedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void VDomDocument::FullUpdateTree(){
|
||||
VMainGraphicsScene *scene = new VMainGraphicsScene();
|
||||
QComboBox *comboBoxDraws = new QComboBox();
|
||||
|
|
|
@ -59,6 +59,8 @@ private:
|
|||
Document::Enum parse, const QString &type);
|
||||
void ParseLineElement(VMainGraphicsScene *scene, const QDomElement& domElement,
|
||||
Document::Enum parse);
|
||||
void ParseSplineElement(VMainGraphicsScene *scene, const QDomElement& domElement,
|
||||
Document::Enum parse, const QString& type);
|
||||
void ParseIncrementsElement(const QDomNode& node);
|
||||
void AddNewDraw(const QDomElement &node, QComboBox *comboBoxDraws)const;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user