【问题标题】:Dragging points to change the shapes拖动点以更改形状
【发布时间】:2015-07-08 12:09:12
【问题描述】:

我已经成功地连接了使用以下代码进行鼠标单击的 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.这应该适用于所有四个点。

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

【问题讨论】:

  • =) 我又来了。 "m_iPointAmount
  • 要做其他你需要使用 OnMouseMove msdn.microsoft.com/en-us/library/3158baat.aspx 的事情,在里面你必须检查鼠标是否被按下,然后做你需要的事情。但显然在这里你也希望能够“选择”点。正如你的用户名所说的你是一个“初学者”,所以我认为首先你应该多学习一点关于 MFC C++ 如何工作的基础知识,GDI 如何工作,检查可用的功能和特性,然后尝试实现一些东西。像这样进入黑暗真的很难。
  • 如何保存第一点?还有如何在点击时选择点?任何示例代码?请…………
  • 我用另一个问题回答你,你是如何保存最后一点的?
  • point.x 和 point.y 为我们提供了点击的最后一点。

标签: mfc gdi


【解决方案1】:

这是如何工作的

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

代码

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

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

【讨论】:

  • 我在此声明中收到错误(未声明的标识符)。 CList m_PointList;这是正确的吗?
  • 你是否忘记添加 CList m_PointList;去你的班级?
  • 我已经在视图类头文件中添加了。
  • 我得到的错误是“语法错误:缺失;在
  • 试试这个“#include afxtempl.h”在这里查看更多关于CList的细节msdn.microsoft.com/en-us/library/bxde0zae.aspx
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-05
  • 2016-12-08
  • 1970-01-01
  • 1970-01-01
  • 2021-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多