50 QPointF best_pt = point;
51 double best_dist = DBL_MAX;
66 bool insideLocalRect =
rect.contains(point);
68 return QPointF(qQNaN(), qQNaN());
69 }
else if (insideLocalRect) {
74 if (!isLastUsedPointCorrectNow &&
KisAlgebra2D::norm(point - strokeBegin) < moveThreshold) {
78 if (!snapToAny && isLastUsedPointCorrectNow) {
88 Q_FOREACH (
int vpIndex, possibleHandles) {
89 QPointF vp = *
handles()[vpIndex];
91 QPointF pt = QPointF();
92 QLineF snapLine = QLineF();
98 qreal dx = point.x() - strokeBegin.x();
99 qreal dy = point.y() - strokeBegin.y();
102 snapLine = QLineF(vp, strokeBegin);
104 QLineF vertical = QLineF(*
handles()[0],*
handles()[1]).normalVector();
105 snapLine = QLineF(vertical.p1(), vertical.p2());
106 QPointF translation = (vertical.p1()-strokeBegin)*-1.0;
107 snapLine = snapLine.translated(translation);
113 const qreal dx2 = dx * dx;
114 const qreal dy2 = dy * dy;
115 const qreal invsqrlen = 1.0 / (dx2 + dy2);
117 pt = QPointF(dx2 * point.x() + dy2 * snapLine.x1() + dx * dy * (point.y() - snapLine.y1()),
118 dx2 * snapLine.y1() + dy2 * point.y() + dx * dy * (point.x() - snapLine.x1()));
121 dist = qAbs(pt.x() - point.x()) + qAbs(pt.y() - point.y());
123 if (dist < best_dist) {
153 Q_UNUSED(updateRect);
159 bool isEditing =
false;
167 Q_FOREACH (
const QPointF* handle,
handles()) {
168 QPointF h = initialTransform.map(*handle);
169 QRectF ellipse = QRectF(QPointF(h.x() -15, h.y() -15), QSizeF(30, 30));
171 QPainterPath pathCenter;
172 pathCenter.addEllipse(ellipse);
178 QLineF normal = horizon.normalVector();
179 normal.translate(*
handles()[2]-normal.p1());
180 QPointF cov = horizon.center();
181 normal.intersects(horizon,&cov);
182 const QPointF center = initialTransform.map(cov);
183 QRectF center_ellipse = QRectF(QPointF(center.x() -15, center.y() -15), QSizeF(30, 30));
184 QPainterPath pathCenter;
185 pathCenter.addEllipse(center_ellipse);
193 QRect viewport = gc.viewport();
195 for (
int i = 0; i <
handles().size(); i++) {
196 const QPointF
p = initialTransform.map(*
handles()[i]);
197 for (
int currentAngle=0; currentAngle <= 180; currentAngle = currentAngle + tempDensity) {
200 float xPos = cos(currentAngle *
M_PI / 180);
201 float yPos = sin(currentAngle *
M_PI / 180);
206 QLineF snapLine = QLineF(
p,
p + unit);
210 path.moveTo(snapLine.p1());
211 path.lineTo(snapLine.p2());
214 QLineF snapLine2 = QLineF(
p,
p - unit);
218 path.moveTo(snapLine2.p1());
219 path.lineTo(snapLine2.p2());
236 const QRect viewport= gc.viewport();
238 const QPolygonF localPoly = (
isLocal() &&
handles().size() == 5) ? initialTransform.map(QPolygonF(
getLocalRect())) : QPolygonF();
239 const QPolygonF viewportAndLocalPoly = !localPoly.isEmpty() ? QPolygonF(QRectF(viewport)).intersected(localPoly) : QRectF(viewport);
243 QPainterPath previewPath;
246 if (assistantVisible ==
true || isEditing ==
true) {
247 QLineF horizonLine = initialTransform.map(QLineF(
p1,
p2));
249 path.moveTo(horizonLine.p1());
250 path.lineTo(horizonLine.p2());
254 if (isEditing ==
false && previewVisible ==
true &&
isSnappingActive() ==
true) {
257 QLineF snapMouse1 = QLineF(initialTransform.map(
p1), mousePos);
258 QLineF snapMouse2 = QLineF(initialTransform.map(
p2), mousePos);
261 previewPath.moveTo(snapMouse1.p1());
262 previewPath.lineTo(snapMouse1.p2());
263 previewPath.moveTo(snapMouse2.p1());
264 previewPath.lineTo(snapMouse2.p2());
268 if (isEditing ==
true && !
sideHandles().isEmpty()) {
269 path.moveTo(initialTransform.map(
p1));
270 path.lineTo(initialTransform.map(*
sideHandles()[0]));
271 path.lineTo(initialTransform.map(*
sideHandles()[1]));
272 path.moveTo(initialTransform.map(
p2));
273 path.lineTo(initialTransform.map(*
sideHandles()[2]));
274 path.lineTo(initialTransform.map(*
sideHandles()[3]));
275 path.moveTo(initialTransform.map(
p1));
276 path.lineTo(initialTransform.map(*
sideHandles()[4]));
277 path.lineTo(initialTransform.map(*
sideHandles()[5]));
278 path.moveTo(initialTransform.map(
p2));
279 path.lineTo(initialTransform.map(*
sideHandles()[6]));
280 path.lineTo(initialTransform.map(*
sideHandles()[7]));
284 if (showLocal && assistantVisible) {
287 QPointF
p2 = QPointF(
p1.x(),
p3.y());
288 QPointF p4 = QPointF(
p3.x(),
p1.y());
290 path.moveTo(initialTransform.map(
p1));
292 path.lineTo(initialTransform.map(
p2));
293 path.lineTo(initialTransform.map(
p3));
294 path.lineTo(initialTransform.map(p4));
295 path.lineTo(initialTransform.map(
p1));
303 path = QPainterPath();
308 const QTransform inv = t.inverted();
309 const QPointF vp_a = t.map(
p1);
310 const QPointF vp_b = t.map(
p2);
312 if ((vp_a.x() < 0 && vp_b.x() > 0) ||
313 (vp_a.x() > 0 && vp_b.x() < 0)) {
316 QLineF vertical = initialTransform.map(inv.map(QLineF::fromPolar(1,90)));
317 if (!isEditing) vertical.translate(mousePos - vertical.p1());
319 if (previewVisible) {
320 path.moveTo(vertical.p1());
321 path.lineTo(vertical.p2());
324 if (assistantVisible) {
326 path.moveTo(initialTransform.map(inv.map(QPointF(0,vp_a.y()-10))));
327 path.lineTo(initialTransform.map(inv.map(QPointF(0,vp_a.y()+10))));
330 path = QPainterPath();
334 const QPointF upper = QPointF(0,vp_a.y() + size);
335 const QPointF lower = QPointF(0,vp_a.y() - size);
340 QGradient fade = QLinearGradient(initialTransform.map(inv.map(upper)),
341 initialTransform.map(inv.map(lower)));
344 fade.setColorAt(0.5, color);
346 const QPen pen = gc.pen();
347 const QBrush new_brush = QBrush(fade);
349 const QPen new_pen = QPen(new_brush, width, pen.style());
356 Q_FOREACH (
const QPointF sp, station_points) {
359 Q_FOREACH (
const QPointF vp, vanishing_points) {
362 const qreal initial_angle = QLineF(sp, vp).angle();
363 const qreal interval = size*
m_gridDensity / cos((initial_angle - 90) *
M_PI/180);
364 const QPointF translation = QPointF(interval, 0);
367 Q_FOREACH (
const int dir,
QList<int>({-1, 1})) {
370 for (
int i = 0; i <= 300; i++) {
371 const QLineF gridline = QLineF(sp + translation * i * dir, vp);
374 const qreal angle = gridline.angle();
375 if (angle < 0.25 || angle > 359.75 || (angle < 180.25 && angle > 179.75)) {
379 QLineF drawn_gridline = initialTransform.map(inv.map(gridline));
382 if (assistantVisible || isEditing ==
true) {
383 path.moveTo(drawn_gridline.p2());
384 path.lineTo(drawn_gridline.p1());