无码中文字幕色专区_91av俱乐部_无码人妻h动漫_26uuu成人_91九色丨porny丨国产jk_青青视频在线播放_国内自拍第二页_国产又粗又长又爽又黄的视频_色哟哟免费网站_久久出品必属精品_a级黄色一级片_99日在线视频

中國自動化學會專家咨詢工作委員會指定宣傳媒體
文摘詳情
gkongbbs

C#運動控制開源(一): CAD導圖和小線段速度前瞻的優化之CAD導圖

http://www.moduwu.com 2026-04-13 10:22 深圳市正運動技術有限公司

01

ZMC432-V2運動控制器介紹

ZMC432-V2高性能多軸運動控制器是一款兼容EtherCAT總線和脈沖型的獨立式運動控制器,自帶6軸本地差分脈沖軸,最多可擴展至32軸,能實現總線軸+脈沖軸混合插補的多軸運動控制場合。同時支持正運動遠程顯示功能,能提供網絡組態顯示,可實時監控和調整參數配置。

正運動ZMC432-V2運動控制器介紹.webp

ZMC432-V2硬件功能特性:

(1)支持32軸運動控制(脈沖+EtherCAT總線),EtherCAT最小通訊周期可達125us;

(2)24路通用輸入、12路通用輸出,2路模擬量輸出(DA),其中包括2路高速輸入和2路高速輸出;

(3)6路差分脈沖軸輸出,總線軸、脈沖軸可混合插補;

(4)內置多項實時性運動控制功能,例如視覺飛拍、多維PSO、高速位置鎖存,多軸同步運行等;

(5)可通過EtherCAT擴展模塊進行IO硬件資源擴展,可擴展至4096個隔離輸入口和4096個隔離輸出口;

(6)具備豐富的運動控制功能,如點位運動、電子凸輪、直線插補、圓弧插補、連續軌跡加工;

(7)支持掉電檢測、掉電存儲,多種程序加密方式,能夠有效防止系統故障,保護項目工程文件數據,并提高系統的可靠性;

(8)通過純國產IDE開發環境RTSys進行項目開發,可實時仿真、在線跟蹤以及診斷與調試,簡便易用,支持多種高級上位機語言聯合編程進行二次開發。

正運動ZMC432-V2運動控制器架構圖.webp

02

C#運動控制+CAD導圖DEMO概述

本期示教DEMO是以正運動的運動控制函數庫,CAD導圖函數庫,在VS環境下使用C#進行編程開發。

DEMO內容主要實現CAD圖紙解析(導入CAD文件,軌跡數據解析,編輯軌跡)后下發給控制器進行運動(運動前瞻,運動指令下發,狀態監控)。用戶可以參考例程更快的使用正運動函數庫進行相關開發。

后期我們將推出以下3篇教程介紹該示教例程的開發流程和使用方法,方便用戶快速上手該例程,并掌握C#運動控制與CAD導圖相結合編程開發的相關知識。

? C#運動控制開源(一): CAD導圖和小線段速度前瞻的優化之CAD導圖

? C#運動控制開源(二): CAD導圖和小線段速度前瞻的優化之前瞻優化

? C#運動控制開源(三): CAD導圖和小線段速度前瞻的優化的軟件框架

03

C#使用ZMOTION CAD庫進行CAD導圖的開發

正運動技術提供開放的ZmotionCadEx庫,可導入DXF、Ai、Plt、Dst圖紙,可以生成運動坐標數據轉G代碼、zbasic運動指令、或直接PC函數執行運動。

1.在VS2019菜單“文件”→“新建”→“項目”,啟動創建項目向導。

3.1.webp

2.選擇開發語言為“C#”和Windows窗體應用程序,點擊下一步。

3.2.webp

3.配置好項目名稱和位置,以及相應框架,點擊創建。

3.3.webp

4.找到廠家提供的光盤資料里面的C#函數庫,路徑如下(64位庫為例)。

進入廠商提供的光盤資料,找到ZmotionCadEx.dll,ZmotionCadEx.cs這兩個個庫文件。庫文件路徑:【00光盤資料】→【04PC函數】→【03Zmotion CAD庫V3.1】→【庫文件】→【Windows平臺】→【C#】→【64位】。

3.4.webp

5.將廠商提供的C#的庫文件以及相關文件復制到新建的項目中。

(1)將ZmotionCadEx.cs文件復制到新建的項目里面中。

3.5.1.webp

(2)將ZmotionCadEx.dll文件放入bin\debug文件夾中。

3.5.2.webp

(3)將ZmotionCadEx.cs文件添加進項目中。右鍵項目名稱,選擇添加,再選擇現有項,選擇ZmotionCadEx.cs文件。

3.5.3.webp

6.雙擊Form1.cs里面的Form1,出現代碼編輯界面,在文件開頭寫入using ZmotionCadDll。

3.6.webp

至此,項目新建完成,可進行C#項目開發。

例程界面如下:

例程界面.webp

CAD解析與編輯流程:

CAD解析與編輯流程.webp

04

實現CAD文件解析與顯示

1.CAD解析相關函數介紹

①連接控制器。

Description:    //與控制器建立鏈接,成功后解鎖高級功能
Input:          //IP地址,字符串的方式輸入
Output:         //控制器句柄
Return:         //錯誤碼
int32 __stdcall ZMotionCadArray_OpenEth(char *ipaddr, ZMC_HANDLE *pHandle);
*************************************************************/
[DllImport("ZmotionCadEx.dll", EntryPoint = "ZMotionCadArray_OpenEth", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ZMotionCadArray_OpenEth(string ipaddr, out IntPtr phandle);

②導入CAD圖形。

/*************************************************************
Description:    //導入圖形文件(支持dxf、plt、ai、dst)
Input:          //
    lpszFileFullPathname 路徑和文件名
    duUnit  PLT的比例    Option   預留, 缺省都轉換為seg
    refDistance    轉換時參考精度
Output:         //
Return:         //錯誤碼
int __stdcall ZMotionCadArray_ImportVectGraph(LPCTSTR lpszFileFullPathname, double duUnit, int Option, double refDistance);
*************************************************************/
[DllImport("ZmotionCadEx.dll", EntryPoint = "ZMotionCadArray_ImportVectGraph", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ZMotionCadArray_ImportVectGraph(string lpszFileFullPathname, double duUnit, int Option, double refDistance);

③提取圖形數組。

/*************************************************************
Description:    // 提取當前圖形數組
Input:          //struct_Array  提取的數組
                //nStructNum    數組的數量
Output:         //
Return:         //錯誤碼
*************************************************************/
//int __stdcall ZMotionCadArray_GetVectArray(Struct_ZCad_Array *struct_Array, int nStructNum);
[DllImport("ZmotionCadEx.dll", EntryPoint = "ZMotionCadArray_GetVectArray", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ZMotionCadArray_GetVectArray(ref Struct_ZCad_Array struct_Array, int nStructNum);

④圖形數組格式。

④圖形數組格式.webp

⑤獲取CAD圖形的范圍。

/*************************************************************
Description:    // 范圍   坐標方向是向上為正
Input:          //
Output:         //
Return:         //錯誤碼
*************************************************************/
//uint32  __stdcall ZMotionCadArray_GetRange(float *pLeft, float *pBottom, float *pWdith, float *pHeight, double refDistance);
[DllImport("ZmotionCadEx.dll", EntryPoint = "ZMotionCadArray_GetRange", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ZMotionCadArray_GetRange(ref float pLeft, ref float pBottom, ref float pWdith, ref float pHeight, double refDistance);

2.解析流程

步驟1:連接控制器并導入需要解析的CAD文件。

ZmotionCad.ZMotionCadArray_ImportVectGraph導入CAD文件(支持DXF、Ai、Plt、Dst格式);

參數3可以設置是否把曲線強制轉換為小線段,本例程是轉化成小線段解析的。

使用ZMotionCadArray_GetRange獲取到CAD圖形的范圍,并和顯示用的PictureBox長寬進行計算,獲得轉換比例和偏移。

if(G_CardHandle == (IntPtr)0)
{
    MessageBox.Show("檢測到尚未連接控制器,請先連接控制器再進行操作");
    return;
}
if (G_CadHandle == (IntPtr)0)
{
    iret = ZmotionCad.ZMotionCadArray_OpenEth(連接控制器.Adrr, out G_CadHandle);
}
if (G_CadHandle != (IntPtr)0)       //開始導入CAD文件
{
    OpenFileDialog openFileDialog1 = new OpenFileDialog();
    openFileDialog1.InitialDirectory = "\\";
    openFileDialog1.Filter = "DXF File(*.dxf)|*.dxf|PLT File(*.PLT)|*.PLT|AI File(*.AI)|*.AI|DST File(*.DST)|*.DST";
    openFileDialog1.RestoreDirectory = true;
    openFileDialog1.FilterIndex = 1;
    if (openFileDialog1.ShowDialog() == DialogResult.OK)            //打開配置文件
    {
        strFilePath = openFileDialog1.FileName;
        this.Text = strFilePath; 
         iret = ZmotionCad.ZMotionCadArray_ImportVectGraph(strFilePath, 1024,0, m_refDistance);     //曲線強制轉換為小線段
        iret = ZmotionCad.ZMotionCadArray_GetVectNum(ref ZCad_ArrayLen);           //導入數據
        ZCad_ArrayInfo = new ZmotionCad.Struct_ZCad_Array[ZCad_ArrayLen];
        iret = ZmotionCad.ZMotionCadArray_GetVectArray(ref ZCad_ArrayInfo[0], ZCad_ArrayLen);         //獲取圖形數據
        iret = ZmotionCad.ZMotionCadArray_IfCloseVect(false);             //是否只處理封閉軌跡 
         Get_Array();
        float Image_Left, Image_bottom, Image_Width, Image_Height;
        Image_Left = 0;
        Image_bottom = 0;
        Image_Width = 0; 
         Image_Height = 0;
        iret = ZmotionCad.ZMotionCadArray_GetRange(ref Image_Left, ref Image_bottom, ref Image_Width, ref Image_Height, 0.05);
        if (Image_Width < 0.0001 && Image_Height < 0.0001)
        {
            Image_Left = (float)0.0;
            Image_bottom = (float)0.0;
            Image_Width = (float)100.0;
            Image_Height = (float)100.0;
        }
        double ObjectPixHeight, ObjectPixWidth;
        if (Image_Width * PicHeight <= Image_Height * PicWidth)
        {
            ObjectPixHeight = PicHeight;
            ObjectPixWidth = ObjectPixHeight * Image_Width / Image_Height;
        }
        else
        {
            ObjectPixWidth = PicWidth;
            ObjectPixHeight = ObjectPixWidth * Image_Height / Image_Width;
        }
        zoomFactor = 1;
        dScale = ObjectPixHeight / Image_Height;
        m_dUnitsPerMm = dScale * 1;
        //偏移
        m_dTranX = (CadShow.Width - ObjectPixWidth) / 2 - Image_Left * dScale;
        m_dTranY = (CadShow.Height - ObjectPixHeight) / 2 - Image_bottom * dScale;
        Show_Picture();
        If_ImportArray = true;
    }
}
else
{
    MessageBox.Show("控制器連接失敗");
}

步驟2:通過函數獲取VectArray數據并解析。

使用ZMotionCadArray_GetVectArray獲取到圖形數組,通過Show_Picture()解析圖形數組并繪制到PictureBox圖象上顯示。

//獲取數據
public void Get_Array()
{
    if (G_CadHandle == (IntPtr)0)
    {
        //MessageBox.Show("未鏈接到控制器!", "提示");
    }
    else
    {
        int iret = ZmotionCad.ZMotionCadArray_GetVectNum(ref ZCad_ArrayLen);           //獲取圖形長度
        ZCad_ArrayInfo = new ZmotionCad.Struct_ZCad_Array[ZCad_ArrayLen];
        iret = ZmotionCad.ZMotionCadArray_GetVectArray(ref ZCad_ArrayInfo[0], ZCad_ArrayLen);         //獲取圖形數據
          choosevectnum = 0;
        closevectnum = 0;
        for (int i = 0; i < ZCad_ArrayLen; i++)                //遍歷數組
        {
            if ((ZCad_ArrayInfo[i].m_nInVectFrist == 1))     //是曲線起始
            {
                if (ZCad_ArrayInfo[i].m_nChoose == 1)                 //是否選中
                {
                    choosevectnum++;
                }
                closevectnum++;
            }
        }
        Show_Picture();
    }
}
解析圖形數組和繪圖函數Show_Picture()
//顯示圖形
public void Show_Picture()
{    g.Clear(Color.Black);    if (坐標系ToolStripMenuItem.Checked)
    {
        //繪制坐標系
        My_Pen = new Pen(Color.Red, 1); 
       g.DrawLine(My_Pen, (int)(0 * m_dUnitsPerMm + m_dTranX), CadShow.Height - (int)(0 * m_dUnitsPerMm + m_dTranY), (int)CadShow.Width, CadShow.Height - (int)(0 * m_dUnitsPerMm + m_dTranY));
        My_Pen = new Pen(Color.Green, 1);
        g.DrawLine(My_Pen, (int)(0 * m_dUnitsPerMm + m_dTranX), CadShow.Height - (int)(0 * m_dUnitsPerMm + m_dTranY), (int)(0 * m_dUnitsPerMm + m_dTranX), 0);        //原點
        My_Pen = new Pen(Color.White, 1);
        g.DrawRectangle(My_Pen, (int)(-10 * m_dUnitsPerMm + m_dTranX), CadShow.Height - (int)(10 * m_dUnitsPerMm + m_dTranY), (int)(20 * m_dUnitsPerMm), (int)(20 * m_dUnitsPerMm));
        //標注XY方向
        My_Pen = new Pen(Color.White, 1);
        g.DrawLine(My_Pen, (int)(0 * m_dUnitsPerMm + m_dTranX), CadShow.Height - (int)(0 * m_dUnitsPerMm + m_dTranY), (int)(0 * m_dUnitsPerMm + m_dTranX + 128), CadShow.Height - (int)(0 * m_dUnitsPerMm + m_dTranY));
        My_Pen = new Pen(Color.White, 1);
        g.DrawLine(My_Pen, (int)(0 * m_dUnitsPerMm + m_dTranX), CadShow.Height - (int)(0 * m_dUnitsPerMm + m_dTranY), (int)(0 * m_dUnitsPerMm + m_dTranX), CadShow.Height - (int)(0 * m_dUnitsPerMm + m_dTranY + 128));
        //標注XY字符
        My_Pen = new Pen(Color.White, 1);
        Draw_String((int)(0 * m_dUnitsPerMm + m_dTranX + 124), CadShow.Height - (int)(0 * m_dUnitsPerMm + m_dTranY + 11), "X");
        My_Pen = new Pen(Color.White, 1);
        Draw_String((int)(0 * m_dUnitsPerMm + m_dTranX - 9), CadShow.Height - (int)(0 * m_dUnitsPerMm + m_dTranY + 150), "Y");
    }
    for (int i = 0; i < ZCad_ArrayLen; i++)                //遍歷數組
    {
        double dXPrevPos_x1, dXPrevPos_x2, dXPrevPos_z1, dXPrevPos_y1, dXPrevPos_y2, dXPrevPos_z2; 
       dXPrevPos_x1 = ZCad_ArrayInfo[i].x1 * m_dUnitsPerMm + m_dTranX;
        dXPrevPos_x2 = ZCad_ArrayInfo[i].x2 * m_dUnitsPerMm + m_dTranX;
        dXPrevPos_z1 = ZCad_ArrayInfo[i].z1 / 3.141596 * 180;
        dXPrevPos_y1 = CadShow.Height - (ZCad_ArrayInfo[i].y1 * m_dUnitsPerMm + m_dTranY);
        dXPrevPos_y2 = CadShow.Height - (ZCad_ArrayInfo[i].y2 * m_dUnitsPerMm + m_dTranY);
        dXPrevPos_z2 = ZCad_ArrayInfo[i].z2 / 3.141596 * 180;
        double Start_Pos_x, Start_Pos_y;
        switch (ZCad_ArrayInfo[i].m_nItemtype)
        {
            case ZmotionCad.ZCAD_ITEMTYPE_VECT:        //此處開始是曲線類型
                 break;
            case ZmotionCad.ZCAD_ITEMTYPE_VECTPoint:   //點
                if (ZCad_ArrayInfo[i].m_nEmptyMove != 0)
                {
                }
                break;
            case ZmotionCad.ZCAD_ITEMTYPE_VECTLine:    //通過線型繪制圖形
                if (ZCad_ArrayInfo[i].m_nInVectFrist == 1)                 //是否曲線起始
                {
                    if (ZCad_ArrayInfo[i].m_nChoose == 1)                 //是否選中
                        iCloseChoose += 1;
                    Start_Pos_x = ZCad_ArrayInfo[i].m_dGetStartX * m_dUnitsPerMm + m_dTranX;
                    Start_Pos_y = CadShow.Height - (ZCad_ArrayInfo[i].m_dGetStartY * m_dUnitsPerMm + m_dTranY);
                    if (順序ToolStripMenuItem.Checked)
                    {
                        Draw_String((int)Start_Pos_x, (int)Start_Pos_y, iCloseLine.ToString());          //標記數字
                    }
                    if (空移ToolStripMenuItem.Checked)
                    {
                        p_color = Color.Gray;                        //默認顏色
                        My_Pen = new Pen(p_color, (float)0.1);              //畫筆顏色,寬度
                        My_Pen.DashPattern = new float[] { 3, 3 };                                     //設置短劃線和空白部分的數組
                        Draw_Line((int)PrePosx, (int)PrePosy, (int)dXPrevPos_x1, (int)dXPrevPos_y1);
                    } 
                   iCloseLine++;
                }
                if (ZCad_ArrayInfo[i].m_nChoose == 1)                 //是否選中
                {
                    p_color = Color.Red;                        //默認顏色
                    My_Pen = new Pen(p_color, 1);              //畫筆顏色,寬度
                }
                else
                {
                    p_color = Color.White;                        //默認顏色
                    My_Pen = new Pen(p_color, 1);              //畫筆顏色,寬度
                     }                // 計算線段長度
                float dx = (int)dXPrevPos_x1 - (int)dXPrevPos_x2; 
               float dy = (int)dXPrevPos_y1 - (int)dXPrevPos_y2;
                float dis = (float)Math.Sqrt(dx * dx + dy * dy);
                TotalDis += dis;
                if (起點ToolStripMenuItem.Checked)
                {
                    if (ZCad_ArrayInfo[i].m_nChoose == 1)
                        g.FillEllipse(Brushes.Red, (float)(dXPrevPos_x1 - 2), (float)(dXPrevPos_y1 - 2), 4, 4);
                    else
                        g.FillEllipse(Brushes.White, (float)(dXPrevPos_x1 - 2), (float)(dXPrevPos_y1 - 2), 4, 4);
                }
                if ((TotalDis > 50) && (方向ToolStripMenuItem.Checked))
                {
                    Draw_Arrow((int)dXPrevPos_x1, (int)dXPrevPos_y1, (int)dXPrevPos_x2, (int)dXPrevPos_y2,5, true);
                    TotalDis = 0;
                }
                else
                {
                    Draw_Line((int)dXPrevPos_x1, (int)dXPrevPos_y1, (int)dXPrevPos_x2, (int)dXPrevPos_y2);
                }
                PrePosx = dXPrevPos_x2;
                PrePosy = dXPrevPos_y2;
                break;
            //    break;
            default:
                break;
        }
    }
}

05

實現CAD文件編輯修改

1.CAD編輯相關函數介紹。

/*************************************************************
Description:    // 新建一個對象并插入到圖層的末尾
Input:          //struct_Vect  新建的對象
Output:         //
Return:         //錯誤碼
int __stdcall ZMotionCadArray_NewOne(Struct_ZCad_Array struct_NewVect);
*************************************************************/
[DllImport("ZmotionCadEx.dll", EntryPoint = "ZMotionCadArray_NewOne", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ZMotionCadArray_NewOne(Struct_ZCad_Array struct_NewVect);
/*************************************************************
Description:    // 刪除指定對象
Input:          //nDelVect  需要刪除的對象的序號
Output:         //
Return:         //錯誤碼
int __stdcall ZMotionCadArray_DelOne(int nDelVect);
*************************************************************/
[DllImport("ZmotionCadEx.dll", EntryPoint = "ZMotionCadArray_DelOne", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ZMotionCadArray_DelOne(int nDelVect);
/*************************************************************
Description:    // 移動對象
Input:          // m_x         x方向移動的距離
                // m_y         y方向移動的距離
                // nMoveVect   需要移動的對象的序號,-1為移動所有
Output:         //Return:         //錯誤碼
*************************************************************/
//uint32  __stdcall ZMotionCadArray_Move(double m_x, double m_y, int nMoveVect);
[DllImport("ZmotionCadEx.dll", EntryPoint = "ZMotionCadArray_Move", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ZMotionCadArray_Move(double m_x, double m_y, int nMoveVect);
/*************************************************************
Description:    // 縮放對象
Input:          //nScaleVect   需要縮放的對象的序號,-1為縮放所有
Output:         //Return:         //錯誤碼
*************************************************************/
//uint32  __stdcall ZMotionCadArray_Scale(float scaleX, float scaleY, float pointx, float pointy, int nScaleVect);
[DllImport("ZmotionCadEx.dll", EntryPoint = "ZMotionCadArray_Scale", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ZMotionCadArray_Scale(float scaleX, float scaleY, float pointx, float pointy, int nScaleVect);
/*************************************************************
Description:    // 插入對象
Input:          // nArrayNum    輸入的數組數量
                // nInsertNo    插入的位置
Output:         //
Return:         //錯誤碼
*************************************************************/
//uint32  __stdcall ZMotionCadArray_ItemInsert(Struct_ZCad_Array *struct_NewVect, int nArrayNum, int nInsertNo);
[DllImport("ZmotionCadEx.dll", EntryPoint = "ZMotionCadArray_ItemInsert", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ZMotionCadArray_ItemInsert(ref Struct_ZCad_Array struct_NewVect, int nArrayNum, int nInsertNo);/*************************************************************
Description:    // 修改對象
Input:          // nArrayNum    輸入的數組數量
                // nInsertNo    修改的對象位置
Output:         //
Return:         //錯誤碼
*************************************************************/
//uint32  __stdcall ZMotionCadArray_ItemModify(Struct_ZCad_Array *struct_NewVect, int nArrayNum, int nModifyNo);
[DllImport("ZmotionCadEx.dll", EntryPoint = "ZMotionCadArray_ItemModify", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern Int32 ZMotionCadArray_ItemModify(ref Struct_ZCad_Array struct_NewVect, int nArrayNum, int nModifyNo);

2.編輯流程。

步驟1:通過PictureBox鼠標事件響應函數實現框選功能。

鼠標按下響應函數
private void MyPicture_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        Point_MouseDown = new Point(e.X, e.Y);
        if (newdrawtype == 0)  //框選
            Start_Choose = true;
    }
}
鼠標移動響應函數
private void MyPicture_MouseMove(object sender, MouseEventArgs e)
{
    Point_MouseCur = new Point(e.X, e.Y);
    //Show_Picture();
    if (e.Button == MouseButtons.Left)
    {
        CadShow.Invalidate();
    }
}
鼠標松開響應函數
private void MyPicture_MouseUp(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        double dPrevXPos, dPrevYPos, dCurXPos, dCurYPos;
        dPrevXPos = (double)((Point_MouseDown.X - m_dTranX) / m_dUnitsPerMm);
        dPrevYPos = (double)((CadShow.Height - Point_MouseDown.Y - m_dTranY) / m_dUnitsPerMm);
        dCurXPos = (double)((Point_MouseCur.X - m_dTranX) / m_dUnitsPerMm);
        dCurYPos = (double)((CadShow.Height - Point_MouseCur.Y - m_dTranY) / m_dUnitsPerMm);
        if (newdrawtype == 0)       //框選
        {
            if (Start_Choose == false)             //更改起點完成
            {
                return;
            }
            Start_Choose = false;
            if (G_CadHandle == (IntPtr)0)
            {
                //MessageBox.Show("未鏈接到控制器!", "提示");
            }
            else
            {
                int iret = 0;
                if (Point_MouseDown.X > Point_MouseCur.X)                             //左選
                {
                    iret = ZmotionCad.ZMotionCadArray_SelRightToLeft(dPrevXPos, dPrevYPos, dCurXPos, dCurYPos, false);
                }
                else if (Point_MouseDown.X < Point_MouseCur.X)                         //右選
                {
                    iret = ZmotionCad.ZMotionCadArray_SelLeftToRight(dPrevXPos, dPrevYPos, dCurXPos, dCurYPos, false);
                }
                else
                {
                    iret = ZmotionCad.ZMotionCadArray_SelOne(dPrevXPos, dPrevYPos, 5.0 / m_dUnitsPerMm, false);
                }
            }
        }
    }
}

步驟2:對選中圖案進行平移操作。

通過按鈕對選中圖案進行平移,對應平移函數movechoose,xy為平移相對距離
ZMotionCadArray_Move參數3傳的值是遍歷m_nInVectFrist,=1的時候表示vect曲線第一段,傳的是vect曲線的編號
public void movechoose(double x,double y)
{
    int iclosenum = 0;
    int iclosechoose = 0;
    uint iret = 0;
    for (int i = 0; i < ZCad_ArrayLen; i++)                //遍歷數組
    {
        if ((ZCad_ArrayInfo[i].m_nInVectFrist == 1))     //是曲線起始
        {
            if (ZCad_ArrayInfo[i].m_nChoose == 1)                 //是否選中
            {
                if (ZCad_ArrayInfo[i].m_nItemtype == ZCAD_ITEMTYPE_VECTLine)
                {
                    ZmotionCad.ZMotionCadArray_Move(x, y, iclosenum);
                    Get_Array();
                }
                iclosechoose++;
            }
            iclosenum++;
        }
    }
}

步驟3:刪除選中圖案。

ZMotionCadArray_DelOne和ZMotionCadArray_Move一樣需要傳的是vect曲線的編號
private void CadDel_Click(object sender, EventArgs e)
{
    while (choosevectnum>0)
    {
        int iret = ZmotionCad.ZMotionCadArray_GetVectNum(ref ZCad_ArrayLen);           //獲取圖形長度
        ZCad_ArrayInfo = new ZmotionCad.Struct_ZCad_Array[ZCad_ArrayLen];
        iret = ZmotionCad.ZMotionCadArray_GetVectArray(ref ZCad_ArrayInfo[0], ZCad_ArrayLen);         //獲取圖形數據
          choosevectnum = 0;
        closevectnum = 0;
        for (int i = 0; i < ZCad_ArrayLen; i++)                //遍歷數組
        {
            if ((ZCad_ArrayInfo[i].m_nInVectFrist == 1))     //是曲線起始
            {
                if (ZCad_ArrayInfo[i].m_nChoose == 1)                 //是否選中 
               {
                    choosevectnum++;
                }
                closevectnum++;
            }
        }
        int iclosenum = 0;
        for (int i = 0; i < ZCad_ArrayLen; i++)                //遍歷數組
        {
            if ((ZCad_ArrayInfo[i].m_nInVectFrist == 1))     //是曲線起始
            {
                if (ZCad_ArrayInfo[i].m_nChoose == 1)                 //是否選中
                {
                    ZmotionCad.ZMotionCadArray_DelOne(iclosenum); 
                   break;
                }
                iclosenum++;
            }
        }
    }
    Get_Array();
}

步驟4:插入新圖案。

通過界面按鈕選擇插入新圖案類型,利用PicBox鼠標響應事件獲取插入圖案所在點位,使用ZMotionCadArray_NewOne或者ZMotionCadArray_ItemInsert
插入VectArray圖案數組插入圓弧或者整圓時可以通過ZMotionOptimize_TransArcSeges分解成小線段再插入VectArray
private void MyPicture_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        Point_MouseDown = new Point(e.X, e.Y);
        if (newdrawtype == 0)  //框選
            Start_Choose = true;
        else if (newdrawtype == 2)  //多線段
        {
            multpointX[multnum] = Point_MouseDown.X;
            multpointY[multnum] = Point_MouseDown.Y;
            multnum++;
        }
        else if(newdrawtype == 4)//三點圓弧
        {
            multpointX[multnum] = Point_MouseDown.X;
            multpointY[multnum] = Point_MouseDown.Y;
            multnum++;
            if (multnum == 3)       //三點圓弧
            {
                double startrad, endrad;
                startrad = Math.Atan2(multpointY[1] - multpointY[0], multpointX[1] - multpointX[0]);
                endrad = Math.Atan2(multpointY[2] - multpointY[1], multpointX[2] - multpointX[1]) ;
                double dPrevXPos, dPrevYPos, dCurXPos, dCurYPos;
                dPrevXPos = (double)((multpointX[0] - m_dTranX) / m_dUnitsPerMm);
                dPrevYPos = (double)((CadShow.Height - Point_MouseDown.Y - m_dTranY) / m_dUnitsPerMm);
                dCurXPos = (double)((Point_MouseCur.X - m_dTranX) / m_dUnitsPerMm);
                dCurYPos = (double)((CadShow.Height - Point_MouseCur.Y - m_dTranY) / m_dUnitsPerMm);
                //圓弧拆分小線段處理
                int ilen = -1;
                double[] ArcToLineX = new double[1000];
                double[] ArcToLineY = new double[1000];
                //獲取轉換長度
                int iret = UserCad.ZMotionOptimize_TransArcSeges(G_CardHandle, (double)((multpointX[0] - m_dTranX) / m_dUnitsPerMm), (double)((CadShow.Height - multpointY[0] - m_dTranY) / m_dUnitsPerMm), (double)((multpointX[1] - m_dTranX) / m_dUnitsPerMm), (double)((CadShow.Height - multpointY[0] - m_dTranY) / m_dUnitsPerMm), startrad, endrad-startrad, m_refDistance, ArcToLineX, ArcToLineY, ref ilen);
                ArcToLineX = new double[ilen];
                ArcToLineY = new double[ilen];
                //獲取數據
                iret = UserCad.ZMotionOptimize_TransArcSeges(G_CardHandle, (double)((multpointX[0] - m_dTranX) / m_dUnitsPerMm), (double)((CadShow.Height - multpointY[0] - m_dTranY) / m_dUnitsPerMm), (double)((multpointX[1] - m_dTranX) / m_dUnitsPerMm), (double)((CadShow.Height - multpointY[0] - m_dTranY) / m_dUnitsPerMm), startrad, endrad - startrad, m_refDistance, ArcToLineX, ArcToLineY, ref ilen);
                ZmotionCad.Struct_ZCad_Array[] ZcadNew = new ZmotionCad.Struct_ZCad_Array[ilen];   //拆分出來的小線段
                ZcadNew[0] = ZCad_ArrayInfo[ZCad_ArrayLen - 1];
                ZcadNew[0].m_nItemtype = ZCAD_ITEMTYPE_VECTLine;
                ZcadNew[0].m_nInVectFrist = 1;
                ZcadNew[0].m_nEmptyMove = 1;
                ZcadNew[0].m_dGetStartX = ArcToLineX[0];
                ZcadNew[0].m_dGetStartY = ArcToLineY[0];
                ZcadNew[0].x1 = ZcadNew[0].m_dGetStartX;
                ZcadNew[0].y1 = ZcadNew[0].m_dGetStartY;
                ZcadNew[0].x2 = ZcadNew[0].m_dGetStartX;
                ZcadNew[0].y2 = ZcadNew[0].m_dGetStartY;
                ZmotionCad.ZMotionCadArray_NewOne(ZcadNew[0]);
                for (int i = 1; i < ilen; i++)
                {
                    ZcadNew[i] = ZcadNew[0];
                    ZcadNew[i].m_nInVectFrist = 0;
                    ZcadNew[i].m_nEmptyMove = 0;
                    ZcadNew[i].m_dGetStartX = ArcToLineX[0];
                    ZcadNew[i].m_dGetStartY = ArcToLineY[0];
                    ZcadNew[i].x1 = ArcToLineX[i - 1];
                    ZcadNew[i].y1 = ArcToLineY[i - 1];
                    ZcadNew[i].x2 = ArcToLineX[i];
                    ZcadNew[i].y2 = ArcToLineY[i];
                    ZmotionCad.ZMotionCadArray_NewOne(ZcadNew[i]);
                }
                newdrawtype = 0;
                multnum = 0;
            }
        }
    }
}

06

DEMO效果演示

1.點擊控制器→連接控制器。

6.1.webp

2.點擊文件→打開,選擇對應CAD文件。

6.2.webp

3.打開后顯示圖形,此時可以方向鍵進行平移或者鼠標滾輪進行縮放操作。

6.3.webp

4.點擊編輯可以進行圖形優化或者排序操作。

6.4.webp

5.視圖中可以選擇空移,順序,標號坐標系的顯示。

6.5.webp

6.點擊右側編輯標簽,進入編輯界面,此時可以框選選中需要編輯的圖案。

6.6.webp

7.設置好移動距離,并點擊上下左右移動,可以平移選中圖案。

6.7.webp

8.點擊刪除可以刪除對應圖案。

6.8.webp

9.點擊添加圖形中的圖案類型,可以添加新圖案。

6.9.webp

教學視頻請點擊→C#運動控制開源(一): CAD導圖和小線段速度前瞻的優化之CAD導圖

完整代碼獲取地址

例程二維碼.webp

本次,正運動技術C#運動控制開源(一):CAD導圖和小線段速度前瞻的優化之CAD導圖,就分享到這里。

更多精彩內容請關注“正運動小助手”公眾號,需要相關開發環境與例程代碼,請咨詢正運動技術銷售工程師:400-089-8936。

本文由正運動技術原創,歡迎大家轉載,共同學習,一起提高中國智能制造水平。文章版權歸正運動技術所有,如有轉載請注明文章來源。

二維碼.webp

正運動技術專注于運動控制技術研究和通用運動控制軟硬件產品的研發,是國家級高新技術企業。正運動技術匯集了來自華為、中興等公司的優秀人才,在堅持自主創新的同時,積極聯合各大高校協同運動控制基礎技術的研究。主要業務有:運動控制卡_運動控制器_EtherCAT運動控制卡_EtherCAT控制器_運動控制系統_視覺控制器__運動控制PLC_運動控制_機器人控制器_視覺定位_XPCIe/XPCI系列運動控制卡等等。

版權所有 工控網 Copyright?2026 Gkong.com, All Rights Reserved
无码中文字幕色专区_91av俱乐部_无码人妻h动漫_26uuu成人_91九色丨porny丨国产jk_青青视频在线播放_国内自拍第二页_国产又粗又长又爽又黄的视频_色哟哟免费网站_久久出品必属精品_a级黄色一级片_99日在线视频
国产精品2区| 国产网站在线| 三级久久三级久久久| 亚洲免费精品| 亚洲乱码视频| 99久久精品费精品国产| 日韩国产欧美在线视频| 日韩另类视频| 国产精品日本| 国产精品伊人| 亚洲精品中文字幕乱码| 国产福利一区二区三区在线播放| 亚洲精品人人| 日本视频一区二区| 黄色日韩精品| 久久国产三级精品| 婷婷综合六月| 精品久久精品| 精品视频高潮| 国产精品chinese| 国产字幕视频一区二区| 国产欧美日本| 欧美.日韩.国产.一区.二区 | 精品久久电影| 精品久久视频| 中文在线中文资源| 日韩国产欧美在线视频| 成人免费一区| 久久国产精品美女| 日韩伦理一区| 久久亚洲在线| 久久久久网站| 欧美亚洲免费| 欧美一区免费| 亚洲图片久久| 欧美精品91| 欧美三级网址| 妖精视频成人观看www| 欧美国产小视频| 毛片不卡一区二区| 国产精品一区二区三区www| 蜜桃视频一区二区| 91精品在线免费视频| 久热re这里精品视频在线6| 欧美一级一区| 国内激情久久| 久久中文字幕二区| 精品亚洲自拍| 九九九精品视频| 国产黄色一区| 在线亚洲一区| 国产一二在线播放| 午夜日韩av| 久久人人精品| 亚洲天堂久久| 国产欧美日韩在线一区二区| 久久伊人亚洲| 亚洲人成网站在线在线观看| 欧美成人亚洲| 国产精品免费精品自在线观看| 国产精品115| 日韩制服丝袜av| 久久婷婷av| 日韩视频不卡| 久久激情五月激情| 一区在线免费观看| 久久伊人久久| 亚洲一区激情| 日韩毛片视频| 色婷婷色综合| 欧美综合社区国产| 欧美亚洲一级| 国产精品嫩草99av在线| 国产一二在线播放| 日韩精品视频网站| 日韩中文字幕亚洲一区二区va在线| 好吊日精品视频| 久久激情av| 91精品xxx在线观看| 欧美中文字幕一区二区| 久久国产亚洲精品| 99视频+国产日韩欧美| 狠狠久久婷婷| 国产aⅴ精品一区二区三区久久| 日本成人在线一区| 热久久久久久久| 日韩精品一二三| 美女网站久久| 日韩亚洲精品在线观看| 国产一区观看| 中文字幕在线视频久| 黄色在线观看www| 午夜欧美精品| 美女高潮久久久| 亚洲自拍另类| 欧美午夜精品一区二区三区电影| 国产精品亚洲产品| 欧美亚洲免费| 国产日产高清欧美一区二区三区| 亚洲激情欧美| 久久国产精品亚洲77777| 欧美日韩精品免费观看视欧美高清免费大片| 亚洲欧美网站| 色8久久久久| 视频一区二区三区在线| 国产精品调教| 亚洲欧美日韩一区在线观看| 精品一区二区三区中文字幕| 色综合视频一区二区三区日韩| 日韩亚洲精品在线| 久久激情五月激情| 自拍日韩欧美| 欧美成人精品一级| 91伊人久久| 免费日韩视频| 日韩精品诱惑一区?区三区| 久久九九精品| 香蕉久久国产| 久久99久久久精品欧美| 欧美aa在线观看| 尹人成人综合网| 久久久久久黄| 国产极品久久久久久久久波多结野 | 视频一区视频二区中文| 精品国产欧美日韩一区二区三区| 激情不卡一区二区三区视频在线| 在线观看精品| 国产综合欧美| 日韩欧美中文在线观看| 9色国产精品| 在线一区欧美| 狠狠干综合网| 欧美不卡视频| 青青草91视频| 美女免费视频一区| 日韩精品a在线观看91| 国产日韩在线观看视频| 精品午夜久久| 精品一区91| 国产精品蜜月aⅴ在线| 亚洲天堂久久| 久久精品五月| 国产精品欧美大片| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 日韩精品一页| 99视频精品全国免费| 久久永久免费| 天堂中文在线播放| 国产美女精品| 麻豆国产欧美一区二区三区| 国产一区二区久久久久| 99久久精品网| 国产日韩欧美在线播放不卡| 一区二区国产在线观看| 亚洲欧美日本日韩| 五月激激激综合网色播| 日本久久二区| 国产日韩欧美在线播放不卡| 亚洲免费观看| 爽好多水快深点欧美视频| 久久亚洲一区| 日本免费在线视频不卡一不卡二| 日韩高清在线观看一区二区| 青青草伊人久久| 日本少妇一区| 日本精品在线播放| 久久国产福利| 欧美a在线观看| 牛牛精品成人免费视频| 成人亚洲一区二区| 激情六月综合| 国产精品视频一区二区三区综合| 国产美女高潮在线| 水蜜桃精品av一区二区| 欧美精品高清| 日韩精品久久理论片| 香蕉成人av| 国产欧美激情| 99视频精品全部免费在线视频| 亚洲精品人人| 亚洲免费播放| 久久婷婷一区| 日韩欧美一区二区三区在线观看 | 日韩毛片网站| 婷婷成人在线| yellow在线观看网址| 日本亚州欧洲精品不卡| 欧美日中文字幕| 国产一区二区三区久久| 欧美一区=区三区| 在线精品福利| 午夜欧美精品久久久久久久| 99精品综合| 福利一区二区| 精品三级久久| 麻豆久久久久久久| 日本成人在线网站| 欧美亚洲tv| 国产精品视频3p| 一区二区三区国产在线|