#include #include "ZxSerializer.h" #include "IxPtyPano.h" #include "ZxSubAxisX.h" #include "ZxSubAxisY.h" #include "nmObjRoundTool.h" #include "nmObjRound.h" #include "nmDataAnalyzeManager.h" ZX_DEFINE_DYNAMIC(nObjRound, nmObjRound) nmObjRound::nmObjRound() { m_sObjTag = "nObjRound"; nmObjRound::init("", NULL, NULL); } nmObjRound::nmObjRound(const QString& sName, \ ZxSubAxisX* pAxisX, \ ZxSubAxisY* pAxisY) { m_sObjTag = "nObjRound"; nmObjRound::init(sName, pAxisX, pAxisY); } nmObjRound::~nmObjRound() { } // 初始化矩形对象对应的笔和填充颜色 void nmObjRound::init(const QString& sName, \ ZxSubAxisX* pAxisX, \ ZxSubAxisY* pAxisY) { nmObjBase::init(sName, pAxisX, pAxisY); nmObjRound::initFlags(); m_oPen = QPen(QBrush(QColor(0, 0, 0)), \ 0.5f, Qt::SolidLine); m_clrBackgrd = QColor(255, 170, 255, 100); loadTempl(); } // 初始化绘制圆形的工具 void nmObjRound::initTools() { m_pTool = new nmObjRoundTool(); nmObjBase::initTools(); } void nmObjRound::initFlags() { setLockPos(false); setLockSize(false); setReadOnly(false); } QColor nmObjRound::getBackgrdColor() const { //if (m_nLineIndex) //return m_vecPresType[m_nLineIndex] return m_clrBackgrd; } void nmObjRound::setBackgrdColor(QColor color) { if (m_clrBackgrd != color) { //m_vecPresType[m_nLineIndex] = m_clrBackgrd = color; update(); } } bool nmObjRound::hitTest(const QPointF& pt) { return nmObjBase::hitTest(pt); } bool nmObjRound::_runHitTest(const QPointF& pt, int& nOption, int& nSubIndex) { if (!nmObjBase::_runHitTest(pt, nOption, nSubIndex)) { return false; } nOption = -1; nSubIndex = 0; if (NULL == m_pAxisX || NULL == m_pAxisY) { return false; } QVector pts = getPosOf(m_vecPoints); // 判断半径是否相同,不相同先修改半径相同 if (pts[1].x() != pts[1].y()) { double radius = qAbs(pts[0].y() - pts[2].y()); pts[1] = QPointF(radius, radius); // 重新计算圆上的四个点 QPointF center = pts[0]; // 圆心 // 上点 (x, y - radius) pts[2] = QPointF(center.x(), center.y() - radius); // 右点 (x + radius, y) pts[3] = QPointF(center.x() + radius, center.y()); // 下点 (x, y + radius) pts[4] = QPointF(center.x(), center.y() + radius); // 左点 (x - radius, y) pts[5] = QPointF(center.x() - radius, center.y()); } // 点 double r = 1.f; QPointF p1;//p1:击中的点;p2:圆心 bool isInitialized = false; for (int i = 2; i < pts.count(); i++) { //下标从2开始 QPointF ptTopLeft = QPointF(pts[i].x() - r, pts[i].y() - r); QSizeF sz = QSizeF(r * 2.f, r * 2.f); QRectF rt = QRectF(ptTopLeft, sz); bool b = rt.contains(pt); if (b) { // 击中了这个点,记录该点的位置 p1 = pts[i]; nSubIndex = i; isInitialized = true; break; } } QPointF p2 = pts[0]; //判断该点所在的位置,与圆心作比较 if (isInitialized) { if(p1.x() == p2.x() && p1.y() < p2.y()) { //上 nOption = (int)OHO_Point; } else if (p1.x() > p2.x() && p1.y() == p2.y()) { //右 nOption = (int)OHO_Point; } else if (p1.x() == p2.x () && p1.y() > p2.y()) { //下 nOption = (int)OHO_Point; } else if(p1.x() < p2.x() && p1.y() == p2.y()) { nOption = (int)OHO_Point;//左 } return true; } // 判断线所在的位置 qreal distance = QLineF(pts[0], pt).length(); qreal radius = pts[1].x(); // 允许误差范围 qreal epsilon = 2.0; // 判断鼠标是否位于圆的边界(即圆的线)上 if (fabs(distance - radius) <= epsilon) { nOption = (int)OHO_Bound; return true; } // 内部 QPainterPath oPath; // 添加圆形路径 oPath.addEllipse(pts[0], pts[1].x(), pts[1].y()); if (oPath.contains(pt) && isSelected()) { nOption = (int)OHO_Inner; nSubIndex = 0; return true; } else { nOption = (int)OHO_None; } return false; } bool nmObjRound::runMove(const QPointF& pt1, const QPointF& pt2) { if (isLockPos()) { return false; } if (NULL == m_pAxisX || NULL == m_pAxisY) { return false; } int nCount = m_vecPoints.count(); QVector vecPts = getPosOf(m_vecPoints); //屏幕值 // 判断半径是否相同,不相同先修改半径相同 if (vecPts[1].x() != vecPts[1].y()) { double radius = qAbs(vecPts[0].y() - vecPts[2].y()); vecPts[1] = QPointF(radius, radius); // 重新计算圆上的四个点 QPointF center = vecPts[0]; // 圆心 // 上点 (x, y - radius) vecPts[2] = QPointF(center.x(), center.y() - radius); // 右点 (x + radius, y) vecPts[3] = QPointF(center.x() + radius, center.y()); // 下点 (x, y + radius) vecPts[4] = QPointF(center.x(), center.y() + radius); // 左点 (x - radius, y) vecPts[5] = QPointF(center.x() - radius, center.y()); } if (m_oHitOption == OHO_Point) { //击中上下边 // x不变 QPointF p1 = pt2; p1.setX(pt1.x()); //计算偏移量 qreal offset = pt1.y() - pt2.y(); // 判断是上边还是下边 if (m_nHitIndex == 2) { // 上边 // 更新半径 vecPts[1].setX(vecPts[1].x() + offset); vecPts[1].setY(vecPts[1].y() + offset); // 更新四个点 vecPts[2].setY(vecPts[2].y() - offset); vecPts[4].setY(vecPts[4].y() + offset); vecPts[5].setX(vecPts[5].x() - offset); //左 vecPts[3].setX(vecPts[3].x() + offset); //右 } else if (m_nHitIndex == 4) { // 下边 offset = pt2.y() - pt1.y(); // 更新半径 vecPts[1].setX(vecPts[1].x() + offset); vecPts[1].setY(vecPts[1].y() + offset); // 下边 vecPts[4].setY(vecPts[4].y() + offset); vecPts[2].setY(vecPts[2].y() - offset); vecPts[3].setX(vecPts[3].x() + offset); vecPts[5].setX(vecPts[5].x() - offset); }else if (m_nHitIndex == 3) { // 右边 offset = pt2.x() - pt1.x(); // 更新半径 vecPts[1].setX(vecPts[1].x() + offset); vecPts[1].setY(vecPts[1].y() + offset); // 右边 vecPts[3].setX(vecPts[3].x() + offset); vecPts[5].setX(vecPts[5].x() - offset); vecPts[2].setY(vecPts[2].y() - offset); // 上 vecPts[4].setY(vecPts[4].y() + offset); // 下 } else if (m_nHitIndex == 5) { // 左边 offset = pt1.x() - pt2.x(); // 更新半径 vecPts[1].setX(vecPts[1].x() + offset); vecPts[1].setY(vecPts[1].y() + offset); // 左边 vecPts[5].setX(vecPts[5].x() - offset); vecPts[3].setX(vecPts[3].x() + offset); vecPts[2].setY(vecPts[2].y() - offset); // 上 vecPts[4].setY(vecPts[4].y() + offset); // 下 } nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged(); return moveToPos(vecPts); } else if (m_oHitOption == OHO_Bound) { //左右两边 // y不变 QPointF p1 = pt2; p1.setY(pt1.y()); //计算偏移量 qreal offset = pt2.x() - pt1.x(); // 判断是上边还是下边 if (m_nHitIndex == 3) { // 右边 // 更新半径 vecPts[1].setX(vecPts[1].x() + offset); vecPts[1].setY(vecPts[1].y() + offset); // 更新四个点 vecPts[3].setX(vecPts[3].x() + offset); //右 vecPts[5].setX(vecPts[5].x() - offset); //左 vecPts[2].setY(vecPts[2].y() - offset); // 上 vecPts[4].setY(vecPts[4].y() + offset); //下 } else if (m_nHitIndex == 5) { // 左边 offset = pt1.x() - pt2.x(); // 更新半径 vecPts[1].setX(vecPts[1].x() + offset); vecPts[1].setY(vecPts[1].y() + offset); // 更新四个点 vecPts[3].setX(vecPts[3].x() + offset); //右 vecPts[5].setX(vecPts[5].x() - offset); //左 vecPts[2].setY(vecPts[2].y() - offset); // 上 vecPts[4].setY(vecPts[4].y() + offset); //下 } nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged(); return moveToPos(vecPts); } if (m_oHitOption == OHO_Inner) { // 更新圆点 vecPts[0] = offsetPoint(vecPts[0], pt1, pt2); m_dOffsetX = pt2.x() - pt1.x(); m_dOffsetY = pt2.y() - pt1.y(); // 更新上下左右四个点 for (int i = 2; i < vecPts.count(); i++) { vecPts[i] = offsetPoint(vecPts[i], pt1, pt2); } nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged(); return moveToPos(vecPts); } else { return false; } return true; } void nmObjRound::fillPtyPano(IxPtyPano* sheet) { nmObjBase::fillPtyPano(sheet); ZX_PROP("ObjPolygon.Pen", getPen, setPen); ZX_PROP("ObjPolygon.BackgrdColor", getBackgrdColor, setBackgrdColor); } void nmObjRound::paintBack(QPainter* painter, const ZxPaintParam& param) { // 判断当前坐标轴是否有效 if (NULL == m_pAxisX || NULL == m_pAxisY || \ m_pAxisX->getRangeMin() == m_pAxisX->getRangeMax() || \ m_pAxisY->getRangeMin() == m_pAxisY->getRangeMax()) { return; } painter->save(); //QVector pts = getPosOf(m_vecPoints); //获取当前对象的原点的坐标 //QRectF bound = getBounds(); //获取图元基础边框(位置) // 判断半径是否相同,不相同先修改半径相同 if (m_vecPoints[1].x() != m_vecPoints[1].y()) { // 重新计算半径 // 计算半径(绝对值) double radius = qAbs(m_vecPoints[0].y() - m_vecPoints[2].y()); // 更新 vecConvertPoints[1] 为 (radius, radius) m_vecPoints[1] = QPointF(radius, radius); } QVector pts = getPosOf(m_vecPoints); // 判断半径是否相同,不相同先修改半径相同,重新计算上下左右四个点的坐标 if (pts[1].x() != pts[1].y()) { double radius = qAbs(pts[0].y() - pts[2].y()); pts[1] = QPointF(radius, radius); // 重新计算圆上的四个点 QPointF center = pts[0]; // 圆心 // 上点 (x, y - radius) pts[2] = QPointF(center.x(), center.y() - radius); // 右点 (x + radius, y) pts[3] = QPointF(center.x() + radius, center.y()); // 下点 (x, y + radius) pts[4] = QPointF(center.x(), center.y() + radius); // 左点 (x - radius, y) pts[5] = QPointF(center.x() - radius, center.y()); } if (!pts.empty()) { //圆存在 // 填充 QPainterPath oPath; // 添加圆形路径 oPath.addEllipse(pts[0], pts[1].x(), pts[1].y()); // m_clrBackgrd.setAlpha(100); painter->fillPath(oPath, QBrush(m_clrBackgrd)); // 边界 QPen pen = m_oPen; painter->setPen(pen); painter->drawEllipse(pts[0], pts[1].x(), pts[1].y()); // 获取圆心和半径 QPointF center = pts[0]; qreal radius = pts[1].x(); // 计算边界框的左上角和右下角坐标 QPointF topLeft = center - QPointF(radius, radius); QPointF bottomRight = center + QPointF(radius, radius); // 创建QRectF对象 QRectF bound(topLeft, bottomRight); // 绘制名称文字 painter->setFont(QFont("Arial", 8, QFont::Normal)); painter->setPen(Qt::black); ZxDrawHelper::drawText(painter, bound, Qt::AlignCenter | Qt::AlignVCenter, m_sName); } //选中状态下的圆形形状 if (isSelected()) { QPen pen(QBrush(Qt::black), 0.0f, Qt::DotLine); painter->setPen(pen); painter->drawEllipse(pts[0], pts[1].x(), pts[1].y()); for (int i = 2; i < pts.count(); i++) { double w = 2.2f; QPointF pt = pts[i]; QRectF rect(pt.x() - w * 0.5f, pt.y() - w * 0.5f, w, w); //每个点周围画小矩形边框 // 击中四个点 if (m_nHitIndex == i && (m_oHitOption == OHO_Point || m_oHitOption == OHO_Bound)) { QBrush br(Qt::red); painter->fillRect(rect, br); } else { painter->setPen(QColor(0, 0, 128)); painter->drawRect(rect); } } } painter->restore(); }