#include "ROIRect2.h" #include"HHomMat2D.h" #include "MyStream.h" ROIRect2::ROIRect2() { numHandles = 6; // 4 corners + 1 midpoint + 1 rotationpoint activeHandleIdx = 4; roiType = ROIType::Rectangle2; length1 = 0; length2 = 0; midR = 0; midC = 0; phi = 0; } void ROIRect2::createROI(double midX, double midY) { midR = midY; midC = midX; length1 = 100; length2 = 50; phi = 0.0; rowsInit.Clear(); rowsInit[0] = -1.0; rowsInit[1] = -1.0; rowsInit[2] = 1.0; rowsInit[3] = 1.0; rowsInit[4] = 0.0; rowsInit[5] = 0.0; colsInit.Clear(); colsInit[0] = -1.0; colsInit[1] = 1.0; colsInit[2] = 1.0; colsInit[3] = -1.0; colsInit[4] = 0.0; colsInit[5] = 0.6; hom2D = HHomMat2D(); tmp = HHomMat2D(); updateHandlePos(); } void ROIRect2::drawROI(HTuple winID, double scaleFactor) { Q_UNUSED(scaleFactor); //DispRectangle2(winID, midR, midC, -phi, length1, length2); HObject ho_Rectangle; GenRectangle2ContourXld(&ho_Rectangle, midR, midC, -phi, length1, length2); DispObj(ho_Rectangle, winID); double width=handleWidth; for (int i = 0; i < numHandles; i++) { //DispRectangle2(winID, rows[i], cols[i], -phi, width, width); GenRectangle2ContourXld(&ho_Rectangle, rows[i], cols[i], -phi, width, width); DispObj(ho_Rectangle, winID); } DispArrow(winID, midR, midC, midR + (sin(phi) * length1 * 1.2), midC + (cos(phi) * length1 * 1.2), width/2); } double ROIRect2::distToClosestHandle(double x, double y) { double max = 10000; double val[6] = {0}; for (int i = 0; i < numHandles; i++) { val[i] = HMisc::DistancePp(y, x, rows[i], cols[i]); } for (int i = 0; i < numHandles; i++) { if (val[i] < max) { max = val[i]; activeHandleIdx = i; } } return val[activeHandleIdx]; } void ROIRect2::displayActive(HTuple winID, double scaleFactor) { Q_UNUSED(scaleFactor); double width=handleWidth; //DispRectangle2(winID, rows[activeHandleIdx], // cols[activeHandleIdx], // -phi, width, width); HObject ho_Rectangle; GenRectangle2ContourXld(&ho_Rectangle, rows[activeHandleIdx], cols[activeHandleIdx], -phi, width, width); DispObj(ho_Rectangle, winID); if (activeHandleIdx == 5) DispArrow(winID, midR, midC, midR + (sin(phi) * length1 * 1.2), midC + (cos(phi) * length1 * 1.2), width/2); } void ROIRect2::moveByHandle(double newX, double newY) { double vX, vY; HTuple l2,l1; switch (activeHandleIdx) { case 0: DistancePl(newY,newX,rows[1],cols[1],rows[2],cols[2],&l1); DistancePl(newY,newX,rows[3],cols[3],rows[2],cols[2],&l2); length1= abs(l1.D())/2.0; length2=abs(l2.D())/2.0; midR=(newY+rows[2].D())/2.0; midC=(newX+cols[2].D())/2.0; break; case 1: DistancePl(newY,newX,rows[2],cols[2],rows[3],cols[3],&l1); DistancePl(newY,newX,rows[3],cols[3],rows[0],cols[0],&l2); length2= abs(l1.D())/2.0; length1=abs(l2.D())/2.0; midR=(newY+rows[3].D())/2.0; midC=(newX+cols[3].D())/2.0; break; case 2: DistancePl(newY,newX,rows[0],cols[0],rows[1],cols[1],&l1); DistancePl(newY,newX,rows[3],cols[3],rows[0],cols[0],&l2); length2= abs(l1.D())/2.0; length1=abs(l2.D())/2.0; midR=(newY+rows[0].D())/2.0; midC=(newX+cols[0].D())/2.0; break; case 3: DistancePl(newY,newX,rows[0],cols[0],rows[1],cols[1],&l1); DistancePl(newY,newX,rows[1],cols[1],rows[2],cols[2],&l2); length2= abs(l1.D())/2.0; length1=abs(l2.D())/2.0; midR=(newY+rows[1].D())/2.0; midC=(newX+cols[1].D())/2.0; break; // tmp = hom2D.HomMat2dInvert(); // x = tmp.AffineTransPoint2d(newX, newY, &y); // length2 = abs(y); // length1 = abs(x); // checkForRange(x, y); // break; case 4: midC = newX; midR = newY; break; case 5: vY = newY - rows[4].D(); vX = newX - cols[4].D(); phi = atan2(vY, vX); break; } updateHandlePos(); } QCursor ROIRect2::showByHandle() { QCursor cursor; switch (activeHandleIdx) { case 0: // 鼠标在圆上的一点时 cursor= Qt::SizeAllCursor; break; case 1: // 鼠标在圆心上时 cursor= Qt::SizeBDiagCursor; break; } return cursor; } HRegion ROIRect2::getRegion() { HRegion region; region.GenRectangle2(midR, midC, -phi, length1, length2); return region; } HTuple ROIRect2::getROIData() { HTuple dat; dat.Clear(); dat[0] = midR; dat[1] = midC; dat[2] = -phi; dat[3] = length1; dat[4] = length2; return dat; } void ROIRect2::setROIData(HTuple dat) { Q_UNUSED(dat); } void ROIRect2::save(QDataStream &dataStream) { ROI::save(dataStream); int paranum;//参数数量 paranum = 10; dataStream << paranum;//先保存参数数量 dataStream << (int)1 << length1; dataStream << (int)2 << length2; dataStream << (int)3 << midR; dataStream << (int)4 << midC; dataStream << (int)5 << phi; dataStream << (int)6 << rowsInit; dataStream << (int)7 << colsInit; dataStream << (int)8 << rows; dataStream << (int)9 << cols; dataStream << (int)10 << m_strTitle; } void ROIRect2::load(QDataStream &dataStream) { ROI::load(dataStream); int paranum;//参数数量 int para; dataStream >> paranum;//读取参数数量 for (int i = 0; i < paranum; i++) { dataStream >> para; switch (para) { case 1: dataStream >> length1; break; case 2: dataStream >> length2; break; case 3: dataStream >> midR; break; case 4: dataStream >> midC; break; case 5: dataStream >> phi; break; case 6: dataStream >> rowsInit; break; case 7: dataStream >> colsInit; break; case 8: dataStream >> rows; break; case 9: dataStream >> cols; break; case 10: dataStream >> m_strTitle; break; default: { qWarning() << "配置文档错误!"; } break; } } } void ROIRect2::updateHandlePos() { hom2D.HomMat2dIdentity(); hom2D = hom2D.HomMat2dTranslate(midC, midR); hom2D = hom2D.HomMat2dRotateLocal(phi); tmp = hom2D.HomMat2dScaleLocal(length1, length2); cols = tmp.AffineTransPoint2d(colsInit, rowsInit, &rows); } void ROIRect2::checkForRange(double x, double y) { switch (activeHandleIdx) { case 0: if ((x < 0) && (y < 0)) return; if (x >= 0) length1 = 0.01; if (y >= 0) length2 = 0.01; break; case 1: if ((x > 0) && (y < 0)) return; if (x <= 0) length1 = 0.01; if (y >= 0) length2 = 0.01; break; case 2: if ((x > 0) && (y > 0)) return; if (x <= 0) length1 = 0.01; if (y <= 0) length2 = 0.01; break; case 3: if ((x < 0) && (y > 0)) return; if (x >= 0) length1 = 0.01; if (y <= 0) length2 = 0.01; break; default: break; } }