整理下大作业例子,这个是按照AutoCAD的操作模式写的,单击线和圆弧将显示夹点,点击夹点将修改实体,
图形学课程的算法都是讲怎么生成像素,像DDA或者光栅化的讲OpenGL内部怎么实现的,所以一般不是讲怎么用OpenGL。
实现是在QPainter上绘制。程序是在VC2019,Qt5.14.2-msvc2017-64预编译库, Eigen3是eigen-3.4.0。蓝奏云上压缩包是编译好的exe,
地址 QtWidgets00
下面的代码实现在QXViewWgt.h 和QXViewWgt.cpp 这个自定义的QWidget中。
截图
QXViewWgt.h
#pragma once
#include <QWidget>
#include "ui_QXViewWgt.h"
class QXViewWgt : public QWidget
{
Q_OBJECT
public:
QXViewWgt(QWidget* parent = Q_NULLPTR);
~QXViewWgt();
void paintEvent(QPaintEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
private:
Ui::QXViewWgt ui;
};
QXViewWgt.cpp
/* -*-c++-*- vege module - Copyright (C) 2008 yrcpp
*
* This file 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.
*/
#include "QXViewWgt.h"
#include <QtGui/QPainter>
#include <QMouseEvent>
#include <Eigen/Eigen>
#include <vector>
#include <set>
#include <map>
#include <memory>
#define _USE_MATH_DEFINES
#include <math.h>
const double MIN_DIST = 1e-4;
namespace vege
{
static QPainter* s_painter = nullptr;
enum CurveState
{
CST_DEFAULT,
CST_SNAPPED,
CST_PICKED
};
class GripPoint
{
public:
Eigen::Vector2d pt;
};
class Curve2d
{
protected:
CurveState _state;
std::map<int, GripPoint> _gripPoints;
std::map<int, GripPoint> _preview_gripPoints;
//bool _showGripPoint;
bool _showModifyPreview;
public:
Curve2d() :_state(CST_DEFAULT),
//_showGripPoint(false),
_showModifyPreview(false)
{}
virtual ~Curve2d() {}
virtual bool projectPoint(Eigen::Vector2d p, Eigen::Vector2d& q) = 0;
virtual bool movePreviewGripPoint(int id, Eigen::Vector2d newPos) = 0;
virtual bool updateGripPoint(int id, Eigen::Vector2d newPos) = 0;
bool isGripPointShow() { return _state == CST_PICKED; }
virtual void paint()
{
if (_state == CST_PICKED)
{
QPen pen0;
pen0.setColor(QColor(101, 101, 101));
pen0.setWidth(2);
s_painter->setPen(pen0);
double gripBoxW = 16.0;
for (auto& g : _gripPoints)
{
s_painter->fillRect(g.second.pt.x() - gripBoxW * 0.5, g.second.pt.y() - gripBoxW * 0.5, gripBoxW, gripBoxW, QColor(0, 127, 255));
s_painter->drawRect(g.second.pt.x() - gripBoxW*0.5, g.second.pt.y() - gripBoxW * 0.5, gripBoxW, gripBoxW);
}
}
};
virtual void setState(CurveState s)
{
if (_state == CST_PICKED && _state != s)
{
int k = 0;
}
_state = s;
};
virtual bool stateIs(CurveState s)
{
return _state == s;
};
int snapGripPoints(Eigen::Vector2d mos, double boxHalfSize, Eigen::Vector2d& gripPtPos)
{
for (auto& g : _gripPoints)
{
if (fabs(g.second.pt[0] - mos[0]) < boxHalfSize &&
fabs(g.second.pt[1] - mos[1]) < boxHalfSize)
{
gripPtPos = g.second.pt;
return g.first;
}
}
return -1;
}
virtual void previewConfirm() {};
};
class Line2d : public Curve2d
{
public:
Eigen::Vector2d _s;
Eigen::Vector2d _e;
Eigen::Vector2d _preview_s;
Eigen::Vector2d _preview_e;
Line2d(Eigen::Vector2d s, Eigen::Vector2d e) :_s(s), _e(e)
{
_gripPoints[0].pt = _s;
_gripPoints[1].pt = (_s + _e) * 0.5;
_gripPoints[2].pt = _e;
_preview_gripPoints = _gripPoints;
_preview_s = _s;
_preview_e = _e;
}
virtual bool projectPoint(Eigen::Vector2d p, Eigen::Vector2d& q)
{
Eigen::Vector2d d = _e - _s;
double v_se_length = d.norm();
d.normalize();
auto v_sp = p - _s;
auto v_sq_length = (p - _s).dot(d);
if (fabs(v_sq_length) < MIN_DIST)
{
q = _s;
return true;
}
if (fabs(v_sq_length - v_se_length) < MIN_DIST)
{
q = _e;
return true;
}
if (v_sq_length > 0.0 && v_sq_length < v_se_length)
{
q = _s + d * v_sq_length;
return true;
}
q = { 0, 0 };
return false;
}
void computeParametersByGripPointModify(std::map<int, GripPoint>& gripPoints,
int id, Eigen::Vector2d newPos,
Eigen::Vector2d& s, Eigen::Vector2d& e)
{
if (id == 0)
{
gripPoints[0].pt = newPos;
gripPoints[1].pt = (gripPoints[0].pt + gripPoints[2].pt) * 0.5;
}
else if (id == 1)
{
Eigen::Vector2d v = newPos - gripPoints[1].pt;
gripPoints[1].pt = newPos;
gripPoints[0].pt = gripPoints[0].pt + v;
gripPoints[2].pt = gripPoints[2].pt + v;
}
else if (id == 2)
{
gripPoints[2].pt = newPos;
gripPoints[1].pt = (gripPoints[0].pt + gripPoints[2].pt) * 0.5;
}
s = gripPoints[0].pt;
e = gripPoints[2].pt;
}
virtual bool movePreviewGripPoint(int id, Eigen::Vector2d newPos)
{
computeParametersByGripPointModify(_preview_gripPoints, id, newPos, _preview_s, _preview_e);
_showModifyPreview = true;
return true;
}
virtual void previewConfirm()
{
_gripPoints = _preview_gripPoints;
_s = _gripPoints[0].pt;
_e = _gripPoints[2].pt;
_preview_s = _s;
_preview_e = _e;
_showModifyPreview = false;
}
virtual bool updateGripPoint(int id, Eigen::Vector2d newPos)
{
computeParametersByGripPointModify(_gripPoints, id, newPos, _s, _e);
_preview_gripPoints = _gripPoints;
_preview_s = _s;
_preview_e = _e;
_showModifyPreview = false;
return true;
}
virtual void paint()
{
switch (_state)
{
case CST_DEFAULT:
{
QPen pen0;
pen0.setColor(QColor(255, 255, 255));
pen0.setWidth(1);
s_painter->setPen(pen0);
s_painter->drawLine(_s(0), _s(1), _e(0), _e(1));
}
break;
case CST_SNAPPED:
{
QPen pen0;
pen0.setColor(QColor(255, 255, 255));
pen0.setWidth(3);
s_painter->setPen(pen0);
s_painter->drawLine(_s(0), _s(1), _e(0), _e(1));
pen0.setColor(QColor(0, 0, 0));
pen0.setWidth(1);
pen0.setStyle(Qt::DotLine);
s_painter->setPen(pen0);
s_painter->drawLine(_s(0), _s(1), _e(0), _e(1));
}
break;
case CST_PICKED:
{
QPen pen0;
pen0.setColor(QColor(255, 255, 255));
pen0.setWidth(1);
pen0.setStyle(Qt::DashLine);
s_painter->setPen(pen0);
s_painter->drawLine(_s(0), _s(1), _e(0), _e(1));
}
break;
default:
break;
}
Curve2d::paint();
if (_showModifyPreview)
{
QPen pen0;
pen0.setColor(QColor(255, 255, 255));
pen0.setWidth(1);
s_painter->setPen(pen0);
s_painter->drawLine(_preview_s(0), _preview_s(1), _preview_e(0), _preview_e(1));
}
}
};
struct Arc2dPara
{
Eigen::Vector2d _c;
double _r;
double _sang; //degree, [0.0,360)
double _eang;
};
class Arc2d : public Curve2d
{
public:
Eigen::Vector2d _c;
double _r;
double _sang; //degree, [0.0,360)
double _eang;
Arc2dPara _preview_para;
std::vector<QPointF> _polyline;
std::vector<QPointF> _preview_polyline;
double _deg2rad(double degv)
{
return (M_PI * degv) / 180.0;
}
double _rad2deg(double radv)
{
return (180.0 * radv) / M_PI;
}
double _getMiddleAngle(double sang, double eang)
{
if (eang > sang)
{
return (sang + eang) * 0.5;
}
else
{
double m = 180.0 + (sang + eang) * 0.5;
if (m > 360.0)
{
m -= 360.0;
}
return m;
}
}
Eigen::Vector2d _getPoint(Eigen::Vector2d c,
double r,
double ang)
{
double x = r * cos(_deg2rad(ang));
double y = r * sin(_deg2rad(ang));
return c + Eigen::Vector2d(x, y);
}
double _getAngleByTwoPoints(Eigen::Vector2d c, Eigen::Vector2d pt)
{
Eigen::Vector2d v = pt - c;
double x = v(0);
double y = v(1);
double s = sqrt(x * x + y * y);
double ag = acos(x / s);
double ag1 = _rad2deg(ag);
if (y < 0.0)
{
ag1 = 360.0 - ag1;
}
return ag1;
}
double _angle(double sang, double eang)
{
if (eang > sang)
{
return eang - sang;
}
else
{
return 360.0 - sang + eang;
}
}
bool isParallel(Eigen::Vector2d a, Eigen::Vector2d b, double tolr = 1e-3)
{
double v = a(0) * b(1) - a(1) * b(0);
if (fabs(v) <= tolr)
{
return true;
}
return false;
}
bool _getCircleByThreePoints(Eigen::Vector2d v0, Eigen::Vector2d v1, Eigen::Vector2d v2,
double& r, Eigen::Vector2d& c)
{
// two line cross at circle center
//
// a s + m = b t + n
//
// |a0, -b0||s|= |n0-m0|
// |a1, -b1||t| |n1-m1|
//
// A B = X
// C D Y
// s =
// [X B,
// Y D] /
// [A B,
// C D]
// t =
// [A X,
// C Y] /
// [A B,
// C D]
Eigen::Vector2d v01 = v1 - v0;
Eigen::Vector2d a(-v01(1), v01(0));
a.normalize();
Eigen::Vector2d v12 = v2 - v1;
Eigen::Vector2d b(-v12(1), v12(0));
b.normalize();
if (isParallel(a, b))
{
return false;
}
Eigen::Vector2d m = (v0 + v1) * 0.5;
Eigen::Vector2d n = (v1 + v2) * 0.5;
double A = a(0);
double C = a(1);
double B = -b(0);
double D = -b(1);
double X = n(0) - m(0);
double Y = n(1) - m(1);
double abcd = A * D - B * C;
double sc = X * D - B * Y;
double tc = A * Y - X * C;
double s = sc / abcd;
double t = tc / abcd;
Eigen::Vector2d cs = a * s + m;
Eigen::Vector2d ct = b * t + n;
c = (cs + ct) * 0.5;
double r0 = (c - v0).norm();
double r1 = (c - v1).norm();
double r2 = (c - v1).norm();
r = (r0 + r1 + r2) / 3.0;
return true;
}
void _getGripPointsByArc(Eigen::Vector2d c,
double r,
double sang,
double eang, std::map<int, GripPoint>& gripPoints)
{
Eigen::Vector2d spt = _getPoint(_c, _r, _sang);
Eigen::Vector2d ept = _getPoint(_c, _r, _eang);
double mang = _getMiddleAngle(_sang, _eang);
Eigen::Vector2d mpt = _getPoint(_c, _r, mang);
_gripPoints[0].pt = spt;
_gripPoints[1].pt = mpt;
_gripPoints[2].pt = ept;
}
void arc2polyline(Eigen::Vector2d c,
double r,
double sang,
double eang,
std::vector<QPointF>& plpoints)
{
plpoints.clear();
double angv = _angle(sang, eang);
int segn = angv / 5.0 + 1;
double da = angv / double(segn);
plpoints.reserve(size_t(segn) + 1);
double curang = sang;
for (int i = 0; i < segn; i++)
{
Eigen::Vector2d pt = _getPoint(c, r, curang);
plpoints.push_back(QPointF(pt(0), pt(1)));
curang += da;
}
Eigen::Vector2d pt = _getPoint(c, r, eang);
plpoints.push_back(QPointF(pt(0), pt(1)));
}
Arc2d(Eigen::Vector2d c, double r, double sang, double eang) :_c(c),
_r(r),
_sang(sang),
_eang(eang)
{
//Eigen::Vector2d spt = _getPoint(_c, _r, _sang);
//Eigen::Vector2d ept = _getPoint(_c, _r, _eang);
//double mang = _getMiddleAngle(_sang, _eang);
//Eigen::Vector2d mpt = _getPoint(_c, _r, mang);
//_gripPoints[0].pt = spt;
//_gripPoints[1].pt = mpt;
//_gripPoints[2].pt = ept;
_getGripPointsByArc(_c, _r, _sang, _eang, _gripPoints);
arc2polyline(_c, _r, _sang, _eang, _polyline);
_preview_polyline = _polyline;
_preview_gripPoints = _gripPoints;
_preview_para._c = _c;
_preview_para._r = _r;
_preview_para._sang = _sang;
_preview_para._eang = _eang;
}
double degToRad(double degv)
{
return (degv * M_PI) / 180.0;
}
double radToDeg(double radv)
{
return (radv * 180.0) / M_PI;
}
Eigen::Vector2d startPoint()
{
return _c + Eigen::Vector2d(cos(degToRad(_sang)), sin(degToRad(_sang))) * _r;
}
Eigen::Vector2d endPoint()
{
return _c + Eigen::Vector2d(cos(degToRad(_eang)), sin(degToRad(_eang))) * _r;
}
double angle()
{
if (_eang > _sang)
{
return _eang - _sang;
}
else
{
return 360.0 - _sang + _eang;
}
}
virtual bool projectPoint(Eigen::Vector2d p, Eigen::Vector2d& q)
{
Eigen::Vector2d d = p - _c;
d.normalize();
Eigen::Vector2d s = startPoint();
if ((s - p).norm() < 1e-4)
{
q = s;
return true;
}
Eigen::Vector2d e = endPoint();
if ((e - p).norm() < 1e-4)
{
q = e;
return true;
}
bool on_flag = false;
double t = radToDeg(acos(d[0]));
if (d[1] < 0.0)
{
t = 360.0 - t;
if (t > 360.0)
{
t -= 360.0;
}
}
if (_eang > _sang)
{
if (t > _sang && t < _eang)
{
on_flag = true;
}
}
else
{
if ((t > _sang && t < 360.0) ||
(t >= 0.0 && t < _eang)
)
{
on_flag = true;
}
}
if (on_flag)
{
q = _c + d * _r;
return true;
}
q = { 0, 0 };
return false;
}
virtual bool movePreviewGripPoint(int id, Eigen::Vector2d newPos)
{
_preview_gripPoints[id].pt = newPos;
bool isOk =_getCircleByThreePoints(_preview_gripPoints[0].pt, _preview_gripPoints[1].pt, _preview_gripPoints[2].pt, _preview_para._r, _preview_para._c);
if (!isOk)
{
copyParaToPreiviewParameters();
return false;
}
_preview_para._sang = _getAngleByTwoPoints(_preview_para._c, _preview_gripPoints[0].pt);
_preview_para._eang = _getAngleByTwoPoints(_preview_para._c, _preview_gripPoints[2].pt);
arc2polyline(_preview_para._c, _preview_para._r, _preview_para._sang, _preview_para._eang, _preview_polyline);
_showModifyPreview = true;
return true;
}
virtual bool updateGripPoint(int id, Eigen::Vector2d newPos)
{
return false;
}
void copyParaToPreiviewParameters()
{
_preview_para._r = _r;
_preview_para._c = _c;
_preview_para._sang = _sang;
_preview_para._eang = _eang;
}
void previewConfirmParameters()
{
_r = _preview_para._r;
_c = _preview_para._c;
_sang = _preview_para._sang;
_eang = _preview_para._eang;
}
virtual void previewConfirm()
{
_getCircleByThreePoints(_preview_gripPoints[0].pt, _preview_gripPoints[1].pt, _preview_gripPoints[2].pt, _r, _c);
_sang = _getAngleByTwoPoints(_c, _preview_gripPoints[0].pt);
_eang = _getAngleByTwoPoints(_c, _preview_gripPoints[2].pt);
_getGripPointsByArc(_c, _r, _sang, _eang, _gripPoints);
previewConfirmParameters();
_preview_gripPoints = _gripPoints;
arc2polyline(_c, _r, _sang, _eang, _polyline);
_preview_polyline = _polyline;
_showModifyPreview = false;
}
virtual void paint()
{
switch (_state)
{
case CST_DEFAULT:
{
QPen pen0;
pen0.setColor(QColor(255, 255, 255));
pen0.setWidth(1);
s_painter->setPen(pen0);
//s_painter->drawArc(_c[0] - _r, _c[1] - _r, 2.0 * _r, 2.0 * _r, -_sang * 16, -angle() * 16);
s_painter->drawPolyline(_polyline.data(), _polyline.size());
}
break;
case CST_SNAPPED:
{
QPen pen0;
pen0.setColor(QColor(255, 255, 255));
pen0.setWidth(3);
s_painter->setPen(pen0);
//s_painter->drawArc(_c[0] - _r, _c[1] - _r, 2.0 * _r, 2.0 * _r, -_sang * 16, -angle() * 16);
s_painter->drawPolyline(_polyline.data(), _polyline.size());
pen0.setColor(QColor(0, 0, 0));
pen0.setWidth(1);
pen0.setStyle(Qt::DotLine);
s_painter->setPen(pen0);
//s_painter->drawArc(_c[0] - _r, _c[1] - _r, 2.0 * _r, 2.0 * _r, -_sang * 16, -angle() * 16);
s_painter->drawPolyline(_polyline.data(), _polyline.size());
}
break;
case CST_PICKED:
{
QPen pen0;
pen0.setColor(QColor(255, 255, 255));
pen0.setWidth(1);
pen0.setStyle(Qt::DashLine);
s_painter->setPen(pen0);
//s_painter->drawArc(_c[0] - _r, _c[1] - _r, 2.0 * _r, 2.0 * _r, -_sang * 16, -angle() * 16);
s_painter->drawPolyline(_polyline.data(), _polyline.size());
}
break;
default:
break;
}
Curve2d::paint();
if (_showModifyPreview)
{
QPen pen0;
pen0.setColor(QColor(255, 255, 255));
pen0.setWidth(1);
s_painter->setPen(pen0);
s_painter->drawPolyline(_preview_polyline.data(), _preview_polyline.size());
}
}
};
}// end of namespace vege
Eigen::Vector2d _mosPos(0.0, 0.0);
double _mosBoxHalfSize = 12;
double _mosBoxBaLength = 62;
double _snapSize = 1.414 * _mosBoxHalfSize;
std::vector<vege::Curve2d*> _curves;
vege::Curve2d* _snappedCurve = nullptr;
int _snappedCurveComponentId = -1;
// vege::Curve2d* _pickedCurve = nullptr;
std::set<vege::Curve2d*> _pickedCurves;
std::pair<vege::Curve2d*, int> _curPickedCurveGripPoint;
void _addPickedCurve(vege::Curve2d* c)
{
if (c == nullptr)
{
return;
}
if (_pickedCurves.find(c) == _pickedCurves.end())
{
c->setState(vege::CST_PICKED);
_pickedCurves.insert(c);
}
}
void _removePickedCurve(vege::Curve2d* c)
{
c->setState(vege::CST_DEFAULT);
_pickedCurves.erase(c);
}
bool _isPickedCurve(vege::Curve2d* c)
{
return _pickedCurves.find(c) != _pickedCurves.end();
}
void _clearPickedCurve()
{
for (auto c: _pickedCurves)
{
c->setState(vege::CST_DEFAULT);
}
_pickedCurves.clear();
}
using namespace vege;
QXViewWgt::QXViewWgt(QWidget* parent)
: QWidget(parent)
{
ui.setupUi(this);
_curves.push_back(new Line2d({ 50,50 }, { 450,50 }));
_curves.push_back(new Line2d({ 50,50 }, { 50,350 }));
_curves.push_back(new Line2d({ 450,50 }, { 450,350 }));
_curves.push_back(new Arc2d({ 250,350 }, 200, 0, 180));
}
QXViewWgt::~QXViewWgt()
{
for (auto& curv : _curves)
{
delete curv;
}
}
void QXViewWgt::mouseReleaseEvent(QMouseEvent* event)
{
if (_curPickedCurveGripPoint.first)
{
_curPickedCurveGripPoint.first->previewConfirm();
_snappedCurve = nullptr;
_snappedCurveComponentId = -1;
_removePickedCurve(_curPickedCurveGripPoint.first);
_curPickedCurveGripPoint.first = nullptr;
_curPickedCurveGripPoint.second = -1;
update();
return;
}
if (_snappedCurve)
{
//if (_pickedCurve != _snappedCurve)
//{
// if (_pickedCurve)
// {
// _pickedCurve->setState(CST_DEFAULT);
// _pickedCurve = nullptr;
// }
// _pickedCurve = _snappedCurve;
// _pickedCurve->setState(CST_PICKED);
//}
_addPickedCurve(_snappedCurve);
if (_snappedCurveComponentId != -1)
{
_curPickedCurveGripPoint.first = _snappedCurve;
_curPickedCurveGripPoint.second = _snappedCurveComponentId;
}
}
else
{
//if (_pickedCurve)
//{
// _pickedCurve->setState(CST_DEFAULT);
// _pickedCurve = nullptr;
//}
_clearPickedCurve();
}
update();
}
void QXViewWgt::mousePressEvent(QMouseEvent* event)
{
QWidget::mousePressEvent(event);
}
void QXViewWgt::mouseMoveEvent(QMouseEvent* event)
{
_mosPos(0) = event->pos().x();
_mosPos(1) = (height()-1) - event->pos().y();
// here we just try each curve, not use aabb
Curve2d* curSnapped = nullptr;
int curSnappedComId = -1;
std::map<Curve2d*, std::pair<int, Eigen::Vector2d> > _curSnappedCurveGripPts;
std::map<Curve2d*, std::pair<int, Eigen::Vector2d> > _curSnappedCurves;
for (auto& curve : _curves)
{
QPen pen0;
Eigen::Vector2d pt_q;
int comId = -1;
Eigen::Vector2d gripPtPos;
comId = curve->snapGripPoints(_mosPos, _snapSize, gripPtPos);
//if (comId != -1)
//{
// curSnapped = curve;
// _mosPos = gripPtPos;
//}
//if (_isPickedCurve(curve))
{
if (comId >= 0)
{
curSnapped = curve;
curSnappedComId = comId;
_mosPos = gripPtPos;
if (curve->isGripPointShow())
{
_curSnappedCurveGripPts[curSnapped] = std::make_pair(curSnappedComId, _mosPos);
}
else
{
_curSnappedCurves[curSnapped] = std::make_pair(curSnappedComId, _mosPos);
}
//break;
continue;
}
}
bool issucess = curve->projectPoint(_mosPos, pt_q);
if (issucess)
{
double dist = (pt_q - _mosPos).norm();
if (dist < _snapSize)
{
_mosPos = pt_q;
curSnapped = curve;
_curSnappedCurves[curSnapped] = std::make_pair(-1, _mosPos);
//break;
continue;
}
}
}
if (!_curSnappedCurveGripPts.empty())
{
curSnapped = _curSnappedCurveGripPts.begin()->first;
curSnappedComId = _curSnappedCurveGripPts.begin()->second.first;
_mosPos = _curSnappedCurveGripPts.begin()->second.second;
}
else if (!_curSnappedCurves.empty())
{
curSnapped = _curSnappedCurves.begin()->first;
curSnappedComId = _curSnappedCurves.begin()->second.first;
_mosPos = _curSnappedCurves.begin()->second.second;
}
else
{
curSnapped = nullptr;
curSnappedComId = -1;
}
if (curSnapped == _curPickedCurveGripPoint.first)
{
curSnapped = nullptr;
}
// mov grip point and curve modify preview
if (_curPickedCurveGripPoint.first)
{
_curPickedCurveGripPoint.first->movePreviewGripPoint(_curPickedCurveGripPoint.second, _mosPos);
this->update();
return;
}
if (curSnapped)
{
//if (/*_pickedCurve && _pickedCurve == curSnapped */_isPickedCurve(curSnapped))
//{
// _snappedCurve = curSnapped;
//}
//else
{
if (_snappedCurve)
{
if (_snappedCurve->stateIs(CST_SNAPPED))
{
_snappedCurve->setState(CST_DEFAULT);
}
}
_snappedCurve = curSnapped;
_snappedCurveComponentId = curSnappedComId;
if (_snappedCurve->stateIs(CST_DEFAULT))
{
_snappedCurve->setState(CST_SNAPPED);
}
}
}
else
{
if (_snappedCurve)
{
if (_snappedCurve->stateIs(CST_SNAPPED))
{
_snappedCurve->setState(CST_DEFAULT);
}
_snappedCurve = nullptr;
curSnappedComId = -1;
}
}
this->update();
}
void QXViewWgt::paintEvent(QPaintEvent* event)
{
QPainter painter(this);
painter.translate(0, height());
painter.scale(1, -1);
vege::s_painter = &painter;
painter.fillRect(0, 0, this->width(), this->height(),QColor(33,40,48));
// draw curves
for (auto& curve : _curves)
{
curve->paint();
}
// draw snap box
QPen pen;
pen.setColor(QColor(255, 255, 255));
pen.setWidth(1);
painter.setPen(pen);
painter.drawLine(_mosPos(0) - _mosBoxBaLength, _mosPos(1), _mosPos(0) - _mosBoxHalfSize, _mosPos(1));
painter.drawLine(_mosPos(0) + _mosBoxBaLength, _mosPos(1), _mosPos(0) + _mosBoxHalfSize, _mosPos(1));
painter.drawLine(_mosPos(0), _mosPos(1) - _mosBoxBaLength, _mosPos(0), _mosPos(1) - _mosBoxHalfSize);
painter.drawLine(_mosPos(0), _mosPos(1) + _mosBoxBaLength, _mosPos(0), _mosPos(1) + _mosBoxHalfSize);
painter.drawRect(_mosPos(0) - _mosBoxHalfSize, _mosPos(1) - _mosBoxHalfSize, _mosBoxHalfSize * 2, _mosBoxHalfSize * 2);
painter.end();
}