Skip to content

Commit

Permalink
Cleaner code + addressing review.
Browse files Browse the repository at this point in the history
  • Loading branch information
mohsenD98 committed Nov 10, 2024
1 parent 31addf2 commit 2bf1179
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 53 deletions.
19 changes: 19 additions & 0 deletions src/core/utils/geometryutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,22 @@ QgsGeometry GeometryUtils::createGeometryFromWkt( const QString &wkt )
{
return QgsGeometry::fromWkt( wkt );
}

double GeometryUtils::calculateAngle( const QgsPoint &a, const QgsPoint &b, const QgsPoint &c )
{
double abX = b.x() - a.x();
double abY = b.y() - a.y();
double bcX = c.x() - b.x();
double bcY = c.y() - b.y();

double dotProduct = abX * bcX + abY * bcY;

double magnitudeAB = std::sqrt( abX * abX + abY * abY );
double magnitudeBC = std::sqrt( bcX * bcX + bcY * bcY );

double cosTheta = dotProduct / ( magnitudeAB * magnitudeBC );

double angle = std::acos( cosTheta );

return std::abs( angle * ( 180.0 / M_PI ) - 180 );
}
3 changes: 3 additions & 0 deletions src/core/utils/geometryutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ class QFIELD_CORE_EXPORT GeometryUtils : public QObject

//! Creates a geometry from a WKT string.
static Q_INVOKABLE QgsGeometry createGeometryFromWkt( const QString &wkt );

//! Calculates angle between AB and AC
static double calculateAngle( const QgsPoint &a, const QgsPoint &b, const QgsPoint &c );
};

#endif // GEOMETRYUTILS_H
54 changes: 15 additions & 39 deletions src/core/vertexmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* *
***************************************************************************/

#include "geometryutils.h"
#include "qgsquickmapsettings.h"
#include "vertexmodel.h"

Expand All @@ -32,7 +33,7 @@ VertexModel::VertexModel( QObject *parent )
connect( this, &VertexModel::vertexCountChanged, this, &VertexModel::updateCanPreviousNextVertex );
connect( this, &VertexModel::currentVertexIndexChanged, this, &VertexModel::updateCanPreviousNextVertex );
connect( this, &VertexModel::currentVertexIndexChanged, this, &VertexModel::updateCanRemoveVertex );
connect( this, &VertexModel::currentVertexIndexChanged, this, &VertexModel::updateAngleFound );
connect( this, &VertexModel::currentVertexIndexChanged, this, &VertexModel::updateSnappedAngle );
}

void VertexModel::setMapSettings( QgsQuickMapSettings *mapSettings )
Expand Down Expand Up @@ -691,31 +692,6 @@ QgsPoint VertexModel::currentPoint() const
{
return mVertices.value( mCurrentIndex ).point;
}
// Function to calculate the angle between two vectors
double VertexModel::calculateAngle( const QgsPoint &a, const QgsPoint &b, const QgsPoint &c )
{
// Create vectors AB and BC
double AB_x = b.x() - a.x();
double AB_y = b.y() - a.y();
double BC_x = c.x() - b.x();
double BC_y = c.y() - b.y();

// Calculate dot product
double dotProduct = AB_x * BC_x + AB_y * BC_y;

// Calculate magnitudes
double magnitudeAB = std::sqrt( AB_x * AB_x + AB_y * AB_y );
double magnitudeBC = std::sqrt( BC_x * BC_x + BC_y * BC_y );

// Calculate cosine of the angle
double cosTheta = dotProduct / ( magnitudeAB * magnitudeBC );

// Calculate the angle in radians
double angle = std::acos( cosTheta );

// Convert to degrees
return std::abs( angle * ( 180.0 / M_PI ) - 180 );
}

void VertexModel::setCurrentPoint( const QgsPoint &point )
{
Expand All @@ -727,8 +703,6 @@ void VertexModel::setCurrentPoint( const QgsPoint &point )

Vertex &vertex = mVertices[mCurrentIndex];

// Calculate angles between edges

int startPoint = mCurrentIndex - 2;
if ( startPoint < 0 )
{
Expand All @@ -740,11 +714,13 @@ void VertexModel::setCurrentPoint( const QgsPoint &point )
endPoint = endPoint - vertexCount();
}

double angle = calculateAngle( mVertices[startPoint].point, mVertices[mCurrentIndex].point, mVertices[endPoint].point );
int angle = ( int ) GeometryUtils::calculateAngle( mVertices[startPoint].point, mVertices[mCurrentIndex].point, mVertices[endPoint].point );

qDebug() << "--------- angle = " << angle;
const double remainder = std::fmod( angle, snapToCommonAngleDegrees() );
const double threshold = .1;
const bool angleFound = std::abs( remainder ) <= threshold || std::abs( std::abs( remainder ) - snapToCommonAngleDegrees() ) <= threshold;

setAngleFonud( angle > snapToCommonAngleDegrees() - 1 && angle < snapToCommonAngleDegrees() + 1 );
setSnappedAngle( angleFound ? angle : 0 );

if ( mMapSettings && vertex.point.distance( point ) / mMapSettings->mapSettings().mapUnitsPerPixel() < 1 )
return;
Expand Down Expand Up @@ -849,9 +825,9 @@ bool VertexModel::dirty() const
return mDirty;
}

bool VertexModel::angleFonud() const
int VertexModel::snappedAngle() const
{
return mAngleFonud;
return mSnappedAngle;
}

bool VertexModel::canRemoveVertex()
Expand Down Expand Up @@ -936,13 +912,13 @@ void VertexModel::setDirty( bool dirty )
emit dirtyChanged();
}

void VertexModel::setAngleFonud( bool angleFonud )
void VertexModel::setSnappedAngle( int snappedAngle )
{
if ( mAngleFonud == angleFonud )
if ( mSnappedAngle == snappedAngle )
return;

mAngleFonud = angleFonud;
emit angleFonudChanged();
mSnappedAngle = snappedAngle;
emit snappedAngleChanged();
}

void VertexModel::updateCanRemoveVertex()
Expand Down Expand Up @@ -1097,11 +1073,11 @@ void VertexModel::setEditingMode( VertexModel::EditingMode mode )
emit editingModeChanged();
}

void VertexModel::updateAngleFound()
void VertexModel::updateSnappedAngle()
{
if ( currentVertexIndex() == -1 )
{
setAngleFonud( false );
setSnappedAngle( 0 );
}
}

Expand Down
38 changes: 26 additions & 12 deletions src/core/vertexmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel
Q_PROPERTY( int ringCount READ ringCount NOTIFY ringCountChanged )
//! determines if the model has changes
Q_PROPERTY( bool dirty READ dirty NOTIFY dirtyChanged )

Q_PROPERTY( bool angleFonud READ angleFonud NOTIFY angleFonudChanged )

//! determines if the model allows editing the geometry
Q_PROPERTY( bool editingAllowed READ editingAllowed )
//! determines if one can remove current vertex
Expand All @@ -72,10 +69,13 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel
* The index of the currently active vertex. If no vertex is selected, this is -1.
*/
Q_PROPERTY( int currentVertexIndex READ currentVertexIndex WRITE setCurrentVertexIndex NOTIFY currentVertexIndexChanged )

//! The `snappedAngle` property holds the angle that has been adjusted to the nearest multiple of `snapToCommonAngleDegrees`.
//! This value is automatically updated whenever the angle is changed.
Q_PROPERTY( int snappedAngle READ snappedAngle NOTIFY snappedAngleChanged )
//! The `snapToCommonAngleDegrees` property specifies the angle increment to which the original angle will be snapped.
//! This value defines the common angle step for snapping.
Q_PROPERTY( int snapToCommonAngleDegrees READ snapToCommonAngleDegrees WRITE setSnapToCommonAngleDegrees NOTIFY snapToCommonAngleDegreesChanged )


/**
* The geometry in layer coordinates
*/
Expand Down Expand Up @@ -231,7 +231,6 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel

//! \copydoc dirty
bool dirty() const;
bool angleFonud() const;

//! \copydoc canRemoveVertex
bool canRemoveVertex();
Expand Down Expand Up @@ -274,8 +273,16 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel

bool canUndo();

double calculateAngle( const QgsPoint &a, const QgsPoint &b, const QgsPoint &c );
//! Returns `snappedAngle`
int snappedAngle() const;

//! sets snapped angle
void setSnappedAngle( int snappedAngle );

//! Returns `snapToCommonAngleDegrees`
int snapToCommonAngleDegrees() const;

//! Sets `snapToCommonAngleDegrees`
void setSnapToCommonAngleDegrees( int snapToCommonAngleDegrees );

signals:
Expand All @@ -291,7 +298,6 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel
void ringCountChanged();
//! \copydoc dirty
void dirtyChanged();
void angleFonudChanged();
//! \copydoc canRemoveVertex
void canRemoveVertexChanged();
//! \copydoc canAddVertex
Expand All @@ -315,6 +321,10 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel
//! Emitted when the history has been modified
void historyChanged();

//! Emitted when `snappedAngle` modified
void snappedAngleChanged();

//! Emitted when new `snapToCommonAngleDegrees` modified
void snapToCommonAngleDegreesChanged();

private:
Expand All @@ -323,13 +333,16 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel
//! This will not emit the reset signals, it's up to the caller to do so
void createCandidates();
void setDirty( bool dirty );
void setAngleFonud( bool angleFonud );
void updateCanRemoveVertex();
void updateCanAddVertex();
void updateCanPreviousNextVertex();
void updateAngleFound();
void setGeometryType( const Qgis::GeometryType &geometryType );

//! This function is called whenever the `currentVertexIndex` changes. It checks if there is an active vertex in editing mode.
//! If no vertex is active, the `snappedAngle` will be reset to 0. This ensures that the angle snapping logic is only applied
//! when there is an active vertex to work with.
void updateSnappedAngle();

QList<Vertex> mVertices;

//! copy of the initial geometry, in destination (layer) CRS
Expand All @@ -340,7 +353,6 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel
QgsCoordinateTransform mTransform = QgsCoordinateTransform();
bool mIsMulti = false;
bool mDirty = false;
bool mAngleFonud = false;

QVector<QgsPoint> mVerticesDeleted;

Expand Down Expand Up @@ -368,8 +380,10 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel
int mHistoryIndex = -1;
bool mHistoryTraversing = false;

int mSnappedAngle = 0;
int mSnapToCommonAngleDegrees = 0;

friend class VertexModelTest;
int mSnapToCommonAngleDegrees;
};

Q_DECLARE_METATYPE( VertexModel::Vertex );
Expand Down
4 changes: 2 additions & 2 deletions src/qml/CoordinateLocator.qml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Item {
inputCoordinate: {
// Get the current crosshair location in screen coordinates. If `undefined`, then we use the center of the screen as input point.
const location = sourceLocation === undefined ? Qt.point(locator.width / 2, locator.height / 2) : sourceLocation;
if (snapToCommonAngleButton.isSnapToCommonAngleEnabled && geometryEditingVertexModel.angleFonud) {
if (snapToCommonAngleButton.isSnapToCommonAngleEnabled && geometryEditingVertexModel.snappedAngle > 0) {
const vertexCount = geometryEditingVertexModel.vertexCount;
const currentIndex = geometryEditingVertexModel.currentVertexIndex;
let startPoint = currentIndex - 2;
Expand All @@ -77,7 +77,7 @@ Item {
const start = mapSettings.coordinateToScreen(geometryEditingVertexModel.currentPoint);
const p1 = mapSettings.coordinateToScreen(geometryEditingVertexModel.getPoint(startPoint));
const p2 = mapSettings.coordinateToScreen(geometryEditingVertexModel.getPoint(endPoint));
const intersections = getIntersectionPoints(start, p1, p2, 1000, 1000);
const intersections = getIntersectionPoints(start, p1, p2);
vertexSnapToCommonAngleLines.endCoordX1 = intersections.x1 || 0;
vertexSnapToCommonAngleLines.endCoordY1 = intersections.y1 || 0;
vertexSnapToCommonAngleLines.endCoordX2 = intersections.x2 || 0;
Expand Down

0 comments on commit 2bf1179

Please sign in to comment.