2301_76850406 2023-04-11 19:56 采纳率: 100%
浏览 58
已结题

关于mfc画线问题一直自动链接原点

老哥们为什么我用mfc画线的时候最新的那个端点一直链接原点是怎么回事,感觉主要问题是在那一串星号下面的代码,因为那个点的颜色会随那个rgb一起改变

img

img


那个原点会一直连接我最新的控制点和绘制出来的曲线的点

void CbView::DoubleBuffer(CDC* pDC) {
    CRect rect;
    GetClientRect(&rect);
    nClientWidth = rect.Width();
    nClientHeight = rect.Height();
    pDC->SetMapMode(MM_ANISOTROPIC);
    pDC->SetWindowExt(rect.Width(), rect.Height());
    pDC->SetViewportExt(rect.Width(), -rect.Height());
    pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2);
    CDC memDC;//内存DC
    memDC.CreateCompatibleDC(pDC);//创建一个与显示pDC兼容的内存memDC
    CBitmap NewBitmap, * pOldBitmap;//内存中承载的临时位图
    NewBitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());//创建兼容位图
    pOldBitmap = memDC.SelectObject(&NewBitmap);//将兼容位图选入memDC
    memDC.FillSolidRect(rect, pDC->GetBkColor());
    rect.OffsetRect(-rect.Width() / 2, -rect.Height() / 2);
    memDC.SetMapMode(MM_ANISOTROPIC);//内存自定义DC坐标系
    memDC.SetWindowExt(rect.Width(), rect.Height());
    memDC.SetViewportExt(rect.Width(), -rect.Height());
    memDC.SetViewportOrg(rect.Width() / 2, rect.Height() / 2);
    *************************
    CPen NewPen, * pOldPen;
    NewPen.CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
    pOldPen = memDC.SelectObject(&NewPen);
    CBrush NewBrush, * pOldBrush;
    pOldBrush = (CBrush*)memDC.SelectStockObject(BLACK_BRUSH);
    for (int i = 0; i < max; i++) {
    
        if (i == 0) {
            memDC.MoveTo(P[i].x,P[i].y);
            memDC.Ellipse(Round(P[i].x) - 5, Round(P[i].y) - 5, Round(P[i].x) + 5, Round(P[i].y) + 5);
        }

        else{

            memDC.LineTo(Round(P[i].x), Round(P[i].y));
        memDC.Ellipse(Round(P[i].x) - 5, Round(P[i].y) - 5, Round(P[i].x) + 5, Round(P[i].y) + 5);
    }
    
    }
    if (CtrlPtNum != -1) {
        CString str;
        str.Format(_T(" x=%.0f,y=%.0f"), P[CtrlPtNum].x, P[CtrlPtNum].y);
        memDC.TextOut(Round(P[CtrlPtNum].x) + 5, Round(P[CtrlPtNum].y) + 5, str);
    }
    pDC->SelectObject(pOldBrush);
    memDC.SelectObject(pOldPen);
    DrawBSplineCurve(&memDC);//绘制曲线 
    pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, -rect.Width() / 2, -rect.Height() / 2, SRCCOPY);
    //pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, NULL, NULL, SRCCOPY);
    memDC.SelectObject(pOldBitmap);
    NewBitmap.DeleteObject();
    memDC.DeleteDC();}
void CbView::OnMouseMove(UINT nFlags, CPoint point)
{
     //TODO: 在此添加消息处理程序代码和/或调用默认值



    CString str;
    str.Format(_T("[%d,%d]  "), point.x - nClientWidth / 2, nClientHeight / 2 - point.y); //引号中的两个空格是为了消除重叠现象
    CDC* pDC = GetDC();
    pDC->TextOut(0, 0, str); //窗口左上角坐标为(0,0),修改可改变鼠标坐标的显示位置
    pDC->MoveTo(nClientWidth / 2, nClientHeight / 2);
    pDC->LineTo(nClientWidth / 2, nClientHeight / 2);

    if (TRUE == bMove)
    {
        if (CtrlPtNum == -1) { CtrlPtNum = 0; }
        else {
            P[CtrlPtNum] =Convert( point);
        
        }
    }
    CtrlPtNum = -1;
    int i;


    for (i = 0; i < max; i++) {
        CP2 CursorPt = Convert (point);//得到鼠标当前位置并且将点存在变量中
        CString str1;
        if ((CursorPt.x - P[i].x) * (CursorPt.x - P[i].x) + (CursorPt.y - P[i].y) * (CursorPt.y - P[i].y) < 25) //如果鼠标与某个控制点的距离不超过5个像素点认为当前鼠标指向点
        {

            CtrlPtNum = i;
            bLBtnDown = TRUE;
            SetCursor(LoadCursor(NULL, IDC_SIZEALL));//鼠标改
            break;



        }
    }
    if (max == i)
    {
        CtrlPtNum = -1;
    }
    ReleaseDC(pDC);
    Invalidate(FALSE);

    CView::OnMouseMove(nFlags, point);
    



}


void CbView::DrawBSplineCurve(CDC * pDC)//绘制曲线
{
    // TODO: 在此处添加实现代码.
    CPen redPen, greenPen, * pOldPen;
    redPen.CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
    greenPen.CreatePen(PS_SOLID, 2, RGB(0, 255, 0));
    CP2 pt;//曲线上的当前点
    pt.x = Round((P[0].x + 4.0 * P[1].x + P[2].x) / 6);
    pt.y = Round((P[0].y + 4.0 * P[1].y + P[2].y) / 6);
    pOldPen = pDC->SelectObject(&greenPen);
    pDC->Ellipse(Round(pt.x) - 5, Round(pt.y) - 5, Round(pt.x) + 5, Round(pt.y) + 5);
     pDC->SelectObject(pOldPen);
     pDC->MoveTo(Round(pt.x), Round(pt.y));
    for (int i = 3; i < max; i++) {
        for (double t = 0.0; t <= 1; t += 0.01) {
            double F03 = (-t * t * t + 3 * t * t - 3 * t + 1) / 6;
            double F13 = (3 * t * t * t - 6 * t * t + 4) / 6;
            double F23 = (-3 * t * t * t + 3 * t * t + 3 * t + 1) / 6;
            double F33 = t * t * t / 6;
             pt.x = P[i - 3].x* F03 + P[i-2].x * F13 + P[i - 1].x * F23 +P[i].x* F33;
             pt.y = P[i - 3].y * F03 + P[i - 2].y * F13 + P[i - 1].y * F23 + P[i].y * F33;        
             pDC->LineTo(Round(pt.x),Round(pt.y));//绘制曲线
        }

        pOldPen = pDC->SelectObject(&greenPen);
        pDC->Ellipse(Round(pt.x) - 5, Round(pt.y) - 5, Round(pt.x) + 5, Round(pt.y) + 5);
        pDC->SelectObject(pOldPen);
    }
    pDC->SelectObject(pOldPen);
    
}
CP2 CbView::Convert(CPoint point) {
    CP2 pt;
    pt.x = point.x - nClientWidth / 2;
    pt.y = nClientHeight / 2 - point.y;
    return pt;


}



void CbView::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    if (Brd)
    {
        P[j] = Convert(point);
        if (j < max - 1) j++;
        else Brd = FALSE;
    
    }
    if (bLBtnDown == TRUE)
    {
        bMove = TRUE;
    }
    

    CView::OnLButtonDown(nFlags, point);
}


void CbView::OnLButtonUp(UINT nFlags, CPoint point)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    bLBtnDown = FALSE;
    bMove = FALSE;
    //CtrlPtNum = 0;
    CView::OnLButtonUp(nFlags, point);
}


  • 写回答

5条回答 默认 最新

  • Mr Bean908 2023-04-12 14:56
    关注

    把max弄成j就行

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月12日
  • 已采纳回答 4月12日
  • 修改了问题 4月11日
  • 创建了问题 4月11日

悬赏问题

  • ¥15 给我一个openharmony跑通webrtc实现视频会议的简单demo项目,sdk为12
  • ¥15 vb6.0使用jmail接收smtp邮件并另存附件到D盘
  • ¥30 vb net 使用 sendMessage 如何输入鼠标坐标
  • ¥15 关于freesurfer使用freeview可视化的问题
  • ¥100 谁能在荣耀自带系统MagicOS版本下,隐藏手机桌面图标?
  • ¥15 求SC-LIWC词典!
  • ¥20 有关esp8266连接阿里云
  • ¥15 C# 调用Bartender打印机打印
  • ¥15 我这个代码哪里有问题 acm 平台上显示错误 90%,我自己运行好像没什么问题
  • ¥50 C#编程中使用printDocument类实现文字排版打印问题