Krita Source Code Documentation
Loading...
Searching...
No Matches
KisSafeTransform Class Reference

#include <kis_safe_transform.h>

+ Inheritance diagram for KisSafeTransform:

Public Member Functions

QPolygonF dstClipPolygon () const
 
QPolygonF getCroppedPolygon (const QLineF &baseHorizon, const QRect &rc, const qreal crossCoeff)
 
qreal getCrossSign (const QLineF &horizon, const QRectF &rc)
 
bool getHorizon (const QTransform &t, QLineF *horizon)
 
 KisSafeTransform (const QTransform &transform, const QRect &bounds, const QRect &srcInterestRect)
 
QPolygonF mapBackward (const QPolygonF &p)
 
QPolygonF mapForward (const QPolygonF &p)
 
QRect mapRectBackward (const QRect &rc)
 
QRectF mapRectBackward (const QRectF &rc)
 
QRect mapRectForward (const QRect &rc)
 
QRectF mapRectForward (const QRectF &rc)
 
QPolygonF srcClipPolygon () const
 
 ~KisSafeTransform ()
 
- Public Member Functions inherited from Private
 Private (KisCanvas2 *c)
 

Public Attributes

QTransform backwardTransform
 
QRect bounds
 
QPolygonF dstClipPolygon
 
QTransform forwardTransform
 
bool needsClipping = true
 
QPolygonF srcClipPolygon
 
- Public Attributes inherited from Private
KisCanvas2canvas
 
int displayedFrame
 
int intendedFrame
 

Private Attributes

const QScopedPointer< Privatem_d
 

Detailed Description

Definition at line 19 of file kis_safe_transform.cpp.

Constructor & Destructor Documentation

◆ KisSafeTransform()

KisSafeTransform::KisSafeTransform ( const QTransform & transform,
const QRect & bounds,
const QRect & srcInterestRect )

Definition at line 116 of file kis_safe_transform.cpp.

119 : m_d(new Private)
120{
121 m_d->bounds = bounds;
122
123 m_d->forwardTransform = transform;
124 m_d->backwardTransform = transform.inverted();
125
126 m_d->needsClipping = transform.type() > QTransform::TxShear;
127
128 if (m_d->needsClipping) {
129 m_d->srcClipPolygon = QPolygonF(QRectF(m_d->bounds));
130 m_d->dstClipPolygon = QPolygonF(QRectF(m_d->bounds));
131
132 qreal crossCoeff = 1.0;
133
134 QLineF srcHorizon;
135 if (m_d->getHorizon(m_d->backwardTransform, &srcHorizon)) {
136 crossCoeff = m_d->getCrossSign(srcHorizon, srcInterestRect);
137 m_d->srcClipPolygon = m_d->getCroppedPolygon(srcHorizon, m_d->bounds, crossCoeff);
138 }
139
140 QLineF dstHorizon;
141 if (m_d->getHorizon(m_d->forwardTransform, &dstHorizon)) {
142 crossCoeff = m_d->getCrossSign(dstHorizon, mapRectForward(srcInterestRect));
143 m_d->dstClipPolygon = m_d->getCroppedPolygon(dstHorizon, m_d->bounds, crossCoeff);
144 }
145 }
146}
const QScopedPointer< Private > m_d
QRectF mapRectForward(const QRectF &rc)

References bounds, m_d, and mapRectForward().

◆ ~KisSafeTransform()

KisSafeTransform::~KisSafeTransform ( )

Definition at line 148 of file kis_safe_transform.cpp.

149{
150}

Member Function Documentation

◆ dstClipPolygon()

QPolygonF KisSafeTransform::dstClipPolygon ( ) const

◆ getCroppedPolygon()

QPolygonF KisSafeTransform::getCroppedPolygon ( const QLineF & baseHorizon,
const QRect & rc,
const qreal crossCoeff )
inline

Definition at line 58 of file kis_safe_transform.cpp.

58 {
59 if (rc.isEmpty()) return QPolygonF();
60
61 QRectF boundsRect(rc);
62 QPolygonF polygon(boundsRect);
63 QPolygonF result;
64
65 // calculate new (offset) horizon to avoid infinity
66 const qreal offsetLength = 10.0;
67 const QPointF horizonOffset = offsetLength * crossCoeff *
68 KisAlgebra2D::rightUnitNormal(baseHorizon.p2() - baseHorizon.p1());
69
70 const QLineF horizon = baseHorizon.translated(horizonOffset);
71
72 // base vectors to calculate the side of the horizon
73 const QPointF &basePoint = horizon.p1();
74 const QPointF horizonVec = horizon.p2() - basePoint;
75
76
77 // iteration
78 QPointF prevPoint = polygon[polygon.size() - 1];
79 qreal prevCross = crossCoeff * KisAlgebra2D::crossProduct(horizonVec, prevPoint - basePoint);
80
81 for (int i = 0; i < polygon.size(); i++) {
82 const QPointF &pt = polygon[i];
83
84 qreal cross = crossCoeff * KisAlgebra2D::crossProduct(horizonVec, pt - basePoint);
85
86 if ((cross >= 0 && prevCross >= 0) || (cross == 0 && prevCross < 0)) {
87 result << pt;
88 } else if (cross * prevCross < 0) {
89 QPointF intersection;
90 QLineF edge(prevPoint, pt);
91 QLineF::IntersectType intersectionType =
92 horizon.intersects(edge, &intersection);
93
94 KIS_ASSERT_RECOVER_NOOP(intersectionType != QLineF::NoIntersection);
95
96 result << intersection;
97
98 if (cross > 0) {
99 result << pt;
100 }
101 }
102
103 prevPoint = pt;
104 prevCross = cross;
105 }
106
107 if (result.size() > 0 && !result.isClosed()) {
108 result << result.first();
109 }
110
111 return result;
112 }
#define KIS_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:97
PointTypeTraits< T >::value_type crossProduct(const T &a, const T &b)
T rightUnitNormal(const T &a)

References KisAlgebra2D::crossProduct(), KIS_ASSERT_RECOVER_NOOP, and KisAlgebra2D::rightUnitNormal().

◆ getCrossSign()

qreal KisSafeTransform::getCrossSign ( const QLineF & horizon,
const QRectF & rc )
inline

Definition at line 51 of file kis_safe_transform.cpp.

51 {
52 if (rc.isEmpty()) return 1.0;
53
54 QPointF diff = horizon.p2() - horizon.p1();
55 return KisAlgebra2D::signPZ(KisAlgebra2D::crossProduct(diff, rc.center() - horizon.p1()));
56 }

References KisAlgebra2D::crossProduct(), and KisAlgebra2D::signPZ().

◆ getHorizon()

bool KisSafeTransform::getHorizon ( const QTransform & t,
QLineF * horizon )
inline

Definition at line 30 of file kis_safe_transform.cpp.

30 {
31 static const qreal eps = 1e-10;
32
33 QPointF vanishingX(t.m11() / t.m13(), t.m12() / t.m13());
34 QPointF vanishingY(t.m21() / t.m23(), t.m22() / t.m23());
35
36 if (qAbs(t.m13()) < eps && qAbs(t.m23()) < eps) {
37 *horizon = QLineF();
38 return false;
39 } else if (qAbs(t.m23()) < eps) {
40 QPointF diff = t.map(QPointF(0.0, 10.0)) - t.map(QPointF());
41 vanishingY = vanishingX + diff;
42 } else if (qAbs(t.m13()) < eps) {
43 QPointF diff = t.map(QPointF(10.0, 0.0)) - t.map(QPointF());
44 vanishingX = vanishingY + diff;
45 }
46
47 *horizon = QLineF(vanishingX, vanishingY);
48 return true;
49 }
const qreal eps

References eps.

◆ mapBackward()

QPolygonF KisSafeTransform::mapBackward ( const QPolygonF & p)

Definition at line 176 of file kis_safe_transform.cpp.

177{
178 QPolygonF poly;
179
180 if (!m_d->needsClipping) {
181 poly = m_d->backwardTransform.map(p);
182 } else {
183 poly = m_d->dstClipPolygon.intersected(p);
184 poly = m_d->backwardTransform.map(poly).intersected(QRectF(m_d->bounds));
185 }
186
187 return poly;
188}
const Params2D p

References m_d, and p.

◆ mapForward()

QPolygonF KisSafeTransform::mapForward ( const QPolygonF & p)

Definition at line 162 of file kis_safe_transform.cpp.

163{
164 QPolygonF poly;
165
166 if (!m_d->needsClipping) {
167 poly = m_d->forwardTransform.map(p);
168 } else {
169 poly = m_d->srcClipPolygon.intersected(p);
170 poly = m_d->forwardTransform.map(poly).intersected(QRectF(m_d->bounds));
171 }
172
173 return poly;
174}

References m_d, and p.

◆ mapRectBackward() [1/2]

QRect KisSafeTransform::mapRectBackward ( const QRect & rc)

Definition at line 205 of file kis_safe_transform.cpp.

206{
207 return mapRectBackward(QRectF(rc)).toAlignedRect();
208}
QRectF mapRectBackward(const QRectF &rc)

References mapRectBackward().

◆ mapRectBackward() [2/2]

QRectF KisSafeTransform::mapRectBackward ( const QRectF & rc)

Definition at line 195 of file kis_safe_transform.cpp.

196{
197 return mapBackward(rc).boundingRect();
198}
QPolygonF mapBackward(const QPolygonF &p)

References mapBackward().

◆ mapRectForward() [1/2]

QRect KisSafeTransform::mapRectForward ( const QRect & rc)

Definition at line 200 of file kis_safe_transform.cpp.

201{
202 return mapRectForward(QRectF(rc)).toAlignedRect();
203}

References mapRectForward().

◆ mapRectForward() [2/2]

QRectF KisSafeTransform::mapRectForward ( const QRectF & rc)

Definition at line 190 of file kis_safe_transform.cpp.

191{
192 return mapForward(rc).boundingRect();
193}
QPolygonF mapForward(const QPolygonF &p)

References mapForward().

◆ srcClipPolygon()

QPolygonF KisSafeTransform::srcClipPolygon ( ) const

Member Data Documentation

◆ backwardTransform

QTransform KisSafeTransform::backwardTransform

Definition at line 25 of file kis_safe_transform.cpp.

◆ bounds

QRect KisSafeTransform::bounds

Definition at line 23 of file kis_safe_transform.cpp.

◆ dstClipPolygon

QPolygonF KisSafeTransform::dstClipPolygon

Definition at line 28 of file kis_safe_transform.cpp.

◆ forwardTransform

QTransform KisSafeTransform::forwardTransform

Definition at line 24 of file kis_safe_transform.cpp.

◆ m_d

const QScopedPointer<Private> KisSafeTransform::m_d
private

Definition at line 43 of file kis_safe_transform.h.

◆ needsClipping

bool KisSafeTransform::needsClipping = true

Definition at line 21 of file kis_safe_transform.cpp.

◆ srcClipPolygon

QPolygonF KisSafeTransform::srcClipPolygon

Definition at line 27 of file kis_safe_transform.cpp.


The documentation for this class was generated from the following files: