//******************************************************************************* 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); }
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 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; }