admin 发表于 2024-3-18 19:23:58

objectArx --- 工具类

目录
一、转换类
二、数学计算类
三、几何计算类
四、字符串工具类
4.1 类定义
4.2 测试代码
五、文件操作类
5.1 类定义
5.2 测试代码
一、转换类
功能:显式转换不同数据类型
筛选器Other中添加(第(三)篇文件结构为基础)
ConvertUtil.h
#pragma once
class ConvertUtil
{
public:
        ConvertUtil();
        ~ConvertUtil();
public:
        // 2d点转换为3d点
        static AcGePoint3d ToPoint3d(const AcGePoint2d& pt, double z = 0);
        // 3d点转换为2d点
        static AcGePoint2d ToPoint2d(const AcGePoint3d& pt);

        // 角度转弧度
        static double AngleToRadian(double angle);
        // 弧度转角度
        static double RadianToAngle(double rad);
        // 整型转字符串(需要支持MFC)
        static CString ToString(int val);
        // 点坐标系转换:世界坐标系wcs->显示坐标系dcs
        static AcGePoint3d WcsPointToDcsPoint(const AcGePoint3d &point);
        // 点坐标系转换:用户坐标系ucs->世界坐标系wcs
        static AcGePoint3d UcsPointToWcsPoint(const AcGePoint3d &point);
        // 点坐标系转换:世界坐标系wcs->用户坐标系ucs
        static AcGePoint3d WcsPointToUcsPoint(const AcGePoint3d &point);
};


ConvertUtil.cpp
#include "stdafx.h"
#include "ConvertUtil.h"
#include "MathUtil.h"

ConvertUtil::ConvertUtil(){}
ConvertUtil::~ConvertUtil(){}

// 2d点转换为3d点
AcGePoint3d ConvertUtil::ToPoint3d(const AcGePoint2d& pt, double z)
{
        return AcGePoint3d(pt.x, pt.y, z);
}

// 3d点转换为2d点
AcGePoint2d ConvertUtil::ToPoint2d(const AcGePoint3d& pt)
{
        return AcGePoint2d(pt.x, pt.y);
}

// 角度转弧度
double ConvertUtil::AngleToRadion(double angle)
{
        return angle * MathUtil::PI() / 180;
}

// 弧度转角度
double ConvertUtil::RadionToAngle(double rad)
{
        return rad * 180 / MathUtil::PI();
}

// 整型转字符串(需要支持MFC)
CString ConvertUtil::ToString(int val)
{
        CString str;
        str.Format(采用T("%d"), val);
        return str;
}

// 点坐标系转换:世界坐标系wcs->显示坐标系dcs
AcGePoint3d ConvertUtil::WcsPointToDcsPoint(const AcGePoint3d &point)
{
        AcGePoint3d pt;
        struct resbuf rbFrom, rbTo;
        rbFrom.restype = RTSHORT;
        rbFrom.resval.rint = 0;
        rbTo.restype = RTSHORT;
        rbTo.resval.rint = 2;
        // 坐标系转换函数:wcs坐标、wcs标识符(0)、dcs标识符(2)、类型为点(0)、dcs坐标
        acedTrans(asDblArray(point), &rbFrom, &rbTo, 0, asDblArray(pt));
        return pt;
}

// 点坐标系转换:用户坐标系ucs->世界坐标系wcs
AcGePoint3d ConvertUtil::UcsPointToWcsPoint(const AcGePoint3d &point)
{
        AcGePoint3d pt;
        struct resbuf rbFrom, rbTo;
        rbFrom.restype = RTSHORT;
        rbFrom.resval.rint = 1;
        rbTo.restype = RTSHORT;
        rbTo.resval.rint = 0;
        // 坐标系转换函数:ucs坐标、ucs标识符(1)、wcs标识符(0)、类型为点(0)、wcs坐标
        acedTrans(asDblArray(point), &rbFrom, &rbTo, 0, asDblArray(pt));
        return pt;
}

// 点坐标系转换:世界坐标系wcs->用户坐标系ucs
AcGePoint3d ConvertUtil::WcsPointToUcsPoint(const AcGePoint3d &point)
{
        AcGePoint3d pt;
        struct resbuf rbFrom, rbTo;
        rbFrom.restype = RTSHORT;
        rbFrom.resval.rint = 0;
        rbTo.restype = RTSHORT;
        rbTo.resval.rint = 1;
        // 坐标系转换函数:wcs坐标、ucs标识符(1)、wcs标识符(0)、类型为点(0)、ucs坐标
        acedTrans(asDblArray(point), &rbFrom, &rbTo, 0, asDblArray(pt));
        return pt;
}




二、数学计算类
功能:涉及到数学类的计算
Other筛选器中添加(第(三)篇文件结构为基础)
MathUtil.h
#pragma once
class MathUtil
{
public:
        MathUtil();
        ~MathUtil();

        // 定义派值
        static double PI();
        // 判断两个双精度浮点数是否相等
        static bool IsEqual(double a, double b, double tol = 1.0E-7);
};

MathUtil.cpp
#include "stdafx.h"
#include "MathUtil.h"

MathUtil::MathUtil(){}
MathUtil::~MathUtil(){}

// 定义派值
double MathUtil::PI()
{        // 数学求派的精确方法
        return atan(1.0) * 4;
}

// 判断两个双精度浮点数是否相等,因为浮点数都是近似存储
bool MathUtil::IsEqual(double a, double b, double tol /* = 1.0E-7 */)
{        // 当两个浮点数的差小于10E-7,则判定两个浮点数相等
        return (fabs(a - b) < tol);
}



三、几何计算类
Geometry筛选器中添加(第(三)篇文件结构为基础)
Geometry.h
#pragma once
class Geometry
{
public:
        Geometry();
        ~Geometry();

public:
        // 算两点中点:下面是2d点和3d点重载
        static AcGePoint2d GetMiddlePoint(const AcGePoint2d &startPt,
                                                                          const AcGePoint2d &endPt);
        static AcGePoint3d GetMiddlePoint(const AcGePoint3d &startPt,
                                                                          const AcGePoint3d &endPt);
        // 计算相对坐标:传入基准坐标pt、x偏移量、y偏移量
        static AcGePoint3d RelativePoint(const AcGePoint3d &pt, double x, double y);
};


Geometry.cpp
#include "stdafx.h"
#include "Geometry.h"

Geometry::Geometry(){}
Geometry::~Geometry(){}

AcGePoint2d Geometry::GetMiddlePoint(const AcGePoint2d &startPt,
                                                                       const AcGePoint2d &endPt)
{        // 这是提取2d点的三个坐标值,为double类型
        double x = (startPt.x + endPt.x) *0.5;
        double y = (startPt.y + endPt.y) *0.5;
        return AcGePoint2d(x, y);
}

AcGePoint3d Geometry::GetMiddlePoint(const AcGePoint3d &startPt,
                                                                       const AcGePoint3d &endPt)
{        // 这是提取3d点的三个坐标值,为double类型
        double x = (startPt.x + endPt.x) *0.5;
        double y = (startPt.y + endPt.y) *0.5;
        double z = (startPt.z + endPt.z) *0.5;
        return AcGePoint3d(x, y, z);
}

AcGePoint3d Geometry::RelativePoint(const AcGePoint3d &pt, double x, double y)
{
        AcGePoint3d ptReturn(pt.x + x, pt.y + y, pt.z);
        return ptReturn;
}


四、字符串工具类
4.1 类定义
Other筛选器中添加(第(三)篇文件结构为基础)
StringUtil.h
#pragma once
#include <vector>

class StringUtil
{
public:
        StringUtil();
        ~StringUtil();

        // 分割字符串:传入字符串、分割符、接收分割后的字符串容器、分隔符间允许包含空字符(默认)
        static void Split(const CString &text,
                                          const ACHAR *separator,
                                          std::vector<CString>&result,
                                          bool bAddEmptyStr = true);
        // 合并字符串:传入字符串容器、分隔符,返回合并的字符串
        static CString Join(const std::vector<CString> &items, const ACHAR *spearator);
};


StringUtil.cpp
#include "stdafx.h"
#include "StringUtil.h"

StringUtil::StringUtil(){}
StringUtil::~StringUtil(){}

// 分割字符串:传入字符串、分割符、接收分割后的字符串容器、是否允许包含空字符
void StringUtil::Split(const CString &text,
                                           const ACHAR *separator,
                                           std::vector<CString>&result,
                                           bool bAddEmptyStr )
{        // 前一个索引号、当前索引号
        int prev = 0, current = 0;
        // 将传入的字符串深拷贝一个副本
        CString strCopyTxt = text;
        // 删除字符串右侧的空字符
        strCopyTxt.TrimRight(采用T(" "));
        // 如果没找到分隔符:未找到返回-1,Find见下注释
        if (strCopyTxt.Find(separator, 0) < 0)
        {        // 如果传入的字符串有长度
                if (strCopyTxt.GetLength() > 0)
                {        // 整个字符串就是唯一的分割字符串,添加进字符串容器
                        result.push采用back(strCopyTxt);
                }
                // 如果传入的字符串长度为0,啥也不添加
                return;
        }
        // 以下为至少发现一个分隔符
        // 获得字符串总长度
        int length = strCopyTxt.GetLength();
        bool bExit = false;
        // 开启无限循环:注意循环中的break语句
        while (true)
        {        // prev为起始索引值,迭代的关键,Find见下注释
                current = strCopyTxt.Find(separator, prev);
                // 循环到最后一个待分割字符串,之后无分隔符
                if (current == -1)
                {        // 将整个字符串长度赋值current,标识退出变量为真
                        current = length;
                        bExit = true;
                }

                // 取最后一个分隔符到结尾的字符串,Mid见下注释
                CString item = strCopyTxt.Mid(prev, current - prev);

                // 添加进容器的条件:每个提取的子字符串是否过滤0长度
                if (bAddEmptyStr || item.GetLength() > 0)       
                        result.push采用back(item);

                //判断退出条件
                if (bExit)        break;

                // 更新Find函数的起始索引值,要包含分隔符,否则如 1,,2 会成死循环
                CString sep = separator;
                prev = current + sep.GetLength();
        }
}

// 合并字符串:传入字符串容器、分隔符,返回合并的字符串
CString StringUtil::Join(const std::vector<CString> &items,
                                               const ACHAR *spearator)
{
        CString strResult;
        // 逐个拼接容器中的字符串
        for (int i = 0; i < items.size(); i++)
        {       
                strResult += items.at(i) + spearator;
        }
        // 删除右侧的空字符
        strResult.TrimRight(spearator);
        // 返回拼接好的字符串
        return strResult;
}



4.2 测试代码
Commands.h
#include "StdAfx.h"

void AddCommands();
void Seperate();
void Unit();

Commands.cpp
#include "StdAfx.h"
#include "Commands.h"
#include "Editor.h"
#include "StringUtil.h"

void AddCommands()
{       
        // 分割字符串
        Editor::AddCommand(L"Seperate", ACRX采用CMD采用MODAL, Seperate);
        // 合并字符串
        Editor::AddCommand(L"unit", ACRX采用CMD采用MODAL, Unit);

}
void Seperate()
{
        std::vector<CString> lines;
        ACHAR line;
        ACHAR separator;
        if (acedGetString(NULL, 采用T("\n请输入待分割内容:"), line) != RTNORM)
        {
                return;
        }
        if (acedGetString(NULL, 采用T("\n请输入分隔符:"), separator) == RTNORM)
        {
                CString str = line;
                StringUtil::Split(str, separator, lines);
        }
        for (int i = 0; i < lines.size(); i++)
        {
                acutPrintf(lines.at(i));
                acutPrintf(采用T("\n"));
        }
        acutPrintf(采用T("%d"), lines.size());
}

void Unit()
{
        std::vector<CString> lines;
        ACHAR line;
        while (acedGetString(NULL, 采用T("\n请输入待组合内容:"), line)== RTNORM)
        {
                CString temp = line;
                if (temp == 采用T("exit")) break;
                lines.push采用back(line);
        }
        CString unitline = StringUtil::Join(lines, 采用T(","));
        acutPrintf(unitline);
}




五、文件操作类
5.1 类定义
IO筛选器中添加(第(三)篇文件结构为基础)
TextFileUtil.h
#pragma once
#include <vector>
class TextFileUtil
{
public:
        TextFileUtil();
        ~TextFileUtil();

        // 覆盖式存到文件:文件名(绝对路径)、接收CString字符串容器
        static void ToFile(const ACHAR *fileName, const std::vector<CString>&lines);
        // 从文件读取:文件名(绝对路径)、输出CString字符串容器
        static bool FromFile(const ACHAR *fileName, std::vector<CString>&lines);
        // 通过对话框选择获取文件绝对路径(多选)
        static bool SelectFilePath(CStringArray & fileNameArray);
};


TextFileUtil.cpp
#include "stdafx.h"
#include "TextFileUtil.h"

TextFileUtil::TextFileUtil(){}
TextFileUtil::~TextFileUtil(){}

// 覆盖式存到文件:文件名(绝对路径)、接收CString字符串容器
void TextFileUtil::ToFile(const ACHAR *fileName, const std::vector<CString>&lines)
{        // 以下是支持MFC才有的,相当于open函数功能
        CStdioFile file(fileName, CFile::modeCreate | CFile::modeWrite | CFile::typeText);
        // 逐个读取容器中的字符串,并在每个字符串后面加换行符
        for (int i = 0; i < lines.size(); i++)
        {
                file.WriteString(lines.at(i));
                file.WriteString(采用T("\n"));
        }
        file.Close();
}

// 从文件读取:文件名(绝对路径)、输出CString字符串容器
bool TextFileUtil::FromFile(const ACHAR *fileName, std::vector<CString>&lines)
{        // 纠错函数:如果文件不存在打印
        if (PathFileExists(fileName) != TRUE)
        {
                acutPrintf(采用T("\n文件不存在!"));
                return false;
        }
        else
        {        // 首先格式化容器
                lines.clear();
                // 以读的方式打开文件
                CStdioFile file(fileName, CFile::modeRead | CFile::typeText);
                CString strLine;
                // 只要读取成功,就循环读每一行
                while (file.ReadString(strLine))
                {        // 将每一行添加到CString字符串容器
                        lines.push采用back(strLine);
                }
                return true;
        }
}

// 通过对话框选择获取文件绝对路径(多选):一些MFC语句,了解即可,重点看注释语句
bool TextFileUtil::SelectFilePath(CStringArray & fileNameArray)
{        // 构建文件过滤器
        CNavFilter *filter;
        // 过滤的注释
        LPCTSTR filterDesc[] = { 采用T("可选文件格式"), NULL };

        // 过滤的后缀名:可以在null前增加后缀
        LPCTSTR filterDWG[] = { 采用T("*.dwg"),采用T("*.dxf"), NULL };
        LPCTSTR *filterSpec[] = { filterDWG, NULL };

        CNavFilterArray gFilterArray;
        gFilterArray.RemoveAllData();

        int i = 0, j;
        while (filterSpec != NULL)
        {
                filter = gFilterArray.AddData();
                if (filter != NULL)
                {
                        filter->SetDescription(filterDesc);
                        j = 0;
                        while (filterSpec != NULL)
                        {
                                filter->Add(filterSpec);
                                j++;
                        }
                }
                i++;
        }

        fileNameArray.RemoveAll();

        CNavDataArray gDataArray;
        while (true)
        {        // 获取autoCAD的窗口句柄
                HWND acadhandle = adsw采用acadMainWnd();
                // 使句柄成为当前窗口
                ::EnableWindow(acadhandle, true);
                // 设置焦点
                ::SetFocus(acadhandle);
                // 获取MFC的主窗口
                CWnd *pWnd = CWnd::FromHandle(acadhandle);       
                CAcUiNavDialog dlg(gDataArray, gFilterArray, 0, pWnd);
                // 开启多选模式
                dlg.SetMultiSelectAllowed(true);
                // 对话框标题
                dlg.SetDialogCaption(采用T("多选对话框"));
                // 设置当前点选的文件可见缩略图
                dlg.SetPreviewPresent(true);
                dlg.SetPreviewVisible(true);

                // 如果点选了确认按钮
                if (dlg.DoModal() == IDOK)
                {
                        for (int i = 0; i < gDataArray.GetCount(); i++)
                        {
                                LPITEMIDLIST id = gDataArray.GetAt(i)->GetID();

                                // 获取并打印:每个选择到的 文件绝对路径 的 字符串
                                fileNameArray.Add(gDataArray.GetAt(i)->GetText());
                        }
                }
                // 跳出循环
                break;
        }
        if (fileNameArray.GetCount() > 0)
                return true;
        else
                return false;
}




5.2 测试代码
Commands.h
#include "StdAfx.h"

void AddCommands();
void ToFile();
void FromFile();
void SelectFile();

Commands.cpp
#include "StdAfx.h"
#include "Commands.h"
#include "Editor.h"
#include "TextFileUtil.h"


void AddCommands()
{       
        // 输出到桌面文件
        Editor::AddCommand(L"tofile", ACRX采用CMD采用MODAL, ToFile);
        // 从桌面文件输入
        Editor::AddCommand(L"fromfile", ACRX采用CMD采用MODAL, FromFile);
        // 打印选择文件路径
        Editor::AddCommand(L"showpath", ACRX采用CMD采用MODAL, SelectFile);

}
void ToFile()
{
        std::vector<CString> lines;
        ACHAR line;
        while (acedGetString(NULL, 采用T("\n请输入行内容:"), line) == RTNORM)
        {
                CString str = line;
                lines.push采用back(str);
        }
        TextFileUtil::ToFile(采用T("C:\\Users\\Administrator\\Desktop\\test.txt"), lines);
}

void FromFile()
{
        std::vector<CString> lines;
        // 包含纠错函数:打开失败情况
        TextFileUtil::FromFile(采用T("C:\\Users\\Administrator\\Desktop\\test.txt"), lines);
        for (int i = 0; i < lines.size() ; i++)
        {
                acutPrintf(lines.at(i));
                acutPrintf(采用T("\n"));
        }
}

void SelectFile()
{
        CStringArray fileNamePath;
        bool isseletct = TextFileUtil::SelectFilePath(fileNamePath);
        if (!isseletct)
        {
                return;
        }
        // 遍历cstringArray每一项
        for (int i = 0; i < fileNamePath.GetCount(); i++)
        {        // Cstring定位和打印方法
                CString filepath = fileNamePath.GetAt(i);
                acutPrintf(采用T("\n文件路径为:%s"), filepath);
        }
}





showpath命令效果

页: [1]
查看完整版本: objectArx --- 工具类