//******************************************************************************* void CBCGPLinearGaugeImpl::OnDrawPointer(CBCGPGraphicsManager* pGM, const CBCGPPointsArray& arPoints, const CBCGPPointsArray& arShadowPoints, int nIndex) { ASSERT_VALID(pGM); CBCGPLinearGaugePointer* pData = DYNAMIC_DOWNCAST(CBCGPLinearGaugePointer, m_arData[nIndex]); ASSERT_VALID(pData); const int nCount = (int)arPoints.GetSize (); const double scaleRatio = GetScaleRatioMid(); const CBCGPBrush& brFill = pData->GetFillBrush().IsEmpty() ? m_Colors.m_brPointerFill : pData->GetFillBrush(); const CBCGPBrush& brFrame = pData->GetOutlineBrush().IsEmpty() ? m_Colors.m_brPointerOutline : pData->GetOutlineBrush(); if (pData->GetStyle() == CBCGPLinearGaugePointer::BCGP_GAUGE_NEEDLE_CIRCLE) { ASSERT(nCount == 4); if (pGM->IsSupported(BCGP_GRAPHICS_MANAGER_COLOR_OPACITY) && arShadowPoints.GetSize() == 4) { CBCGPRect rectShadow; CreateRectFromArray(arShadowPoints, rectShadow); pGM->FillEllipse(rectShadow, m_brShadow); } CBCGPRect rect; CreateRectFromArray(arPoints, rect); pGM->FillEllipse(rect, brFill); pGM->DrawEllipse(rect, brFrame, scaleRatio); } else { if (pGM->IsSupported(BCGP_GRAPHICS_MANAGER_COLOR_OPACITY) && arShadowPoints.GetSize() > 2) { pGM->FillGeometry(CBCGPPolygonGeometry(arShadowPoints), m_brShadow); } if (nCount > 2) { CBCGPPolygonGeometry rgn(arPoints); pGM->FillGeometry(rgn, brFill); } for (int i = 0; i < nCount - 1; i++) { pGM->DrawLine(arPoints[i], arPoints[i + 1], brFrame, scaleRatio); } if (nCount > 2) { pGM->DrawLine(arPoints[nCount - 1], arPoints[0], brFrame, scaleRatio); } } }
BOOL PointInPolygon(const CBCGPPointsArray& arPoly, const CBCGPPoint& pt) { int nSize = (int)arPoly.GetSize (); if (nSize < 3) { return FALSE; } const CBCGPPoint* pData = arPoly.GetData(); int count = 0; int current = 0; int next = 1; while(next < nSize) { BOOL b = (pData[next].y <= pt.y); if (pData[current].y <= pt.y) { b = !b; } if (b) { if(((pData[next].x - pData[current].x) * (pt.y - pData[current].y) / (pData[next].y - pData[current].y)) <= (pt.x - pData[current].x)) { count++; } } current++; next++; } if (pData[0] != pData[nSize - 1]) { current = nSize - 1; next = 0; BOOL b = (pData[next].y <= pt.y); if (pData[current].y <= pt.y) { b = !b; } if (b) { if(((pData[next].x - pData[current].x) * (pt.y - pData[current].y) / (pData[next].y - pData[current].y)) <= (pt.x - pData[current].x)) { count++; } } } return (count & 1) ? TRUE : FALSE; }
//**************************************************************************************** void CBCGPEngine3D::DrawPolygon(const CBCGPPointsArray& arPoints, const CBCGPBrush& brush, double dblLineWidth) { int nNumPoints = (int)arPoints.GetSize(); if (m_pDefaultGM == NULL || nNumPoints == 0) { return; } m_pDefaultGM->DrawLines(arPoints, brush, dblLineWidth); }
BOOL AddPointInPolygon(CBCGPPointsArray& arPoly, const CBCGPPoint& pt) { if (FindPointInPolygon (arPoly, pt) != -1) { return FALSE; } arPoly.Add (pt); return TRUE; }
int FindPointInPolygon(const CBCGPPointsArray& arPoly, const CBCGPPoint& pt) { int nSize = (int)arPoly.GetSize (); if (nSize == 0) { return -1; } int index = -1; const CBCGPPoint* pData = arPoly.GetData(); for (int i = 0; i < nSize; i++) { if (pData[i].x == pt.x && pData[i].y == pt.y) { index = i; break; } } return index; }
void CBCGPVector4::CalcPlane(const CBCGPPointsArray& arPoints) { int i; const CBCGPPoint* pData = arPoints.GetData(); if (pData == NULL) { return; } CBCGPMatrix4x4 mA; for (i = 0; i < 3; i++) { mA[i][0] = 1.; mA[i][1] = pData[i].y; mA[i][2] = pData[i].z; } CBCGPMatrix4x4 mB; for (i = 0; i < 3; i++) { mB[i][0] = pData[i].x; mB[i][1] = 1.; mB[i][2] = pData[i].z; } CBCGPMatrix4x4 mC; for (i = 0; i < 3; i++) { mC[i][0] = pData[i].x; mC[i][1] = pData[i].y; mC[i][2] = 1.; } CBCGPMatrix4x4 mD; for (i = 0; i < 3; i++) { mD[i][0] = pData[i].x; mD[i][1] = pData[i].y; mD[i][2] = pData[i].z; } m_data[0] = mA.Det(3); m_data[1] = mB.Det(3); m_data[2] = mC.Det(3); m_data[3] = -mD.Det(3); }
//**************************************************************************************** void CBCGPEngine3D::FillPolygon(const CBCGPPointsArray& arPoints, const CBCGPBrush& brush) { int nNumPoints = (int)arPoints.GetSize(); if (m_pDefaultGM == NULL || nNumPoints == 0) { return; } ASSERT_VALID(m_pDefaultGM); if (m_pDefaultGM->GetType() == CBCGPGraphicsManager::BCGP_GRAPHICS_MANAGER_GDI) { CBCGPPolygonGeometry g(arPoints); g.SetTemporary(); m_pDefaultGM->FillGeometry(g, brush); } else { LPPOINT arPointsGDI = new POINT[nNumPoints]; for (int i = 0; i < nNumPoints; i++) { arPointsGDI[i] = CPoint(bcg_round(arPoints[i].x), bcg_round(arPoints[i].y)); } HRGN hrgn = ::CreatePolygonRgn(arPointsGDI, nNumPoints, ALTERNATE); UINT nBytesCount = ::GetRegionData(hrgn, sizeof(RGNDATA), NULL); if (nBytesCount == 0) { delete [] arPointsGDI; return; } LPBYTE lpRgnData = new BYTE[nBytesCount]; ZeroMemory( lpRgnData, nBytesCount); if (::GetRegionData(hrgn, nBytesCount, (LPRGNDATA)lpRgnData) != nBytesCount) { delete [] arPointsGDI; delete [] lpRgnData; return; } LPRGNDATA pData = (LPRGNDATA)lpRgnData; LPRECT points = (LPRECT)pData->Buffer; for (DWORD k = 0; k < pData->rdh.nCount; k++) { m_pDefaultGM->FillRectangle(CBCGPRect(points[k]), brush); } delete [] arPointsGDI; delete [] lpRgnData; DeleteObject(hrgn); } }
//******************************************************************************* CBCGPGeometry* CBCGPChartInterLineColoringEffect::CreateGeometry(const CBCGPPointsArray& arOrgPoints, const CBCGPRect& rectBounds, BCGPChartFormatSeries::ChartCurveType curveType, BOOL bClip) { CBCGPChartAxis* pXAxis = m_pSeries1->GetRelatedAxis(CBCGPChartSeries::AI_X); ASSERT_VALID(pXAxis); BOOL bIsVertical = pXAxis->IsVertical(); CBCGPGeometry* pGeometry = NULL; CBCGPPointsArray arPoints; arPoints.Append(arOrgPoints); CBCGPPoint ptStart = arPoints[0]; CBCGPPoint ptEnd = arPoints[arPoints.GetSize() - 1]; CBCGPPoint ptClipCorrectionStart = ptStart; CBCGPPoint ptClipCorrectionEnd = ptEnd; if (bIsVertical) { if (bClip) { if (pXAxis->m_bReverseOrder) { ptClipCorrectionStart.y -= 1.; ptClipCorrectionEnd.y += 1.; } else { ptClipCorrectionStart.y += 1.; ptClipCorrectionEnd.y -= 1.; } ptStart = CBCGPPoint(rectBounds.left, ptClipCorrectionStart.y); ptEnd = CBCGPPoint(rectBounds.left, ptClipCorrectionEnd.y); } else { ptStart = CBCGPPoint(rectBounds.left, ptStart.y); ptEnd = CBCGPPoint(rectBounds.left, ptEnd.y); } } else { if (bClip) { if (pXAxis->m_bReverseOrder) { ptClipCorrectionStart.x += 1.; ptClipCorrectionEnd.x -= 1.; } else { ptClipCorrectionStart.x -= 1.; ptClipCorrectionEnd.x += 1.; } ptStart = CBCGPPoint(ptClipCorrectionStart.x, rectBounds.bottom); ptEnd = CBCGPPoint(ptClipCorrectionEnd.x, rectBounds.bottom); } else { ptStart = CBCGPPoint(ptStart.x, rectBounds.bottom); ptEnd = CBCGPPoint(ptEnd.x, rectBounds.bottom); } } if (curveType == BCGPChartFormatSeries::CCT_SPLINE || curveType == BCGPChartFormatSeries::CCT_SPLINE_HERMITE) { CBCGPSplineGeometry::BCGP_SPLINE_TYPE splineType = CBCGPSplineGeometry::BCGP_SPLINE_TYPE_KB; if (curveType == BCGPChartFormatSeries::CCT_SPLINE_HERMITE) { splineType = CBCGPSplineGeometry::BCGP_SPLINE_TYPE_HERMITE; } CBCGPComplexGeometry* pComplex = new CBCGPComplexGeometry() ; CBCGPSplineGeometry geometryTop(arOrgPoints, splineType, FALSE); pComplex->AddPoints(geometryTop.GetPoints(), CBCGPPolygonGeometry::BCGP_CURVE_TYPE_BEZIER); if (bClip) { pComplex->AddLine(ptClipCorrectionEnd); } pComplex->AddLine(ptEnd); pComplex->AddLine(ptStart); if (bClip) { pComplex->AddLine(ptClipCorrectionStart); } pComplex->SetClosed(TRUE); pGeometry = pComplex; } else { if (bClip) { arPoints.Add(ptClipCorrectionEnd); } arPoints.Add(ptEnd); arPoints.Add(ptStart); if (bClip) { arPoints.Add(ptClipCorrectionStart); } pGeometry = new CBCGPPolygonGeometry(arPoints); } return pGeometry; }
BOOL BCGPCalculateIntersectPoint(const CBCGPPointsArray& arPoly1, const CBCGPPointsArray& arPoly2, CBCGPPoint& ptIntersect) { int nPoly1Size = (int)arPoly1.GetSize(); int nPoly2Size = (int)arPoly2.GetSize(); if (nPoly1Size == 0 || nPoly2Size == 0) { return FALSE; } const CBCGPPoint* pData1 = arPoly1.GetData (); const CBCGPPoint* pData2 = arPoly2.GetData (); CBCGPPointsArray arPolyRes; arPolyRes.SetSize (0, nPoly1Size + nPoly2Size); int i = 0; int j = 0; // 1. find all points from arPoly1F in arPoly2F int nSize1 = 0; for (i = 0; i < nPoly1Size; i++) { const CBCGPPoint& pt = pData1[i]; if (PointInPolygon (arPoly2, pt)) { if (AddPointInPolygon(arPolyRes, pt)) { nSize1++; } } } // all points in arPoly2F if (nSize1 != nPoly1Size) { // 2. find all points from arPoly2F in arPoly1F int nSize2 = 0; for (i = 0; i < nPoly2Size; i++) { const CBCGPPoint& pt = pData2[i]; if (PointInPolygon (arPoly1, pt)) { if (AddPointInPolygon(arPolyRes, pt)) { nSize2++; } } } // all points in arPoly1F if (nSize1 != 0 || nSize2 != nPoly2Size) { // 3. find all intersection points arPoly1F and arPoly2F for (i = 0; i < nPoly1Size; i++) { const CBCGPPoint& ptStart1 = pData1[i]; const CBCGPPoint& ptEnd1 = pData1[(i + 1) % nPoly1Size]; for (j = 0; j < nPoly2Size; j++) { const CBCGPPoint& ptStart2 = pData2[j]; const CBCGPPoint& ptEnd2 = pData2[(j + 1) % nPoly2Size]; if (bcgp_classify_point2D(ptStart1, ptEnd1, ptStart2) != bcgp_classify_point2D(ptStart1, ptEnd1, ptEnd2)) { CBCGPPoint pt; if (BCGPIntersectPoints2D (ptStart1, ptEnd1, ptStart2, ptEnd2, pt)) { AddPointInPolygon(arPolyRes, pt); } } } } } } int nSize = (int)arPolyRes.GetSize(); if (nSize < 2) { return FALSE; } ptIntersect.x = 0.0; ptIntersect.y = 0.0; for (i = 0; i < nSize; i++) { ptIntersect += arPolyRes[i]; } ptIntersect /= nSize; return TRUE; }
//******************************************************************************* BOOL CBCGPLinearGaugeImpl::GetRangeShape(CBCGPRect& rect, CBCGPPolygonGeometry& shape, double dblStartValue, double dblFinishValue, double dblStartWidth, double dblFinishWidth, double dblOffsetFromFrame, int nScale) { rect.SetRectEmpty(); shape.Clear(); CBCGPPoint pt1; if (!ValueToPoint(dblStartValue, pt1, nScale)) { return FALSE; } CBCGPPoint pt2; if (!ValueToPoint(dblFinishValue, pt2, nScale)) { return FALSE; } const double scaleRatio = GetScaleRatioMid(); if (dblStartWidth == 0.) { CBCGPGaugeScaleObject* pScale = GetScale(nScale); if (pScale != NULL) { dblStartWidth = pScale->m_dblMajorTickMarkSize + pScale->m_dblOffsetFromFrame; } } if (dblFinishWidth == 0.) { dblFinishWidth = dblStartWidth; } dblStartWidth *= scaleRatio; dblFinishWidth *= scaleRatio; dblOffsetFromFrame *= scaleRatio; if (dblFinishWidth == dblStartWidth) { if (m_bIsVertical) { rect.left = pt1.x + dblOffsetFromFrame; rect.top = pt1.y; rect.right = pt1.x + dblStartWidth + dblOffsetFromFrame; rect.bottom = pt2.y; } else { rect.left = pt1.x; rect.top = pt1.y + dblOffsetFromFrame; rect.right = pt2.x; rect.bottom = pt1.y + dblStartWidth + dblOffsetFromFrame; } } else { CBCGPPointsArray arPoints; if (m_bIsVertical) { arPoints.Add(CBCGPPoint(pt1.x + dblOffsetFromFrame, pt1.y)); arPoints.Add(CBCGPPoint(pt2.x + dblOffsetFromFrame, pt2.y)); arPoints.Add(CBCGPPoint(pt2.x + dblOffsetFromFrame + dblFinishWidth, pt2.y)); arPoints.Add(CBCGPPoint(pt1.x + dblOffsetFromFrame + dblStartWidth, pt1.y)); } else { arPoints.Add(CBCGPPoint(pt1.x, pt1.y + dblOffsetFromFrame)); arPoints.Add(CBCGPPoint(pt2.x, pt2.y + dblOffsetFromFrame)); arPoints.Add(CBCGPPoint(pt2.x, pt2.y + dblOffsetFromFrame + dblFinishWidth)); arPoints.Add(CBCGPPoint(pt1.x, pt1.y + dblOffsetFromFrame + dblStartWidth)); } shape.SetPoints(arPoints); } return TRUE; }
//******************************************************************************* void CBCGPLinearGaugeImpl::CreatePointerPoints(CBCGPPointsArray& arPoints, int nPointerIndex, BOOL bShadow) { if (m_rect.IsRectEmpty()) { return; } CBCGPLinearGaugePointer* pData = DYNAMIC_DOWNCAST(CBCGPLinearGaugePointer, m_arData[nPointerIndex]); if (pData == NULL) { ASSERT(FALSE); return; } CBCGPGaugeScaleObject* pScale = GetScale(pData->GetScale()); if (pScale == NULL) { ASSERT(FALSE); return; } const double scaleRatio = GetScaleRatioMid(); double dblValue = pData->m_nAnimTimerID != 0 ? pData->m_dblAnimatedValue : pData->m_dblValue; double dblSizeMax = max(pScale->m_dblMajorTickMarkSize, 2. * pScale->m_dblMinorTickMarkSize) * scaleRatio; double dblSize = dblSizeMax; if (dblSize == 0) { dblSize = 8. * scaleRatio; } double dblSizePerc = bcg_clamp(pData->m_dblSize, 0.0, 1.0); if (dblSizePerc != 0.0) { dblSize = max(dblSize * dblSizePerc, 2.0); } CBCGPPoint point; if (!ValueToPoint(dblValue, point, pData->GetScale())) { return; } double offset = max(pScale->m_dblMajorTickMarkSize, pScale->m_dblMinorTickMarkSize) * scaleRatio; offset = max(offset, m_dblMaxRangeSize); double x = point.x; double y = point.y; if (dblSize < dblSizeMax && pData->GetPosition() != CBCGPLinearGaugePointer::BCGP_GAUGE_POSITION_NEAR) { double dblSizeDelta = dblSizeMax - dblSize; if (pData->GetPosition() == CBCGPLinearGaugePointer::BCGP_GAUGE_POSITION_CENTER) { dblSizeDelta /= 2.0; } if (m_bIsVertical) { x += dblSizeDelta; } else { y += dblSizeDelta; } } if (bShadow) { x += 2. * m_sizeScaleRatio.cx; y += 2. * m_sizeScaleRatio.cy; } const double delta = pData->m_dblWidth == 0 ? dblSize / 2 : (pData->m_dblWidth * scaleRatio) / 2; switch (pData->GetStyle()) { case CBCGPLinearGaugePointer::BCGP_GAUGE_NEEDLE_TRIANGLE: if (m_bIsVertical) { arPoints.Add(CBCGPPoint(x, y - delta)); arPoints.Add(CBCGPPoint(x, y + delta)); arPoints.Add(CBCGPPoint(x + dblSize, y)); } else { arPoints.Add(CBCGPPoint(x + delta, y)); arPoints.Add(CBCGPPoint(x - delta, y)); arPoints.Add(CBCGPPoint(x, y + dblSize)); } break; case CBCGPLinearGaugePointer::BCGP_GAUGE_NEEDLE_TRIANGLE_INV: if (m_bIsVertical) { arPoints.Add(CBCGPPoint(x + dblSize, y - delta)); arPoints.Add(CBCGPPoint(x + dblSize, y + delta)); arPoints.Add(CBCGPPoint(x, y)); } else { arPoints.Add(CBCGPPoint(x + delta, y + dblSize)); arPoints.Add(CBCGPPoint(x - delta, y + dblSize)); arPoints.Add(CBCGPPoint(x, y)); } break; case CBCGPLinearGaugePointer::BCGP_GAUGE_NEEDLE_RECT: case CBCGPLinearGaugePointer::BCGP_GAUGE_NEEDLE_CIRCLE: if (m_bIsVertical) { arPoints.Add(CBCGPPoint(x, y + delta)); arPoints.Add(CBCGPPoint(x, y - delta)); arPoints.Add(CBCGPPoint(x + dblSize, y - delta)); arPoints.Add(CBCGPPoint(x + dblSize, y + delta)); } else { arPoints.Add(CBCGPPoint(x + delta, y + dblSize)); arPoints.Add(CBCGPPoint(x - delta, y + dblSize)); arPoints.Add(CBCGPPoint(x - delta, y)); arPoints.Add(CBCGPPoint(x + delta, y)); } break; case CBCGPLinearGaugePointer::BCGP_GAUGE_NEEDLE_DIAMOND: if (m_bIsVertical) { arPoints.Add(CBCGPPoint(x + .5 * dblSize, y + delta)); arPoints.Add(CBCGPPoint(x, y)); arPoints.Add(CBCGPPoint(x + .5 * dblSize, y - delta)); arPoints.Add(CBCGPPoint(x + dblSize, y)); } else { arPoints.Add(CBCGPPoint(x, y + dblSize)); arPoints.Add(CBCGPPoint(x - delta, y + .5 * dblSize)); arPoints.Add(CBCGPPoint(x, y)); arPoints.Add(CBCGPPoint(x + delta, y + .5 * dblSize)); } } }
//********************************************************************************************************** void CBCGPLinearGaugeImpl::OnDrawTickMark(CBCGPGraphicsManager* pGM, const CBCGPPoint& ptFrom, const CBCGPPoint& ptTo, CBCGPGaugeScaleObject::BCGP_TICKMARK_STYLE style, BOOL bMajor, double dblVal, int nScale, const CBCGPBrush& brFillIn, const CBCGPBrush& brOutlineIn) { ASSERT_VALID(pGM); CBCGPGaugeScaleObject* pScale = GetScale(nScale); if (pScale == NULL) { ASSERT(FALSE); return; } const double scaleRatio = GetScaleRatioMid(); const double dblSize = (bMajor ? pScale->m_dblMajorTickMarkSize : pScale->m_dblMinorTickMarkSize) * scaleRatio; const CBCGPGaugeColoredRangeObject* pRange = GetColoredRangeByValue(dblVal, nScale, BCGP_GAUGE_RANGE_TICKMARK_COLOR); const CBCGPBrush& brFill = (pRange != NULL && !pRange->m_brTickMarkFill.IsEmpty()) ? pRange->m_brTickMarkFill : (brFillIn.IsEmpty() ? m_Colors.m_brTickMarkFill : brFillIn); const CBCGPBrush& brOutline = (pRange != NULL && !pRange->m_brTickMarkOutline.IsEmpty()) ? pRange->m_brTickMarkOutline : (brOutlineIn.IsEmpty() ? m_Colors.m_brTickMarkOutline : brOutlineIn); switch (style) { case CBCGPGaugeScaleObject::BCGP_TICKMARK_LINE: pGM->DrawLine(ptFrom, ptTo, brOutline, scaleRatio); break; case CBCGPGaugeScaleObject::BCGP_TICKMARK_TRIANGLE: case CBCGPGaugeScaleObject::BCGP_TICKMARK_TRIANGLE_INV: case CBCGPGaugeScaleObject::BCGP_TICKMARK_BOX: { CBCGPPointsArray arPoints; const double dblWidth = (style == CBCGPGaugeScaleObject::BCGP_TICKMARK_BOX) ? (dblSize / 4.) : (bMajor ? (dblSize * 2. / 3.) : (dblSize / 2.)); const double dx = m_bIsVertical ? dblSize : max(dblWidth * .5, 3); const double dy = m_bIsVertical ? max(dblWidth * .5, 3) : dblSize; double x = ptTo.x; double y = ptTo.y; switch (style) { case CBCGPGaugeScaleObject::BCGP_TICKMARK_TRIANGLE: if (m_bIsVertical) { arPoints.Add(CBCGPPoint(x - dx, y - dy)); arPoints.Add(CBCGPPoint(x - dx, y + dy)); arPoints.Add(CBCGPPoint(x, y)); } else { arPoints.Add(CBCGPPoint(x + dx, y - dy)); arPoints.Add(CBCGPPoint(x - dx, y - dy)); arPoints.Add(CBCGPPoint(x, y)); } break; case CBCGPGaugeScaleObject::BCGP_TICKMARK_TRIANGLE_INV: if (m_bIsVertical) { arPoints.Add(CBCGPPoint(x, y - dy)); arPoints.Add(CBCGPPoint(x, y + dy)); arPoints.Add(CBCGPPoint(x - dx, y)); } else { arPoints.Add(CBCGPPoint(x + dx, y)); arPoints.Add(CBCGPPoint(x - dx, y)); arPoints.Add(CBCGPPoint(x, y - dy)); } break; case CBCGPGaugeScaleObject::BCGP_TICKMARK_BOX: if (m_bIsVertical) { arPoints.Add(CBCGPPoint(x - dx, y - dy)); arPoints.Add(CBCGPPoint(x - dx, y + dy)); arPoints.Add(CBCGPPoint(x, y + dy)); arPoints.Add(CBCGPPoint(x, y - dy)); } else { arPoints.Add(CBCGPPoint(x + dx, y - dy)); arPoints.Add(CBCGPPoint(x - dx, y - dy)); arPoints.Add(CBCGPPoint(x - dx, y)); arPoints.Add(CBCGPPoint(x + dx, y)); } break; } CBCGPPolygonGeometry rgn(arPoints); pGM->FillGeometry(rgn, brFill); pGM->DrawGeometry(rgn, brOutline, scaleRatio); } break; case CBCGPGaugeScaleObject::BCGP_TICKMARK_CIRCLE: { CBCGPPoint ptCenter( .5 * (ptFrom.x + ptTo.x), .5 * (ptFrom.y + ptTo.y)); const double dblRadius = bMajor ? (dblSize / 2.) : (dblSize / 4.); CBCGPEllipse ellipse(ptCenter, dblRadius, dblRadius); pGM->FillEllipse(ellipse, brFill); pGM->DrawEllipse(ellipse, brOutline, scaleRatio); if (scaleRatio == 1.0 && !pGM->IsSupported(BCGP_GRAPHICS_MANAGER_ANTIALIAS)) { CBCGPEllipse ellipse1(ptCenter, dblRadius - 1., dblRadius - 1.); pGM->DrawEllipse(ellipse1, brOutline); } } break; } }
//******************************************************************************* void CBCGPKnob::CreatePointerPoints(double dblRadius, CBCGPPointsArray& arPoints, int nPointerIndex, BOOL bShadow) { if (m_rect.IsRectEmpty()) { return; } CBCGPRect rect = m_rect; CBCGPKnobPointer* pData = DYNAMIC_DOWNCAST(CBCGPKnobPointer, m_arData[nPointerIndex]); if (pData == NULL) { ASSERT(FALSE); return; } CBCGPCircularGaugeScale* pScale = GetScale(pData->GetScale()); if (pScale == NULL) { ASSERT(FALSE); return; } const double scaleRatio = GetScaleRatioMid(); double dblValue = pData->IsAnimated() ? pData->GetAnimatedValue() : pData->GetValue(); double dblOffset = bcg_clamp(pData->GetOffsetFromCenter(), 0.0, 1.0); if (dblOffset == 0.0) { dblOffset = dblRadius * .5; } else { dblOffset = dblRadius * bcg_clamp(dblOffset, 0.5, 1.0); } double dblAngle = bcg_deg2rad(pScale->GetStartAngle()) - bcg_deg2rad(pScale->GetStartAngle() - pScale->GetFinishAngle()) * (dblValue - pScale->GetStart()) / (pScale->GetFinish() - pScale->GetStart()); dblAngle = bcg_normalize_rad (dblAngle); if (bShadow) { rect.OffsetRect(2 * m_sizeScaleRatio.cx, 2 * m_sizeScaleRatio.cy); } CBCGPPoint center((rect.left + rect.right) / 2.0, (rect.top + rect.bottom) / 2.0); const double angleCos = cos(dblAngle); const double angleSin = sin(dblAngle); double dblWidth = bcg_clamp(pData->GetWidth(), 0.0, dblRadius / 10.0); const double dblPointerAngle = dblAngle - M_PI_2; switch (pData->GetStyle()) { case CBCGPKnobPointer::BCGP_KNOB_POINTER_HANDLE: { dblRadius -= .2 * scaleRatio; double dblExtend = (dblRadius * .9); double dblSize = dblRadius + dblExtend; center.x -= angleCos * dblExtend; center.y += angleSin * dblExtend; if (dblWidth == 0.0) { dblWidth = dblRadius / 3.0; } dblWidth *= 0.5; if (dblWidth < 1.0) { arPoints.Add(center); arPoints.Add(CBCGPPoint( center.x + angleCos * dblSize, center.y - angleSin * dblSize)); } else { double dblArrowLen = max(2.0 * dblWidth, 10.0 * scaleRatio); dblSize -= dblArrowLen; const double dx = cos(dblPointerAngle) * dblWidth; const double dy = -sin(dblPointerAngle) * dblWidth; arPoints.Add(CBCGPPoint(center.x + dx, center.y + dy)); arPoints.Add(CBCGPPoint(center.x - dx, center.y - dy)); const CBCGPPoint pt1( center.x + angleCos * dblSize - dx, center.y - angleSin * dblSize - dy); const CBCGPPoint pt2( center.x + angleCos * dblSize + dx, center.y - angleSin * dblSize + dy); arPoints.Add(pt1); arPoints.Add(CBCGPPoint( center.x + angleCos * (dblSize + dblArrowLen), center.y - angleSin * (dblSize + dblArrowLen))); arPoints.Add(pt2); } } break; case CBCGPKnobPointer::BCGP_KNOB_POINTER_LINE: { if (bShadow) { return; } if (dblWidth == 0.0) { dblWidth = 2. * scaleRatio; } const double dx = cos(dblPointerAngle) * dblWidth; const double dy = -sin(dblPointerAngle) * dblWidth; arPoints.Add(CBCGPPoint(center.x + angleCos * dblOffset - dx, center.y - angleSin * dblOffset - dy)); arPoints.Add(CBCGPPoint(center.x + angleCos * dblOffset + dx, center.y - angleSin * dblOffset + dy)); dblOffset = dblRadius - 4. * scaleRatio; arPoints.Add(CBCGPPoint(center.x + angleCos * dblOffset + dx, center.y - angleSin * dblOffset + dy)); arPoints.Add(CBCGPPoint(center.x + angleCos * dblOffset - dx, center.y - angleSin * dblOffset - dy)); } break; case CBCGPKnobPointer::BCGP_KNOB_POINTER_CIRCLE: { if (bShadow) { return; } if (dblWidth == 0.0) { dblWidth = max(2. * scaleRatio, dblRadius / 8); } dblOffset = dblRadius - 6. * scaleRatio - dblWidth; arPoints.Add(CBCGPPoint(center.x + angleCos * dblOffset, center.y - angleSin * dblOffset)); arPoints.Add(CBCGPPoint(dblWidth, dblWidth)); } break; } }