先来说说这段时间用AI写代码的初步感受
在过去的几天里,尝试了多款AI代码生成工具,包括Cursor、豆包MarsCode、
通义灵码TongYi、文心快码BaiduComate以及腾讯AI助手。通过对这些工具的
使用体验进行比较,我发现Cursor在代码完整度、可用性、代码质量以及界面
交互方面表现尤为出色,完胜国内其他几款AI工具。特别是在涉及到一些几何
算法库时,Cursor生成的代码几乎是唯一可用的,尽管目前还未达到理想的效果。
相比之下,国内的AI工具在处理较为复杂或语料较少的情况时,生成的回复往往
有种顾左右而言他的感觉。此外,从生成的代码来看,这些AI工具的训练数据似
乎较为陈旧,例如在OCCT库中,一些接口的变化并未被AI所了解。在生成前端
项目时,几款AI工具的表现都还不错,它们能够生成完整的框架结构,并且编译
后可以正常运行。期间曾使用Cursor生成了一个VisualLisp的语法着色插件,由
于之前对js和ts的经验较少,因此经过了几十轮对话才使其成功运行。在这个过
程中,还遇到了一个bug,导致它在两个问题上一直循环,最后不得不手动处理
才得以解决。
总的来说,AI代码生成工具在提高开发效率方面具有巨大潜力,但仍有许多改
进空间。随着技术的不断发展,相信这些工具将会变得越来越智能和实用。一旦
它们迭代成熟,估计软件开发从业人员又有大批面临再就业的困境。
Cursor+QT6.4+OCCT7.7.0+六轮对话生成的几何预览
来说说使用小技巧吧:
1. 尽可能提供详细的上下文
"生成一个登录页面"
"使用React和Tailwind CSS生成一个登录页面,需要包含邮箱验证和密码强度检查"
2. 分步骤请求
将复杂的需求拆分成小步骤:
- 先请求基础架构
- 再添加具体功能
- 最后优化细节
3. 使用迭代式开发
1. 生成初始版本
2. 审查代码
3. 要求具体的改进
4. 重复以上步骤
4. 明确技术要求
- 指定编程语言版本
- 说明依赖库要求
- 提供性能或兼容性要求
5. 提供示例
"生成一个API接口"
"按照以下格式生成一个用户注册API:
{
'endpoint': '/api/register',
'method': 'POST',
'request': {
'username': 'string',
'email': 'string'
}
}"
6. 使用代码审查
- 检查生成的代码是否符合最佳实践
- 验证错误处理
- 确保代码安全性
- 检查性能问题
7. 提供反馈
如果生成的代码不理想:
- 指出具体问题
- 解释期望的结果
- 要求特定的修改
以下是一个使用MarsCode生成的插件示例
没有经过测试,后面用Cursor改了提示+重新生成了部分代码+手动重写核心拓扑算法
提问:基于AutoCAD的ObjectARX二次开发接口开发一个一键剪切多段线的功能,输入参数有两个,一个被剪切对象集,一个修剪对象,被剪切对象集为N个多段线(可能是闭合,也可能是非闭合的),修剪对象为一条非闭合或闭合多段线,程序要根据修剪对象将被剪切对象切成几个部分,如果被剪切对象为闭合多段线,则将它切分成几个独立的闭合多段线,如果被剪切对象为非闭合多段线,则将其切为几个独立的非闭合多段线,然后输出所有结果。
MarsCode AI:
好的,根据你的需求,我将使用 C++ 和 ObjectARX 库来实现一键剪切多段线的功能。以下是一个简单的示例代码,它展示了如何使用 ObjectARX 库来处理 AutoCAD 中的实体对象。
cpp
#include
#include
#include
#include
#include
void CutPolylines(AcDbObjectIdArray& cutLines, AcDbObjectId cutLineId)
{
AcDbEntity* cutLineEnt = nullptr;
acdbOpenObject(cutLineEnt, cutLineId, AcDb::kForRead);
if (cutLineEnt->isKindOf(AcDbPolyline::desc()))
{
AcDbPolyline* cutLine = AcDbPolyline::cast(cutLineEnt);
if (cutLine->isClosed())
{
// 处理闭合多段线的剪切
for (int i = 0; i < cutlines.length i acdbentity lineent='nullptr;' acdbopenobjectlineent cutlinesi acdb::kforread if lineent->isKindOf(AcDbPolyline::desc()))
{
AcDbPolyline* line = AcDbPolyline::cast(lineEnt);
if (line->isClosed())
{
// 闭合多段线之间的剪切,将其切分成几个独立的闭合多段线
// 这里需要实现具体的剪切算法
//...
}
else
{
// 非闭合多段线与闭合多段线的剪切,将其切为几个独立的非闭合多段线
// 这里需要实现具体的剪切算法
//...
}
lineEnt->close();
delete lineEnt;
}
}
}
else
{
// 处理非闭合多段线的剪切
for (int i = 0; i < cutlines.length i acdbentity lineent='nullptr;' acdbopenobjectlineent cutlinesi acdb::kforread if lineent->isKindOf(AcDbPolyline::desc()))
{
AcDbPolyline* line = AcDbPolyline::cast(lineEnt);
if (line->isClosed())
{
// 闭合多段线与非闭合多段线的剪切,将其切为几个独立的非闭合多段线
// 这里需要实现具体的剪切算法
//...
}
else
{
// 非闭合多段线之间的剪切,将其切为几个独立的非闭合多段线
// 这里需要实现具体的剪切算法
//...
}
lineEnt->close();
delete lineEnt;
}
}
}
cutLineEnt->close();
delete cutLineEnt;
}
}
void CutPolylinesCommand()
{
AcDbObjectIdArray cutLines;
AcDbObjectId cutLineId;
// 获取用户选择的被剪切对象集和修剪对象
// 这里需要实现具体的选择逻辑
//...
CutPolylines(cutLines, cutLineId);
}
extern "C" AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch (msg)
{
case AcRx::kInitAppMsg:
acrxDynamicLinker->unlockApplication(pkt);
acrxRegisterAppMDIAware(pkt);
acutPrintf(_T("\n加载一键剪切多段线功能"));
break;
case AcRx::kUnloadAppMsg:
acutPrintf(_T("\n卸载一键剪切多段线功能"));
break;
default:
break;
}
return AcRx::kRetOK;
}
在这个示例中,CutPolylines 函数接受两个参数:一个是被剪切对象集(AcDbObjectIdArray),另一个是修剪对象(AcDbObjectId)。函数内部首先打开修剪对象,并检查它是否是一个多段线。如果是,它会进一步检查多段线是否闭合。然后,它会遍历被剪切对象集,对每个多段线进行剪切操作。剪切操作的具体实现需要根据实际需求来完成,可以使用 ObjectARX 库提供的几何操作函数来实现。
CutPolylinesCommand 函数是一个命令函数,它负责获取用户选择的被剪切对象集和修剪对象,并调用 CutPolylines 函数进行剪切操作。
acrxEntryPoint 函数是 ObjectARX 应用程序的入口点,它在应用程序加载和卸载时被调用。在这个函数中,我们注册了一个命令 CutPolylinesCommand,以便用户可以通过命令行来调用这个功能。
请注意,这个示例代码只是一个框架,你需要根据实际需求来实现具体的剪切算法和选择逻辑。
提问:Workspace // 获取用户选择的被剪切对象集和修剪对象 // 这里需要实现具体的选择逻辑 //...将这部分实现写出来
MarsCode AI:
在 ObjectARX 中,获取用户选择的对象通常涉及到与 AutoCAD 交互,以便用户可以通过图形界面选择对象。以下是一个简单的示例,展示了如何获取用户选择的被剪切对象集和修剪对象。在这个示例中,我们将使用 acedSSGet() 函数来获取用户选择的对象。
cpp
#include
#include
#include
#include
#include
void CutPolylinesCommand()
{
AcDbObjectIdArray cutLines;
AcDbObjectId cutLineId;
// 提示用户选择被剪切对象集
acutPrintf(_T("\n请选择被剪切的多段线对象:"));
ads_name ssname;
if (acedSSGet(_T(""), NULL, NULL, NULL, ssname)!= RTNORM)
{
acutPrintf(_T("\n选择对象失败!"));
return;
}
// 将选择集中的对象转换为 AcDbObjectId 数组
long sslen;
acedSSLength(ssname, &sslen);
for (long i = 0; i < sslen i ads_name ename acedssnamessname i ename acdbobjectid id acdbgetobjectidid ename cutlines.appendid acutprintf_t\n if acedssget_t null null null ssname='RTNORM)' acutprintf_t\n return acdbobjectid ads_name ename acedssnamessname 0 ename acdbgetobjectidcutlineid ename cutpolylines cutpolylinescutlines cutlineid extern c acrx::appretcode acrxentrypointacrx::appmsgcode msg void pkt switch msg case acrx::kinitappmsg: acrxdynamiclinker->unlockApplication(pkt);
acrxRegisterAppMDIAware(pkt);
acutPrintf(_T("\n加载一键剪切多段线功能"));
break;
case AcRx::kUnloadAppMsg:
acutPrintf(_T("\n卸载一键剪切多段线功能"));
break;
default:
break;
}
return AcRx::kRetOK;
}
在这个示例中,我们首先提示用户选择被剪切的多段线对象,然后使用 acedSSGet() 函数获取选择集。接着,我们遍历选择集,将每个对象转换为 AcDbObjectId 并添加到 cutLines 数组中。然后,我们提示用户选择修剪对象,并获取其 AcDbObjectId。最后,我们调用 CutPolylines 函数进行剪切操作。
请注意,这个示例代码假设用户每次只选择一个修剪对象。如果需要支持多个修剪对象,你需要相应地修改代码。此外,剪切操作的具体实现需要根据实际需求来完成,这里没有提供具体的剪切算法。
提问:将处理闭合多段线的剪切这里面的实现代码写出来
MarsCode AI:
好的,以下是处理闭合多段线剪切的示例实现代码。这里使用了
AcDbPolyline::getOffsetCurves() 方法来获取多段线的偏移曲线,然后根据这些曲线来剪切其他多段线。
cpp
// 处理闭合多段线的剪切
for (int i = 0; i < cutlines.length i acdbentity lineent='nullptr;' acdbopenobjectlineent cutlinesi acdb::kforread if lineent->isKindOf(AcDbPolyline::desc()))
{
AcDbPolyline* line = AcDbPolyline::cast(lineEnt);
if (line->isClosed())
{
// 闭合多段线之间的剪切,将其切分成几个独立的闭合多段线
AcDbVoidPtrArray offsetCurves;
cutLine->getOffsetCurves(1.0, AcDb::OffsetCurve::kBoth, offsetCurves);
for (int j = 0; j < offsetcurves.length j acdbcurve offsetcurve='AcDbCurve::cast(offsetCurves[j]);' if offsetcurve ... else ... lineent->close();
delete lineEnt;
}
}
请注意,上述代码中的 //... 部分需要根据实际需求来实现具体的剪切算法。例如,你可以使用
AcDbCurve::getClosestPointTo() 方法来找到多段线上与偏移曲线最近的点,然后根据这些点来分割多段线。
此外,由于
AcDbPolyline::getOffsetCurves() 方法返回的是 AcDbVoidPtrArray,你需要将其转换为 AcDbCurve* 数组来使用。在使用完这些曲线后,记得释放它们所占用的内存。
最后,记得在实现剪切算法时考虑到所有可能的情况,例如多段线的自相交、与修剪对象的重叠等。