// ArrowObj.cpp: implementation of the CArrowObj class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ActiveXArrow.h"
#include "ArrowObj.h"
#include "PieForm.h"
#include <math.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CArrowObj::CArrowObj()
{
m_swapAngle = 10;
m_colorArrow = Color(255, 0, 0, 0);
}
CArrowObj::~CArrowObj()
{
}
void CArrowObj::GetPointFromCircle(double ptFarx, double ptFary,
CRect rectCircle,
double angle,
double swapAngle,
double length,
double& p1x, double& p1y,
double& p2x, double& p2y)
// CPoint& p1,
// CPoint& p2)
{
double ox, oy;
ox = rectCircle.left + m_rectCircle.Width() / 2;
oy = rectCircle.top + m_rectCircle.Height() / 2;
double px1, py1, px2, py2;
double pheta, alpha;
pheta = CPieForm::D2R(swapAngle);
// alpha = CPieForm::D2R(angle);
// alpha = -alpha;
double h = pow(length, 2) - pow((oy -ptFary), 2);
// CString s;
// s.Format(_T("h: %f, len: %f, len2: %f"), h, (int)length, oy - ptFary);
// AfxMessageBox(_T("") + s);
py1 = (ptFary) * pow(sin(pheta / 2), 2) +
(oy) * pow(cos(pheta / 2), 2)
+ sin(pheta / 2) * cos(pheta /2) * sqrt(pow(length, 2) - pow((oy - ptFary), 2));
py2 = (ptFary) * pow(sin(pheta / 2), 2) +
(oy) * pow(cos(pheta / 2), 2)
- sin(pheta / 2) * cos(pheta /2) * sqrt(pow(length, 2) - pow((oy - ptFary), 2));
double radius = rectCircle.Width() / 2.0;
if(angle > 90)
{
// AfxMessageBox(_T(">90"));
px1 = -sqrt(abs(pow(radius, 2) - pow((py1 - oy), 2))) + ox;
px2 = sqrt(abs(pow(radius, 2) - pow((py2 - oy), 2))) + ox;
}
else if(angle <= 90)
{
// AfxMessageBox(_T("<=90"));
px1 = sqrt(abs(pow(radius, 2) - pow((py1 - oy), 2))) + ox;
px2 = -sqrt(abs(pow(radius, 2) - pow((py2 - oy), 2))) + ox;
}
p1x = px1;
p1y = py1;
p2x = px2;
p2y = py2;
}
void CArrowObj::CalculateCircle(CRect rectOrigin, double angle, double swapAngle, CRect& circleRect)
{
// m_rectCircle;
// CPoint topPoint = CPieForm::GetPointFromEllipse(angle, rectOrigin);
double topPointx, topPointy;
CPieForm::GetPointFromEllipse(angle, rectOrigin, topPointx, topPointy);
double ox, oy;
ox = rectOrigin.right - rectOrigin.Width() / 2;
oy = rectOrigin.bottom;
// double length = rectOrigin.Height() ;
double length = sqrt(pow(topPointx - ox, 2) + pow(topPointy - oy, 2));
double pheta = CPieForm::D2R(swapAngle);
// double radius = rectOrigin.Height() * tan(pheta / 2);
double radius = length * sin(pheta / 2);
CPoint sp(ox - radius, oy - radius);
CPoint ep(ox + radius, oy + radius);
circleRect.SetRect(sp, ep);
}
double CArrowObj::GetLengthFromTwoPoints(double x1, double y1, double x2, double y2)
{
double ret;
ret = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
return ret;
}
void CArrowObj::Draw(Graphics* g, CRect rectOrigin, double angle, BOOL bShowOnlyArrow)
{
if(!g) return;
CalculateCircle(rectOrigin, angle, m_swapAngle, m_rectCircle);
double ox, oy;
ox = m_rectCircle.left + m_rectCircle.Width() / 2;
oy = m_rectCircle.top + m_rectCircle.Height() / 2;//.bottom;
Rect oRect(rectOrigin.left, rectOrigin.top, rectOrigin.Width(), rectOrigin.Height());
if(!bShowOnlyArrow)
g->SetClip(oRect, CombineModeIntersect);
// double farPtx, farPty;
CPieForm::GetPointFromEllipse(angle, rectOrigin, farPtx, farPty);
CRect rectCenter;
rectCenter.SetRect(rectOrigin.left + rectOrigin.Width()*0.5 *0.75,
rectOrigin.top + rectOrigin.Height() * 0.75,
rectOrigin.right - rectOrigin.Width() * 0.5* 0.75,
rectOrigin.bottom);
int centerMargin = 0.75;
Rect CenterRect(rectCenter.left, rectCenter.top,
rectCenter.Width(), rectCenter.Height()*2);
SolidBrush centerBrush(Color(20, 0, 0, 0));
// g->FillPie(¢erBrush, CenterRect, 0, -360);
// CPoint p1, p2;
double length = GetLengthFromTwoPoints(farPtx, farPty, ox, oy);
GetPointFromCircle(farPtx, farPty, m_rectCircle, angle, m_swapAngle, length,
p1x, p1y, p2x, p2y);
// PointF* gp1 = new PointF();
// PointF* gp2 = new PointF();
// PointF* gp3 = new PointF();
PointF gp1(farPtx, farPty);
PointF gp2(p1x, p1y);
PointF gp3(p2x, p2y);
// if(angle <= 90)
{
// CString sa;
// sa.Format(_T("angle: %f"), angle);
// AfxMessageBox(_T(">=90 ") + sa);
// delete gp1;
// delete gp2;
// delete gp3;
}
// else
{
// delete gp1;
// delete gp2;
// delete gp3;
//
// gp1 = new PointF(farPtx, farPty);
// gp3 = new PointF(p1.x, p1.y);
// gp2 = new PointF(p2.x, p2.y);
}
// PointF gp1(farPtx, farPty);
// PointF gp2(p1.x, p1.y);
// PointF gp3(p2.x, p2.y);
// PointF arrayPt[3] = {gp1, gp3, gp2};
Pen mypen(Color(255, 255, 0, 0));
// SolidBrush myArrowBrush(Color(255, 0, 0, 0));
PointF bottomPoint(rectOrigin.Width()/2, rectCenter.bottom);
// that is color
// LinearGradientBrush myArrowBrush(oRect, m_colorArrow,
// Color(255, 255, 255, 255), 45 + angle);
SolidBrush myArrowBrush(m_colorArrow);
Rect crect(m_rectCircle.left, m_rectCircle.top, m_rectCircle.Width(),
m_rectCircle.Height());
g->DrawEllipse(&mypen, crect);
g->DrawRectangle(&mypen, crect);
GraphicsPath myPath1(FillModeAlternate);
// myPath1.AddLine(*gp3, *gp1);
// myPath1.AddLine(*gp1, *gp2);
myPath1.AddLine(gp3, gp1);
myPath1.AddLine(gp1, gp2);
GraphicsPath myPath2(FillModeAlternate);
myPath2.AddEllipse(CenterRect);
// Region myRegion(&myPath2);
// myRegion.Xor(&myPath1);
g->FillPath(&myArrowBrush, &myPath1);
g->FillPath(&myArrowBrush, &myPath2);
// g->FillRegion(&myArrowBrush, &myRegion);
// g->DrawEllipse(&mypen, crect);
// g->DrawRectangle(&mypen, crect);
// delete gp1;
// delete gp2;
// delete gp3;
}