拖动点可更改形状

时间:2015-04-29 09:37:13

标签: mfc gdi

我已设法使用以下代码连接点击鼠标的4个点。(我使用的是MFC)。

  void CChildView::OnLButtonDown(UINT nFlags,CPoint point)
  {    
  if(m_LastPoint.x!=-1 && m_iPointAmount<6)
  {
    CDC* pDC= GetDC();
    pDC->MoveTo(m_LastPoint.x,m_LastPoint.y);
    pDC->LineTo(point.x,point.y);
  }
    m_LastPoint=point;
    m_iPointAmount++;
  }

变量在构造函数中初始化如下。

 m_LastPoint.x=-1;
 m_LastPoint.y=-1;
 m_iPointAmount=1;

我现在想做以下事情。

1.无论何时在其中一个点上进行鼠标点击并拖动,该点都应重新定位到新位置。(因此形状会发生变化)。

2.这应适用于所有四点。

请指导我如何实现这一目标。

1 个答案:

答案 0 :(得分:0)

这是如何工作的

开始单击窗口,直到达到m_iPolygonMaximumSides中的sepcified数量。 当达到指定的点数时,多边形将被关闭,因此现在您可以选择一个点。 单击一个点以选择它,拖动将继续,直到您再次单击。 要重置多边形,您必须关闭窗口。

在你的CChildView类的cpp文件中添加以下include,因为它用于计算平方根

#include <math.h>

在CChildView类中添加以下方法和变量

CList<CPoint> m_PointList;
CPoint m_selectedPoint;
int m_iPolygonMaximumSides;
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
void DrawPolygonFromList();

在CChildView类的消息映射中添加这些行

ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
CChildView构造函数中的

用你想要的数量初始化m_iPolygonMaximumSides(4)和m_selectedPoint用(-1,-1)初始化

m_iPolygonMaximumSides = 4;
m_selectedPoint = CPoint(-1,-1);

然后将这个添加到您的CChildView cpp文件中,这些都是使用的方法

void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
{

    //check if we already reached the maximum point number
    if (m_PointList.GetSize() == m_iPolygonMaximumSides)
    {
        //check if a point was already selected, and so we are in the drag mode
        if (m_selectedPoint.x !=-1)
        {
            //if the point was already selected it means that we want to stop the dragging,
            //so we just set the x to -1
            m_selectedPoint.x =-1;
        }
        else
        {
            //if we didn't have a point selected we have to check if the point clicked is one of our points
            //so we will use this for to search for out point
            for (POSITION pos = m_PointList.GetHeadPosition();pos != NULL;m_PointList.GetNext(pos))
            {
                CPoint currentPoint = m_PointList.GetAt(pos);
                //this is the pythagorean theorem to find a distance between two points A and B
                // distance = squareRoot( (A.x-B.x)^2+(A.y-B.y)^2)
                int distanceBetweenPoints = floor(sqrt(pow(double(currentPoint.x-point.x),2)+pow(double(currentPoint.y-point.y),2)));
                //if this distance is less than 10 pixels, then we accept it as a click on our points
                //this is just a tollerance, so we can reduce or increment it as we like
                //the smaller the tollerance nearer you will have to click to be able to select the point
                if (distanceBetweenPoints <= 10)
                {
                    //if the tollerance is met then we set the point as our selected point
                    m_selectedPoint = currentPoint;
                    //interrupt the iteration, because we don't need to look further
                    break;
                }
            }
        }
    }
    //if we didn't reach the maximum point amount it means that we still have to keep going on getting the points
    else if (m_PointList.GetSize() > 0)
    {
        CDC* pDC= GetDC();
        CPoint lastPoint = m_PointList.GetTail();
        //draw a line from the previous (last) point to the new one
        pDC->MoveTo(lastPoint.x,lastPoint.y);
        pDC->LineTo(point.x,point.y);

        //if we are going to reach the maximum amount of points then we will have to close the polygon
        if (m_PointList.GetSize()==m_iPolygonMaximumSides-1)
        {
            CPoint firstPoint = m_PointList.GetHead();
            //draw a line from the current point to the first point
            pDC->MoveTo(point.x,point.y);
            pDC->LineTo(firstPoint.x,firstPoint.y);
        }
    }
    //add the point to the list only after you have done everything, only if we didn't reachthe maximum amount
    if (m_PointList.GetSize() < m_iPolygonMaximumSides)
        m_PointList.AddTail(point);
}


void CChildView::OnMouseMove(UINT nFlags, CPoint point)
{
    //check if we already have the maximum number of points
    if (m_PointList.GetSize()==m_iPolygonMaximumSides)
    {
        //check i
        if (m_selectedPoint.x != -1)
        {
            //check if we actually find the point
            POSITION posFound = m_PointList.Find(m_selectedPoint);
            if (posFound != NULL)
            {
                //update the selected point with the new one
                m_selectedPoint=point;
                //now also update the list
                m_PointList.SetAt(posFound,point);
                //draw the polygon
                DrawPolygonFromList();
            }
        }
    }
}

void CChildView::DrawPolygonFromList()
{
    //this is checked again because we might want to use this function in another place
    if (m_PointList.GetSize()==m_iPolygonMaximumSides)
    {
        //use this to clear the window
        RedrawWindow();
        //this will be used to draw
        CDC* pDC= GetDC();
        POSITION pos = m_PointList.GetHeadPosition();
        //load the first and second point
        CPoint pointBefore = m_PointList.GetNext(pos);
        CPoint currentPoint = m_PointList.GetNext(pos);
        //draw the line connecting the first and the second point
        pDC->MoveTo(pointBefore.x,pointBefore.y);
        pDC->LineTo(currentPoint.x,currentPoint.y);

        //draw the intermediary points
        while (pos != NULL) 
        {
            pointBefore = currentPoint;
            currentPoint = m_PointList.GetNext(pos);
            pDC->MoveTo(pointBefore.x,pointBefore.y);
            pDC->LineTo(currentPoint.x,currentPoint.y);
        } 
        //now close the poligon
        pointBefore = currentPoint;
        currentPoint = m_PointList.GetHead();
        pDC->MoveTo(pointBefore.x,pointBefore.y);
        pDC->LineTo(currentPoint.x,currentPoint.y);
    }
}
相关问题