File indexing completed on 2024-09-22 04:06:59

0001 /*
0002  * SPDX-FileCopyrightText: 2022 Agata Cacko <cacko.azh@gmail.com>
0003  */
0004 
0005 #ifndef _PERSPECTIVE_BASED_ASSISTANT_HELPER_H_
0006 #define _PERSPECTIVE_BASED_ASSISTANT_HELPER_H_
0007 
0008 
0009 #include <QObject>
0010 #include <boost/optional.hpp>
0011 
0012 #include "Ellipse.h"
0013 #include "kis_abstract_perspective_grid.h"
0014 #include "kis_painting_assistant.h"
0015 
0016 #include "kritaassistanttool_export.h"
0017 
0018 class KRITAASSISTANTTOOL_EXPORT PerspectiveBasedAssistantHelper
0019 {
0020 private:
0021     PerspectiveBasedAssistantHelper();
0022     ~PerspectiveBasedAssistantHelper();
0023 
0024 
0025 public:
0026 
0027     class CacheData
0028     {
0029     public:
0030         // vanishing points that one gets from getVanishingPoints
0031         boost::optional<QPointF> vanishingPoint1 {boost::none};
0032         boost::optional<QPointF> vanishingPoint2 {boost::none};
0033 
0034         // distances from the horizon line to point 1, 2, 3 and 4 on the final polygon
0035         QVector<qreal> distancesFromPoints;
0036         qreal maxDistanceFromPoint {0.0};
0037 
0038         QLineF horizon;
0039 
0040         // final polygon
0041         QPolygonF polygon;
0042 
0043 
0044         typedef enum PerspectiveType {
0045             None,
0046             OneVp,
0047             TwoVps
0048         } PerspectiveType;
0049 
0050 
0051         PerspectiveType type {None};
0052 
0053     };
0054 
0055 
0056 
0057     // *** main functions ***
0058 
0059     // creates the convex hull, returns false if it's not a quadrilateral/tetragon
0060     static bool getTetragon(const QList<KisPaintingAssistantHandleSP> &handles, bool isAssistantComplete, QPolygonF& outPolygon);
0061 
0062     // creates a fully connected tetragon (as in, every vertex is connected to every other vertex)
0063     // this is useful for drawing a wrong state in perspective-based assistants (when one vertex is inside the triangle created by the rest of them)
0064     static QPolygonF getAllConnectedTetragon(const QList<KisPaintingAssistantHandleSP>& handles);
0065 
0066     // distance in Perspective grid
0067     // used for calculating the Perspective sensor
0068     static qreal distanceInGrid(const QList<KisPaintingAssistantHandleSP>& handles, bool isAssistantComplete, const QPointF &point);
0069 
0070     // distance in Perspective grid
0071     // used for calculating the Perspective sensor
0072     static qreal distanceInGrid(const CacheData& cache, const QPointF &point);
0073 
0074     static void updateCacheData(CacheData& cache, const QPolygonF& poly);
0075 
0076     // vp1 - vp for lines 0-1 and 2-3
0077     // vp2 - vp for lines 1-2 and 3-0
0078     static bool getVanishingPointsOptional(const QPolygonF &poly, boost::optional<QPointF>& vp1, boost::optional<QPointF>& vp2);
0079 
0080 
0081 
0082     static qreal localScale(const QTransform& transform, QPointF pt);
0083 
0084     // returns the reciprocal of the maximum local scale at the points (0,0),(0,1),(1,0),(1,1)
0085     static qreal inverseMaxLocalScale(const QTransform& transform);
0086 
0087 
0088     // *** small helper functions ***
0089 
0090     // perpendicular dot product
0091     // it's basically a dot product between vector A(xa, ya) and vector B'(xb, -yb)
0092     // or a dot product between vector A'(xa, -ya) and vector B(xb, yb)
0093     // if it's needed elsewhere in Krita too, you can move it to KisAlgebra2D
0094     static qreal pdot(const QPointF& a, const QPointF& b);
0095 
0096 };
0097 
0098 #endif