You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kev/Drawer/Module/GeoSigmaDraw/HTrackerTransform.cpp

247 lines
7.1 KiB
C++

1 month ago
#include "stdafx.h"
#include "HTrackerTransform.h"
HTrackerTransform::HTrackerTransform()
:m_handle(0)
,m_bDrag(false)
,m_bCanMoved(false)
,m_nAllowMovePixel(5)
,m_kind(HTRACKER_TRANSFORM_KIND_SCALE)
{
m_StartPhi = 0.0f;
m_Transform.Reset();
}
//<2F><><EFBFBD><EFBFBD>:mousePt <20><>ʼ<EFBFBD><CABC>קʱ,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
void HTrackerTransform::Init(int handle, const CRect & boundRect, CPoint mousePt)
{
m_bDrag = true;
m_bCanMoved = false;
m_StartPhi = 0.0f;
m_StartPoint = mousePt;
if (handle == 8) //ƽ<><C6BD>
m_kind = HTRACKER_TRANSFORM_KIND_MOVE;
else
m_kind = HTRACKER_TRANSFORM_KIND_SCALE;
m_Transform.Reset();
m_boundRect = boundRect;
m_calculator.Calculate(m_boundRect);
m_handle = handle;
SetFixedPoints();
}
void HTrackerTransform::Draging(CPoint mousePt)
{
if (m_bDrag == false)
return;
if (m_kind == HTRACKER_TRANSFORM_KIND_SCALE)
Scale(mousePt);
else if (m_kind == HTRACKER_TRANSFORM_KIND_MOVE)
Move(mousePt);
else if (m_kind == HTRACKER_TRANSFORM_KIND_ROTATION)
Rotate(mousePt);
else //KIND_SHEAR
Shear(mousePt);
}
void HTrackerTransform::EndDrag()
{
m_bDrag = false;
m_Transform.Reset();
m_handle = 0;
m_bCanMoved = false;
m_StartPhi = 0.0f;
m_kind = HTRACKER_TRANSFORM_KIND_SCALE;
}
Gdiplus::Matrix * HTrackerTransform::GetMatrix()
{
return &m_Transform;
}
void HTrackerTransform::SetKind(HTRACKER_TRANSFORM_KIND kind)
{
m_kind = kind;
SetFixedPoints();
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<3A><><EFBFBD><EFBFBD>ѡ<EFBFBD>е<EFBFBD>handle<6C><65>Ӧ<EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD>
// HandleTopLeft HandleTop HandleTopRight
// 0 1 2
// *-----------*-----------*
// | |
// | |
// HandleLeft 7 * * 8 * 3 HandleRight
// | HandleCenter |
// | |
// *-----------*-----------*
// 6 5 4
//<2F><>קHandleʱ<65>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>
//<2F><>ק0Handleʱ<65><CAB1><EFBFBD><EFBFBD>Ӧ<EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>Ϊ4<CEAA><34><EFBFBD><EFBFBD>ק1Handleʱ<65><CAB1><EFBFBD><EFBFBD>Ӧ<EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>Ϊ5<CEAA><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ2-->6,3-->7,
//4-->0,5-->1,6-->2,7-->3.
//handle ^ 4<><34> <20><><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD>Ӧ<EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD>
void HTrackerTransform::SetFixedPoints()
{
//m_handle<6C>ķ<EFBFBD>Χ:[0,8]
if (m_handle < 0 || m_handle>8)
return ;
int hFixed = m_handle ^ 4;
//m_FixedSrc = GetHandlePoint(m_PointSrc, hFixed);
//m_FixedDest = GetHandlePoint(m_PointDest, hFixed);
m_FixedSrc = m_calculator.GetHandlePoint(hFixed);
m_FixedDest = m_FixedSrc;
if (m_kind == HTRACKER_TRANSFORM_KIND_ROTATION)
{
CSize sz = CPoint(m_calculator.Test(m_handle / 2)) - m_FixedSrc;
m_StartPhi = 180.0f * (Gdiplus::REAL) (atan2((double)sz.cy, sz.cx) / PI);
}
}
//<2F><><EFBFBD><EFBFBD>:point <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void HTrackerTransform::Scale(CPoint & point)
{
//m_FixedDest is the selected handle point of destination rectangle
CSize sz = point - m_FixedDest;
//m_FixedSrc is the selected handle point of source rectangle
CSize szSrc = m_StartPoint - m_FixedSrc;
Gdiplus::REAL scaleX = 1.0f;
Gdiplus::REAL scaleY = 1.0f;
if ((m_handle & 1) == 0) //ż<><C5BC><EFBFBD><EFBFBD>Ϊ<EFBFBD>ǵ㣬X,Y<><59><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>š<EFBFBD>
{
if (szSrc.cx != 0)
scaleX = (Gdiplus::REAL) sz.cx / (Gdiplus::REAL) szSrc.cx;
//if (!(m_Options & OptionAllowMirror) && scaleX < 0.0f)
// scaleX = 0.0f; //no allow mirror x
if (szSrc.cy != 0)
scaleY = (Gdiplus::REAL) sz.cy / (Gdiplus::REAL) szSrc.cy;
//if (!(m_Options & OptionAllowMirror) && scaleY < 0.0f)
// scaleY = 0.0f; //no allow mirror y
// if (!(nFlags & MK_SHIFT)) // maintain proportions, //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SHIFT<46><54>ʱ<EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// {
// Gdiplus::REAL scaleXabs = fabsf(scaleX);
// Gdiplus::REAL scaleYabs = fabsf(scaleY);
// if (scaleXabs > scaleYabs) scaleX = (scaleX < 0) ? -scaleYabs : scaleYabs;
// else scaleY = (scaleY < 0) ? -scaleXabs : scaleXabs;
// }
// Set cursor; might be changed after flipping
//int curs = (m_Handle & 2) / 2; // 0 or 1
//if (m_bMapFlip) curs ^= 1;
//curs ^= scaleX < 0;
//curs ^= scaleY < 0;
//HCURSOR h = g_hCursor[curs];
//if (h)
// ::SetCursor(h);
}
else if ((m_handle & 3) == 1) // horizontal edge, scale vertical
{
if (szSrc.cy != 0)
scaleY = (Gdiplus::REAL) sz.cy / (Gdiplus::REAL) szSrc.cy;
//if (!(m_Options & OptionAllowMirror) && scaleY < 0.0f)
// scaleY = 0.0f;
//if (nFlags & MK_SHIFT)
// scaleX = scaleY; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SHIFT<46><54>ʱ<EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
else if ((m_handle & 3) == 3) // vertical edge, scale horizontal
{
if (szSrc.cx != 0)
scaleX = (Gdiplus::REAL) sz.cx / (Gdiplus::REAL) szSrc.cx;
//if (!(m_Options & OptionAllowMirror) && scaleX < 0.0f)
// scaleX = 0.0f;
// if (nFlags & MK_SHIFT)
// scaleY = scaleX; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SHIFT<46><54>ʱ<EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
m_Transform.Reset();
// Translate the fixed point to the origin.
m_Transform.Translate((Gdiplus::REAL) - m_FixedSrc.x, (Gdiplus::REAL) - m_FixedSrc.y, Gdiplus::MatrixOrderAppend);
// Scale the object.
m_Transform.Scale(scaleX, scaleY, Gdiplus::MatrixOrderAppend);
// Translate back to fixed point (which may be different).
m_Transform.Translate((Gdiplus::REAL)m_FixedDest.x, (Gdiplus::REAL)m_FixedDest.y, Gdiplus::MatrixOrderAppend);
}
void HTrackerTransform::Move(CPoint & point)
{
CSize sz = point - m_StartPoint;
//Ϊ<>˷<EFBFBD>ֹ<EFBFBD><D6B9>С<EFBFBD><D0A1><EFBFBD>ƶ<EFBFBD>Ԫ<EFBFBD>أ<EFBFBD><D8A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵʱ<D6B5><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD><EFBFBD>
if (IsCanMove(point, m_StartPoint))
{
m_Transform.Reset();
m_Transform.Translate((Gdiplus::REAL)sz.cx, (Gdiplus::REAL)sz.cy);
}
}
bool HTrackerTransform::IsCanMove(const CPoint& nPrevPoint, const CPoint& nCurPoint)
{
if (m_bCanMoved)
return true;
CSize sz = nCurPoint - nPrevPoint;
//Ϊ<>˷<EFBFBD>ֹ<EFBFBD><D6B9>С<EFBFBD><D0A1><EFBFBD>ƶ<EFBFBD>Ԫ<EFBFBD>أ<EFBFBD><D8A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵʱ<D6B5><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD><EFBFBD>
if (abs(sz.cx) >= m_nAllowMovePixel || abs(sz.cy) >= m_nAllowMovePixel)
{
m_bCanMoved = true;
return true;
}
return false;
}
void HTrackerTransform::Rotate(CPoint & point)
{
CSize sz = point - m_FixedDest;
Gdiplus::REAL phi = 180.0f * (Gdiplus::REAL)(atan2((double)sz.cy, (double)sz.cx) / PI) - m_StartPhi;
while (phi <= -180.0f)
phi += 360.0f; // (-180, 180]
m_Transform.Reset();
m_Transform.Translate((Gdiplus::REAL) - m_FixedSrc.x, (Gdiplus::REAL) - m_FixedSrc.y);
m_Transform.Rotate(phi, Gdiplus::MatrixOrderAppend);
m_Transform.Translate((Gdiplus::REAL) m_FixedDest.x, (Gdiplus::REAL) m_FixedDest.y, Gdiplus::MatrixOrderAppend);
}
void HTrackerTransform::Shear(CPoint & point)
{
CSize sz = point - m_FixedDest;
CSize szSrc = m_StartPoint - m_FixedSrc;
Gdiplus::REAL shearX = 0.0f;
Gdiplus::REAL shearY = 0.0f;
Gdiplus::REAL scaleX = 1.0f;
Gdiplus::REAL scaleY = 1.0f;
if (m_handle & 2) // vertical edge
{
if (sz.cx != 0)
shearY = (Gdiplus::REAL) sz.cy / (Gdiplus::REAL) sz.cx;
if (szSrc.cx != 0)
scaleX = (Gdiplus::REAL) sz.cx / (Gdiplus::REAL) szSrc.cx;
//if (!(m_Options&OptionAllowMirror) && scaleX < 0.0f) scaleX = 0.0f;
}
else // horizontal edge
{
if (sz.cy != 0)
shearX = (Gdiplus::REAL) sz.cx / (Gdiplus::REAL) sz.cy;
if (szSrc.cy != 0)
scaleY = (Gdiplus::REAL) sz.cy / (Gdiplus::REAL) szSrc.cy;
//if (!(m_Options&OptionAllowMirror) && scaleY < 0.0f) scaleY = 0.0f;
}
m_Transform.Reset();
m_Transform.Translate((Gdiplus::REAL) - m_FixedSrc.x, (Gdiplus::REAL) - m_FixedSrc.y);
// Don't scale the other direction if Shift is pressed
//if ((nFlags & MK_SHIFT) == 0) m_Transform.Scale(scaleX, scaleY, Gdiplus::MatrixOrderAppend);
m_Transform.Shear(shearX, shearY, Gdiplus::MatrixOrderAppend);
m_Transform.Translate((Gdiplus::REAL) m_FixedDest.x, (Gdiplus::REAL) m_FixedDest.y, Gdiplus::MatrixOrderAppend);
}