[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [Calligra] a9be43f: implement perspective value calculation
From: Geoffry Song <goffrie () gmail ! com>
Date: 2010-12-31 23:27:34
Message-ID: 20101231232734.28C4AA6092 () git ! kde ! org
[Download RAW message or body]
A krita/ui/kis_abstract_perspective_grid.h [License: UNKNOWN]
commit a9be43f3a1d52b80bfa461a9c851c22064d215c7
Author: Geoffry Song <goffrie@gmail.com>
Date: Wed Dec 29 21:50:06 2010 -0500
implement perspective value calculation
diff --git a/krita/plugins/assistants/RulerAssistant/PerspectiveAssistant.cc \
b/krita/plugins/assistants/RulerAssistant/PerspectiveAssistant.cc index \
0442ded..95d1106 100644
--- a/krita/plugins/assistants/RulerAssistant/PerspectiveAssistant.cc
+++ b/krita/plugins/assistants/RulerAssistant/PerspectiveAssistant.cc
@@ -28,8 +28,8 @@
#include "kis_coordinates_converter.h"
#include <math.h>
-
#include <limits>
+#include <algorithm>
PerspectiveAssistant::PerspectiveAssistant()
: KisPaintingAssistant("perspective", i18n("Perspective assistant"))
@@ -104,6 +104,51 @@ void PerspectiveAssistant::endStroke()
snapLine = QLineF();
}
+bool PerspectiveAssistant::contains(const QPointF& pt) const
+{
+ QPolygonF poly;
+ if (!quad(poly)) return false;
+ return poly.containsPoint(pt, Qt::OddEvenFill);
+}
+
+inline qreal lengthSquared(const QPointF& vector)
+{
+ return vector.x() * vector.x() + vector.y() * vector.y();
+}
+
+inline qreal distanceSquared(const QTransform& transform, QPointF pt, QPointF orig)
+{
+ const qreal epsilon = 1e-5, epsilonSquared = epsilon * epsilon;
+ qreal xSizeSquared = lengthSquared(transform.map(pt + QPointF(epsilon, 0.0)) - \
orig) / epsilonSquared; + qreal ySizeSquared = lengthSquared(transform.map(pt + \
QPointF(0.0, epsilon)) - orig) / epsilonSquared; + xSizeSquared /= \
lengthSquared(transform.map(QPointF(0.0, pt.y())) - transform.map(QPointF(1.0, \
pt.y()))); + ySizeSquared /= lengthSquared(transform.map(QPointF(pt.x(), 0.0)) - \
transform.map(QPointF(pt.x(), 1.0))); + return xSizeSquared + ySizeSquared;
+}
+
+qreal PerspectiveAssistant::distance(const QPointF& pt) const
+{
+ QPolygonF poly;
+ if (!quad(poly)) return 1.0;
+ QTransform transform;
+ if (!QTransform::squareToQuad(poly, transform)) return 1.0;
+ bool invertible;
+ QTransform inverse = transform.inverted(&invertible);
+ if (!invertible) return 1.0;
+ if (inverse.m13() * pt.x() + inverse.m23() * pt.y() + inverse.m33() == 0.0) {
+ // point at infinity
+ return 0.0;
+ }
+ QPointF realPoint = inverse.map(pt);
+ const qreal corners[4] = {
+ distanceSquared(transform, QPointF(0.0, 0.0), transform.map(QPointF(0.0, \
0.0))), + distanceSquared(transform, QPointF(0.0, 1.0), \
transform.map(QPointF(0.0, 1.0))), + distanceSquared(transform, QPointF(1.0, \
0.0), transform.map(QPointF(1.0, 0.0))), + distanceSquared(transform, \
QPointF(1.0, 1.0), transform.map(QPointF(1.0, 1.0)))}; + const qreal max = \
std::max(std::max(corners[0], corners[1]), std::max(corners[2], corners[3])); + \
return sqrt(distanceSquared(transform, realPoint, pt) / max); +}
+
// draw a vanishing point marker
inline void drawX(QPainter& gc, const QPointF& pt)
{
diff --git a/krita/plugins/assistants/RulerAssistant/PerspectiveAssistant.h \
b/krita/plugins/assistants/RulerAssistant/PerspectiveAssistant.h index \
4048f0d..19fea0e 100644
--- a/krita/plugins/assistants/RulerAssistant/PerspectiveAssistant.h
+++ b/krita/plugins/assistants/RulerAssistant/PerspectiveAssistant.h
@@ -19,12 +19,13 @@
#ifndef _PERSPECTIVE_ASSISTANT_H_
#define _PERSPECTIVE_ASSISTANT_H_
+#include "kis_abstract_perspective_grid.h"
#include "kis_painting_assistant.h"
#include <QObject>
#include <QPolygonF>
#include <QLineF>
-class PerspectiveAssistant : public KisPaintingAssistant
+class PerspectiveAssistant : public KisPaintingAssistant, public \
KisAbstractPerspectiveGrid {
public:
PerspectiveAssistant();
@@ -33,6 +34,9 @@ public:
void drawAssistant(QPainter& gc, const QRectF& updateRect, const \
KisCoordinatesConverter *converter); virtual QPointF buttonPosition() const;
virtual int numHandles() const { return 4; }
+
+ virtual bool contains(const QPointF& point) const;
+ virtual qreal distance(const QPointF& point) const;
private:
QPointF project(const QPointF& pt, const QPointF& strokeBegin);
// creates the convex hull, returns false if it's not a quadrilateral
diff --git a/krita/ui/kis_abstract_perspective_grid.h \
b/krita/ui/kis_abstract_perspective_grid.h new file mode 100644
index 0000000..864b482
--- /dev/null
+++ b/krita/ui/kis_abstract_perspective_grid.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of Krita
+ *
+ * Copyright (c) 2010 Geoffry Song <goffrie@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_ABSTRACT_PERSPECTIVE_GRID_H
+#define KIS_ABSTRACT_PERSPECTIVE_GRID_H
+
+#include <QPointF>
+
+class KisAbstractPerspectiveGrid
+{
+public:
+ virtual bool contains(const QPointF& pt) const = 0;
+ /**
+ * Returns the reciprocal of the distance from the given point
+ * to the 'observer', in the range [0, 1] where 0 = inifinite
+ * distance and 1 = closest.
+ */
+ virtual qreal distance(const QPointF& pt) const = 0;
+};
+
+#endif
diff --git a/krita/ui/tool/kis_tool_freehand.cc b/krita/ui/tool/kis_tool_freehand.cc
index 702c6dc..2359aea 100644
--- a/krita/ui/tool/kis_tool_freehand.cc
+++ b/krita/ui/tool/kis_tool_freehand.cc
@@ -48,6 +48,7 @@
// Krita/ui
+#include "kis_abstract_perspective_grid.h"
#include "kis_config.h"
#include <opengl/kis_opengl.h>
#include "canvas/kis_canvas2.h"
@@ -141,10 +142,19 @@ void KisToolFreehand::mousePressEvent(KoPointerEvent *e)
* FIXME: we need some better way to implement modifiers
* for a paintop level
*/
+ QPointF pos = adjustPosition(e->point, e->point);
+ qreal perspective = 1.0;
+ foreach (const KisPaintingAssistant* assistant, \
static_cast<KisCanvas2*>(canvas())->view()->paintingAssistantManager()->assistants()) \
{ + const KisAbstractPerspectiveGrid* perspectiveGrid = dynamic_cast<const \
KisAbstractPerspectiveGrid*>(assistant); + if (!perspectiveGrid) continue;
+ if (!perspectiveGrid->contains(pos)) continue;
+ perspective = perspectiveGrid->distance(pos);
+ break;
+ }
bool ignoreEvent = \
currentPaintOpPreset()->settings()->mousePressEvent(KisPaintInformation(convertToPixelCoord(e->point),
\
pressureToCurve(e->pressure()), e->xTilt(), e->yTilt(),
KisVector2D::Zero(),
- e->rotation(), \
e->tangentialPressure(), 1.0, m_strokeTimeMeasure.elapsed()),e->modifiers()); + \
e->rotation(), e->tangentialPressure(), perspective, \
m_strokeTimeMeasure.elapsed()),e->modifiers()); if (!ignoreEvent){
e->accept();
return;
@@ -168,7 +178,7 @@ void KisToolFreehand::mousePressEvent(KoPointerEvent *e)
m_previousPaintInformation = \
KisPaintInformation(convertToPixelCoord(adjustPosition(e->point, \
e->point)),
\
pressureToCurve(e->pressure()), e->xTilt(), e->yTilt(),
KisVector2D::Zero(),
- e->rotation(), \
e->tangentialPressure(), 1.0, m_strokeTimeMeasure.elapsed()); + \
e->rotation(), e->tangentialPressure(), perspective, m_strokeTimeMeasure.elapsed()); \
m_strokeBegin = e->point;
e->accept();
@@ -212,13 +222,23 @@ void KisToolFreehand::mouseMoveEvent(KoPointerEvent *e)
/**
* Actual painting
*/
- QPointF pos = convertToPixelCoord(adjustPosition(e->point, m_strokeBegin));
+ QPointF adjusted = adjustPosition(e->point, m_strokeBegin);
+ QPointF pos = convertToPixelCoord(adjusted);
QPointF dragVec = pos - m_previousPaintInformation.pos();
+ qreal perspective = 1.0;
+ foreach (const KisPaintingAssistant* assistant, \
static_cast<KisCanvas2*>(canvas())->view()->paintingAssistantManager()->assistants()) \
{ + const KisAbstractPerspectiveGrid* perspectiveGrid = dynamic_cast<const \
KisAbstractPerspectiveGrid*>(assistant); + if (!perspectiveGrid) continue;
+ if (!perspectiveGrid->contains(adjusted)) continue;
+ perspective = perspectiveGrid->distance(adjusted);
+ break;
+ }
+
KisPaintInformation info =
KisPaintInformation(pos, pressureToCurve(e->pressure()),
e->xTilt(), e->yTilt(), toKisVector2D(dragVec),
- e->rotation(), e->tangentialPressure(), 1.0,
+ e->rotation(), e->tangentialPressure(), perspective,
m_strokeTimeMeasure.elapsed());
if (m_smooth) {
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic