bool bcg_pointInPie (const CBCGPRect& rect, double dblAngleStart, double dblAngleFinish, const CBCGPPoint& ptTestIn, double dblDoughnutPercent) { if (!rect.PtInRect(ptTestIn)) { return false; } CBCGPPoint ptTest = ptTestIn; CBCGPPoint ptCenter = rect.CenterPoint(); double dblRadiusX = 0.5 * rect.Width(); double dblRadiusY = 0.5 * rect.Height(); if (dblRadiusX > dblRadiusY && dblRadiusX != 0.) { ptTest.Scale(CBCGPPoint(dblRadiusY / dblRadiusX, 1.0), ptCenter); } else if (dblRadiusY > dblRadiusX && dblRadiusY != 0.) { ptTest.Scale(CBCGPPoint(1.0, dblRadiusX / dblRadiusY, 1.0), ptCenter); } double dblAngle = bcg_normalize_rad(bcg_angle(ptCenter, ptTest)); dblAngleStart = bcg_normalize_rad(dblAngleStart); dblAngleFinish = bcg_normalize_rad(dblAngleFinish); BOOL bIn = FALSE; const BOOL bIsFullEllipse = bcg_IsFullEllipse(bcg_rad2deg(dblAngleStart), bcg_rad2deg(dblAngleFinish), TRUE, 0.1f); if (bIsFullEllipse) { bIn = TRUE; } else { if (dblAngleStart > dblAngleFinish) { bIn = (dblAngle <= dblAngleFinish) || (dblAngleStart <= dblAngle); } else { bIn = (dblAngle >= dblAngleStart) && (dblAngle <= dblAngleFinish); } } if (bIn) { double angleCos = cos(dblAngle); double angleSin = sin(dblAngle); CBCGPPoint ptEdge(ptCenter.x + angleCos * .5 * rect.Width(), ptCenter.y + angleSin * .5 * rect.Height()); double r = bcg_distance(ptEdge, ptCenter); double distToCenter = bcg_distance(ptTestIn, ptCenter); return (distToCenter <= r && distToCenter > r * dblDoughnutPercent); } return false; }
//*************************************************************************************** int CBCGPRadialMenuObject::HitTestShape(const CBCGPPoint& pt) { CBCGPRect rect = m_rect; if (rect.Width() < rect.Height()) { rect.top += (rect.Height() - rect.Width()) / 2; rect.bottom = rect.top + rect.Width(); } else if (rect.Height() < rect.Width()) { rect.left += (rect.Width() - rect.Height()) / 2; rect.right = rect.left + rect.Height(); } rect.DeflateRect(2., 2.); rect.right -= m_nShadowDepth; rect.bottom -= m_nShadowDepth; const double radius = rect.Width() / 2; const double radiusSmall = INTERNAL_PART * rect.Width() + 1.0; const CBCGPPoint center = rect.CenterPoint(); double dblDistanceToCenter = bcg_distance(pt, center); if (dblDistanceToCenter > radius) { return -1; } const int nItems = (int)m_arItems.GetSize(); if (dblDistanceToCenter <= radiusSmall) { return m_bHasCenterButton ? nItems - 1 : -1; } const int nCircleItems = m_bHasCenterButton ? nItems - 1 : nItems; if (nCircleItems == 0) { return -1; } double dblDeltaAngle = 360. / nCircleItems; double dblStartAngle = 90. - dblDeltaAngle / 2; double dblAngle = bcg_normalize_deg(bcg_rad2deg(acos((pt.x - center.x) / dblDistanceToCenter))); if (pt.y > center.y) { dblAngle = 360 - dblAngle; } int nHit = (int)((dblAngle - dblStartAngle) / dblDeltaAngle); if (dblAngle < dblStartAngle) { nHit = nCircleItems - 1 - (int)((dblStartAngle - dblAngle) / dblDeltaAngle); } return nHit; }