bool ArcObjectImp::hit(LocationType pixelCoord) const { int iStart = static_cast<int>(getStartAngle()); if (iStart < 0) { iStart--; } int iStop = static_cast<int>(getStopAngle()); if (iStop < 0) { iStop--; } if (iStart == iStop) { iStart = 0; iStop = 360; } ArcRegion eArcRegion = getArcRegion(); DrawUtil::initializeCircle(); LocationType center = getCenter(); bool bHit = false; // Filled area FillStyle eFillStyle = getFillStyle(); if (eFillStyle != EMPTY_FILL) { int iSize = abs(iStop - iStart) + 1; if (eArcRegion == ARC_CENTER) { iSize += 2; } else if (eArcRegion == ARC_CHORD) { iSize += 1; } double* pXVertices = new double[iSize]; double* pYVertices = new double[iSize]; int i = 0; int iIndex = 0; for (i = iStart, iIndex = 0; i <= iStop; i++, iIndex++) { LocationType arcPoint = getLocation(static_cast<double>(i)); pXVertices[iIndex] = arcPoint.mX; pYVertices[iIndex] = arcPoint.mY; } if ((eArcRegion == ARC_CENTER) || (eArcRegion == ARC_CHORD)) { if (eArcRegion == ARC_CENTER) { pXVertices[iSize - 2] = center.mX; pYVertices[iSize - 2] = center.mY; } pXVertices[iSize - 1] = pXVertices[0]; pYVertices[iSize - 1] = pYVertices[0]; } bHit = DrawUtil::isWithin(pixelCoord.mX, pixelCoord.mY, pXVertices, pYVertices, iSize); delete [] pXVertices; delete [] pYVertices; } // Line if (bHit == false) { bool bLine = false; bLine = getLineState(); if (bLine == true) { // Check the arc line double size = 1.0; GraphicLayer* pLayer = NULL; pLayer = getLayer(); if (pLayer != NULL) { View* pView = pLayer->getView(); if (pView != NULL) { size = pView->getPixelSize(center, center); } size *= min(pLayer->getXScaleFactor(), pLayer->getYScaleFactor()); } LocationType basePoint; for (int i = iStart; i <= iStop; i++) { LocationType currentPoint = getLocation(static_cast<double>(i)); if (i != iStart) { bHit = DrawUtil::lineHit(currentPoint, basePoint, pixelCoord, 2.0/size); if (bHit == true) { break; } } basePoint.mX = currentPoint.mX; basePoint.mY = currentPoint.mY; } // Check the arc region lines if (bHit == false) { LocationType startPoint = getLocation(static_cast<double>(iStart)); LocationType stopPoint = getLocation(static_cast<double>(iStop)); if (eArcRegion == ARC_CENTER) { bHit = DrawUtil::lineHit(startPoint, center, pixelCoord, 2.0/size); if (bHit == false) { bHit = DrawUtil::lineHit(stopPoint, center, pixelCoord, 2.0/size); } } else if (eArcRegion == ARC_CHORD) { bHit = DrawUtil::lineHit(startPoint, stopPoint, pixelCoord, 2.0/size); } } } } return bHit; }
void TextObjectImp::updateBoundingBox() { // Get the width and height of the bounding box in screen pixels based on the scaled text image size int iWidth = 0; int iHeight = 0; string text = getSubstitutedText(); if (text.empty() == false) { QString strMessage = QString::fromStdString(text); QFont scaledFont = getScaledFont(); int iMaxSize = 0; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &iMaxSize); int iAlignment = getTextAlignment(); QFontMetrics ftMetrics(scaledFont); QRect boundingBox = ftMetrics.boundingRect(0, 0, iMaxSize, iMaxSize, iAlignment | Qt::TextWordWrap, strMessage); iWidth = boundingBox.width(); iHeight = boundingBox.height(); } // Get the current bounding box LocationType llCorner = getLlCorner(); LocationType urCorner = getUrCorner(); // Use the lower left corner as the anchor and compute the data coordinate of the upper right corner GraphicLayer* pLayer = getLayer(); if (pLayer != NULL) { // Compute the upper right coordinate PerspectiveView* pView = dynamic_cast<PerspectiveView*>(pLayer->getView()); if (pView != NULL) { double zoomFactor = 100.0 / pView->getZoomPercentage(); double xScale = zoomFactor / pLayer->getXScaleFactor(); double yScale = zoomFactor / pLayer->getYScaleFactor(); urCorner.mX = llCorner.mX + (iWidth * xScale); urCorner.mY = llCorner.mY + (iHeight * yScale); } if (dynamic_cast<OrthographicView*>(pLayer->getView()) != NULL) { double dScreenX = 0.0; double dScreenY = 0.0; pLayer->translateDataToScreen(llCorner.mX, llCorner.mY, dScreenX, dScreenY); pLayer->translateScreenToData(dScreenX + iWidth, dScreenY + iHeight, urCorner.mX, urCorner.mY); } } else { urCorner.mX = llCorner.mX + iWidth; urCorner.mY = llCorner.mY + iHeight; } // Update the bounding box and selection handles setBoundingBox(llCorner, urCorner); updateHandles(); mUpdateBoundingBox = false; }
bool EllipseObjectImp::hit(LocationType pixelCoord) const { LocationType llCorner = getLlCorner(); LocationType urCorner = getUrCorner(); double xVertices[DrawUtil::VERTEX_COUNT + 1]; double yVertices[DrawUtil::VERTEX_COUNT + 1]; DrawUtil::initializeCircle(); LocationType center; center.mX = (llCorner.mX + urCorner.mX) / 2.0; center.mY = (llCorner.mY + urCorner.mY) / 2.0; LocationType radii; radii.mX = fabs (llCorner.mX - urCorner.mX) / 2.0; radii.mY = fabs (llCorner.mY - urCorner.mY) / 2.0; int i = 0; for (i = 0; i < DrawUtil::VERTEX_COUNT; i++) { xVertices[i] = center.mX + radii.mX * DrawUtil::sCirclePoints[i].mX; yVertices[i] = center.mY + radii.mY * DrawUtil::sCirclePoints[i].mY; } xVertices[DrawUtil::VERTEX_COUNT] = xVertices[0]; yVertices[DrawUtil::VERTEX_COUNT] = yVertices[0]; bool bHit = false; // Filled area FillStyle eFillStyle = getFillStyle(); if (eFillStyle != EMPTY_FILL) { bHit = DrawUtil::isWithin(pixelCoord.mX, pixelCoord.mY, xVertices, yVertices, DrawUtil::VERTEX_COUNT+1); } // Line if (bHit == false) { bool bLine = false; bLine = getLineState(); if (bLine == true) { double size = 1.0; GraphicLayer* pLayer = NULL; pLayer = getLayer(); if (pLayer != NULL) { View* pView = pLayer->getView(); if (pView != NULL) { size = pView->getPixelSize(llCorner, urCorner); } size *= min(pLayer->getXScaleFactor(), pLayer->getYScaleFactor()); } LocationType basePoint; for (i = 0; i < DrawUtil::VERTEX_COUNT; i++) { LocationType currentPoint(xVertices[i], yVertices[i]); if (i != 0) { bHit = DrawUtil::lineHit(currentPoint, basePoint, pixelCoord, 2.0/size); if (bHit == true) { break; } } basePoint = currentPoint; } } } return bHit; }