拖动点以更改形状 [英] Dragging points to change the shapes

查看:67
本文介绍了拖动点以更改形状的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经成功地使用以下代码连接了四个单击鼠标的点.(我使用的是MFC).

I have managed to connect 4 points where the mouse click is made using the following code.(I am using 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++;
  }

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

The variables are initialized in the constructor as follows.

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

我现在想做以下事情.

1.每当在其中一个点上单击鼠标并拖动鼠标时,该点应重新定位到新位置.(因此,形状会发生变化).

1.Whenever the mouse click is made on one of the points and dragged, the point should relocate to the new position.(so the shape is changed).

2.这应该适用于所有四个点.

2.This should be applicable for all the four points.

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

Pls guide me on how to achieve this.

推荐答案

这是如何工作的

开始单击窗口,直到达到m_iPolygonMaximumSides中分隔的数量. 当达到指定的点数时,多边形将关闭,因此现在您可以选择一个点. 单击一个点附近以将其选中,拖动将继续进行,直到再次单击为止. 要重置多边形,您必须关闭窗口.

how this works

start clicking on the window until you reach the amount sepcified in m_iPolygonMaximumSides. When you reach the amount of points specified the polygon will be closed, so now you are able to select a point. Click near a point to select it, the drag will keep going until you click again. To reset the polygon you will have to close the window.

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

in the cpp file of your CChildView class add the following include, because it is used to calculate square root

#include <math.h>

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

in your CChildView class add the following methods and variables

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

在CChildView类的消息图中,添加以下行

in the message map of your CChildView class add these lines

ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()

在CChildView构造函数中,使用所需的数量(4)初始化m_iPolygonMaximumSides并使用(-1,-1)初始化m_selectedPoint

in the CChildView constructor initialize m_iPolygonMaximumSides with the amount you want (4) and m_selectedPoint with (-1,-1) like

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

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

then this is to be added to your CChildView cpp file, these are all the moethods used

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

这篇关于拖动点以更改形状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆