123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396 |
- #include "ROICircularArc.h"
- ROICircularArc::ROICircularArc()
- {
- numHandles = 4; // midpoint handle + three handles on the arc
- activeHandleIdx = 0;
- circDir = "";
- TwoPI = 2 * PI;
- roiType = ROIType::CircleArc;
- }
- void ROICircularArc::createROI(double midX, double midY)
- {
- midR = midY;
- midC = midX;
- radius = 100;
- sizeR = midR;
- sizeC = midC - radius;
- startPhi = PI * 0.25;
- extentPhi = PI * 1.5;
- circDir = "positive";
- determineArcHandles();
- updateArrowHandle();
- updateStartRect2XLDHandle(handleWidth);
- }
- void ROICircularArc::drawROI(HTuple winID, double scaleFactor)
- {
- Q_UNUSED(scaleFactor);
- contour.GenCircleContourXld(HTuple(midR), HTuple(midC), HTuple(radius), HTuple(startPhi),
- HTuple((startPhi + extentPhi)), HTuple(circDir.toUtf8().data()), HTuple(1.0));
- DispObj(contour, winID);
- int width = handleWidth;
- //DispRectangle2(winID, sizeR, sizeC, 0, width, width);
- //DispRectangle2(winID, midR, midC, 0, width, width);
- HObject ho_Rectangle;
- GenRectangle2ContourXld(&ho_Rectangle, sizeR, sizeC, 0, width, width);
- DispObj(ho_Rectangle, winID);
- GenRectangle2ContourXld(&ho_Rectangle, midR, midC, 0, width, width);
- DispObj(ho_Rectangle, winID);
- //if (startRect2XLD.IsInitialized()==false)
- {
- updateStartRect2XLDHandle(handleWidth);
- }
- DispObj(startRect2XLD, winID);
- //if (arrowHandleXLD.IsInitialized()==false)
- {
- updateArrowHandle();
- }
- DispObj(arrowHandleXLD, winID);
- DispLine(winID, midR, midC, startR, startC);
- DispLine(winID, midR, midC, extentR, extentC);
- }
- double ROICircularArc::distToClosestHandle(double x, double y)
- {
- double max = 10000;
- double val[4];
- val[0] = HMisc::DistancePp(y, x, midR, midC); // midpoint
- val[1] = HMisc::DistancePp(y, x, sizeR, sizeC); // border handle
- val[2] = HMisc::DistancePp(y, x, startR, startC); // border handle
- val[3] = HMisc::DistancePp(y, x, extentR, extentC); // border handle
- for (int i = 0; i < numHandles; i++)
- {
- if (val[i] < max)
- {
- max = val[i];
- activeHandleIdx = i;
- }
- }// end of for
- return val[activeHandleIdx];
- }
- void ROICircularArc::displayActive(HTuple winID, double scaleFactor)
- {
- Q_UNUSED(scaleFactor);
- HObject ho_Rectangle;
- double width = handleWidth;
- switch (activeHandleIdx)
- {
- case 0:
- //DispRectangle2(winID, midR, midC, 0, width, width);
- GenRectangle2ContourXld(&ho_Rectangle, midR, midC, 0, width, width);
- DispObj(ho_Rectangle, winID);
- break;
- case 1:
- //DispRectangle2(winID, sizeR, sizeC, 0, width, width);
- GenRectangle2ContourXld(&ho_Rectangle, sizeR, sizeC, 0, width, width);
- DispObj(ho_Rectangle, winID);
- break;
- case 2:
- //window.DispRectangle2(startR, startC, startPhi, 10, 2);
- DispObj(startRect2XLD, winID);
- break;
- case 3:
- DispObj(arrowHandleXLD, winID);
- break;
- }
- }
- void ROICircularArc::moveByHandle(double newX, double newY)
- {
- double distance;
- double dirX, dirY, prior, next, valMax, valMin;
- switch (activeHandleIdx)
- {
- case 0: // midpoint
- dirY = midR - newY;
- dirX = midC - newX;
- midR = newY;
- midC = newX;
- sizeR -= dirY;
- sizeC -= dirX;
- determineArcHandles();
- break;
- case 1: // handle at circle border
- sizeR = newY;
- sizeC = newX;
- distance = HMisc::DistancePp(sizeR, sizeC,
- midR, midC);
- radius = distance;
- determineArcHandles();
- break;
- case 2: // start handle for arc
- dirY = newY - midR;
- dirX = newX - midC;
- startPhi = atan2(-dirY, dirX);
- if (startPhi < 0)
- startPhi = PI + (startPhi + PI);
- setStartHandle();
- prior = extentPhi;
- extentPhi = HMisc::AngleLl(midR, midC, startR, startC, midR, midC, extentR, extentC);
- if (extentPhi < 0 && prior > PI * 0.8)
- extentPhi = (PI + extentPhi) + PI;
- else if (extentPhi > 0 && prior < -PI * 0.7)
- extentPhi = -PI - (PI - extentPhi);
- break;
- case 3: // end handle for arc
- dirY = newY - midR;
- dirX = newX - midC;
- prior = extentPhi;
- next = atan2(-dirY, dirX);
- if (next < 0)
- next = PI + (next + PI);
- if (circDir == "positive" && startPhi >= next)
- extentPhi = (next + TwoPI) - startPhi;
- else if (circDir == "positive" && next > startPhi)
- extentPhi = next - startPhi;
- else if (circDir == "negative" && startPhi >= next)
- extentPhi = -1.0 * (startPhi - next);
- else if (circDir == "negative" && next > startPhi)
- extentPhi = -1.0 * (startPhi + TwoPI - next);
- valMax = std::max<double>(std::abs(prior), std::abs(extentPhi));
- valMin = std::max<double>(std::abs(prior), std::abs(extentPhi));
- if ((valMax - valMin) >= PI)
- {
- extentPhi = (circDir == "positive") ? -1.0 * valMin : valMin;
- }
- setExtentHandle();
- break;
- }
- circDir = (extentPhi < 0) ? "negative" : "positive";
- updateArrowHandle();
- updateStartRect2XLDHandle(handleWidth);
- }
- QCursor ROICircularArc::showByHandle()
- {
- QCursor cursor;
- switch (activeHandleIdx)
- {
- case 0: // 鼠标在圆上的一点时
- cursor = Qt::SizeAllCursor;
- break;
- case 1: // 鼠标在圆心上时
- cursor = Qt::SizeBDiagCursor;
- break;
- }
- return cursor;
- }
- HRegion ROICircularArc::getRegion()
- {
- HRegion region;
- contour.GenCircleContourXld(HTuple(midR), HTuple(midC),
- HTuple(radius), HTuple(startPhi), HTuple((startPhi + extentPhi)), HTuple(circDir.toUtf8().data()), HTuple(1.0));
- region = HRegion(contour);
- return region;
- }
- HTuple ROICircularArc::getROIData()
- {
- HTuple dat;
- dat.Clear();
- dat[0] = midR;
- dat[1] = midC;
- dat[2] = radius;
- dat[3] = startPhi;
- dat[4] = extentPhi;
- return dat;
- }
- void ROICircularArc::setROIData(HTuple dat)
- {
- Q_UNUSED(dat);
- }
- void ROICircularArc::save(QDataStream &dataStream)
- {
- ROI::save(dataStream);
- int paranum;//参数数量
- paranum = 14;
- dataStream << paranum;//先保存参数数量
- dataStream << (int)1 << midR;
- dataStream << (int)2 << midC;
- dataStream << (int)3 << sizeR;
- dataStream << (int)4 << sizeC;
- dataStream << (int)5 << startR;
- dataStream << (int)6 << startC;
- dataStream << (int)7 << extentR;
- dataStream << (int)8 << extentC;
- dataStream << (int)9 << radius;
- dataStream << (int)10 << startPhi;
- dataStream << (int)11 << extentPhi;
- dataStream << (int)12 << TwoPI;
- dataStream << (int)13 << circDir;
- dataStream << (int)14 << m_strTitle;
- }
- void ROICircularArc::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 >> midR; break;
- case 2: dataStream >> midC; break;
- case 3: dataStream >> sizeR; break;
- case 4: dataStream >> sizeC; break;
- case 5: dataStream >> startR; break;
- case 6: dataStream >> startC; break;
- case 7: dataStream >> extentR; break;
- case 8: dataStream >> extentC; break;
- case 9: dataStream >> radius; break;
- case 10: dataStream >> startPhi; break;
- case 11: dataStream >> extentPhi; break;
- case 12: dataStream >> TwoPI; break;
- case 13: dataStream >> circDir; break;
- case 14: dataStream >> m_strTitle; break;
- default:
- {
- qWarning() << "配置文档错误!";
- }
- break;
- }
- }
- }
- void ROICircularArc::determineArcHandles()
- {
- setStartHandle();
- setExtentHandle();
- }
- void ROICircularArc::updateArrowHandle()
- {
- double row1, col1, row2, col2;
- double rowP1, colP1, rowP2, colP2;
- double length, dr, dc, halfHW, sign, angleRad;
- double headLength = handleWidth;
- double headWidth = handleWidth;
- row2 = extentR;
- col2 = extentC;
- angleRad = (startPhi + extentPhi) + PI * 0.5;
- sign = (circDir == "negative") ? -1.0 : 1.0;
- row1 = row2 + sign * sin(angleRad) * 20;
- col1 = col2 - sign * cos(angleRad) * 20;
- length = HMisc::DistancePp(row1, col1, row2, col2);
- if (length == 0)
- length = -1;
- dr = (row2 - row1) / length;
- dc = (col2 - col1) / length;
- halfHW = headWidth / 2.0;
- rowP1 = row1 + (length - headLength) * dr + halfHW * dc;
- rowP2 = row1 + (length - headLength) * dr - halfHW * dc;
- colP1 = col1 + (length - headLength) * dc - halfHW * dr;
- colP2 = col1 + (length - headLength) * dc + halfHW * dr;
- arrowHandleXLD.GenEmptyObj();
- if (length == -1)
- arrowHandleXLD.GenContourPolygonXld(row1, col1);
- else
- {
- double rTmpDouble[5] = { 1, 2, 3 };
- HTuple test(rTmpDouble, 5);
- HTuple rTmp;
- rTmp.Clear();
- rTmp[0] = row1;
- rTmp[1] = row2;
- rTmp[2] = rowP1;
- rTmp[3] = row2;
- rTmp[4] = rowP2;
- rTmp[5] = row2;
- HTuple cTmp;
- cTmp.Clear();
- cTmp[0] = col1;
- cTmp[1] = col2;
- cTmp[2] = colP1;
- cTmp[3] = col2;
- cTmp[4] = colP2;
- cTmp[5] = col2;
- arrowHandleXLD.GenContourPolygonXld(rTmp, cTmp);
- }
- }
- void ROICircularArc::updateStartRect2XLDHandle(int imageWidth)
- {
- startRect2XLD.GenEmptyObj();
- startRect2XLD.GenRectangle2ContourXld(startR, startC, startPhi, imageWidth, imageWidth / 5.0);
- }
- void ROICircularArc::setStartHandle()
- {
- startR = midR - radius * sin(startPhi);
- startC = midC + radius * cos(startPhi);
- }
- void ROICircularArc::setExtentHandle()
- {
- extentR = midR - radius * sin(startPhi + extentPhi);
- extentC = midC + radius *cos(startPhi + extentPhi);
- }
- #ifndef QT_NO_DATASTREAM
- QDataStream &operator>>(QDataStream &in, ROICircularArc &data)
- {
- in >> data.midR >> data.midC >> data.sizeR >> data.sizeC >> data.startR
- >> data.startC >> data.extentR >> data.extentC >> data.radius >> data.startPhi
- >> data.extentPhi >> data.circDir >> data.TwoPI;
- return in;
- }
- QDataStream &operator<<(QDataStream &out, ROICircularArc &data)
- {
- out << data.midR << data.midC << data.sizeR << data.sizeC << data.startR
- << data.startC << data.extentR << data.extentC << data.radius << data.startPhi
- << data.extentPhi << data.circDir << data.TwoPI;
- return out;
- }
- #endif
|