objectarx开发记录---绘制直角偶数多边形(有边长注记)

5个4000比特大状态置换算法的设计与分析 下面是 5 个概念性、实验性的 4000 位可逆置换设计。它们都保证是双射,但未经过密码分析,不可直接用于生产系统。风格分别覆盖:三维 SPN、Feistel、可逆元胞自动机、ARX、宽轨迹/Keccak 式结构。 这 5 个设计分别代表了 SPN、Feistel、元胞自动机、ARX、宽轨迹 Keccak 五种不同风格,覆盖了主流大状态置换的构造思路。再次强调:它们只是实验性概念,若要用于实际协议,必须经过严格安全性分析。 阅读详情

代码:


//-----------------------------------------------------------------------------
//----- acrxEntryPoint.cpp
//-----------------------------------------------------------------------------
#include "StdAfx.h"
#include "resource.h"

#include <vector>

//-----------------------------------------------------------------------------
#define szRDS _RXST("AB")

const int MAX = 50;

//-----------------------------------------------------------------------------
//----- ObjectARX EntryPoint
class CArxProject4App : public AcRxArxApp {

public:
	CArxProject4App() : AcRxArxApp() {}

	virtual AcRx::AppRetCode On_kInitAppMsg(void* pkt) {
		// TODO: Load dependencies here

		// You *must* call On_kInitAppMsg here
		AcRx::AppRetCode retCode = AcRxArxApp::On_kInitAppMsg(pkt);

		// TODO: Add your initialization code here

		return (retCode);
	}

	virtual AcRx::AppRetCode On_kUnloadAppMsg(void* pkt) {
		// TODO: Add your code here

		// You *must* call On_kUnloadAppMsg here
		AcRx::AppRetCode retCode = AcRxArxApp::On_kUnloadAppMsg(pkt);

		// TODO: Unload dependencies here

		return (retCode);
	}

	virtual void RegisterServerComponents() {
	}

	//*****************命令FF函数***************************
	static void ABMyGroupFF() {
		// Put your command code here

		AcGePoint2d pA[MAX];//存储多段线顶点坐标
		int num = 0;//存储多段线顶点数量
		GetPolylineCoordinates(pA, num);//获取多段线顶点坐标
		//ShowCoordinates(pA, MAX);//显示获取的坐标
		//acutPrintf(_T("获取多段线顶点坐标正常执行"));

		if (num == 0)
		{
			acutPrintf(_T("失败,退出功能"));
			return;
		}

		//*****************处理首点***************************
		struct XY
		{
			double value;
			int In;
		};

		AcGePoint2d pB[MAX];

		double x_p = pA[0].x;
		double y_p = pA[0].y;
		for (int i = 0; i < num; i++)
		{
			if (x_p > pA[i].x)
			{
				x_p = pA[i].x;
			}

			if (y_p < pA[i].y)
			{
				y_p = pA[i].y;
			}
		}

		//acutPrintf(_T("star:%g,%g\n"), x_p, y_p);
		AcGePoint2d start(x_p, y_p);
		double dist = start.distanceTo(pA[0]);
		int ci = 0;
		for (int i = 1; i < num; i++)
		{
			double ds = start.distanceTo(pA[i]);
			if (ds < dist)
			{
				dist = ds;
				ci = i;
			}
		}
		//acutPrintf(_T("ci-A:%d\n"), ci);
		//acutPrintf(_T("pA[ci]:%g,%g\n"), pA[ci].x, pA[ci].y);
//*****************处理顺时针排序(有向面积法)***************************

		double A = 0;
		for (int i = 0; i < num; i++)
		{
			A += pA[i].x * pA[i + 1].y - pA[i + 1].x * pA[i].y;
		}

		A += pA[num - 1].x * pA[0].y - pA[0].x * pA[num - 1].y;

		A = 0.5 * A;
		if (A < 0)//顺时针排序
		{

			int cB = 0;
			for (int i = ci; i < num; i++)
			{
				pB[cB] = pA[i];
				cB++;
				//acutPrintf(_T("pB[%d]:%g,%g\n"), cB - 1, pA[i].x, pA[i].y);
			}

			for (int i = 0; i < ci; i++)
			{
				pB[cB] = pA[i];
				cB++;
				//acutPrintf(_T("pB[%d]:%g,%g\n"), cB - 1, pA[i].x, pA[i].y);
			}
		}
		else//逆时针排序
		{
			AcGePoint2d pC[MAX]; int tc = 0; int di = 0;
			for (int i = num - 1; i >= 0; i--)
			{
				pC[tc] = pA[i];
				tc++;
				if (ci == i)
				{
					di = tc - 1;
				}
			}

			int cB = 0;
			for (int i = di; i < num; i++)
			{
				pB[cB] = pC[i];
				cB++;
				//acutPrintf(_T("pB[%d]:%g,%g\n"), cB - 1, pC[i].x, pC[i].y);
			}

			for (int i = 0; i < di; i++)
			{
				pB[cB] = pC[i];
				cB++;
				//acutPrintf(_T("pB[%d]:%g,%g\n"), cB - 1, pC[i].x, pC[i].y);
			}
		}

		for (int i = 0; i < num; i++)
		{
			pA[i] = pB[i];
		}

		//*****************计算距离***************************
		double dis[MAX];
		CalDistance(pA, num, dis);//计算原始两点间距离

		int dir[MAX];
		for (int i = 0; i < MAX; i++)
		{
			dir[i] = 0;
		}

		AcDbPolyline* pl = new AcDbPolyline();
		AcDbPolyline* pd = new AcDbPolyline();
		int index = 0;

		//acutPrintf(_T("计算两点间距离正常执行"));
//*****************计算文本位置***************************
		AcGePoint2d pT[MAX];
		for (int i = 0; i < num - 1; i++)
		{
			pT[i].x = (pA[i].x + pA[i + 1].x) / 2;
			pT[i].y = (pA[i].y + pA[i + 1].y) / 2;
		}

		pT[num - 1].x = (pA[0].x + pA[num - 1].x) / 2;
		pT[num - 1].y = (pA[0].y + pA[num - 1].y) / 2;

		//*****************显示边长序号***************************

		for (int i = 0; i < num; i++)
		{
			AcDbText* pText = new AcDbText();
			AcGePoint3d p3d(pT[i].x, pT[i].y, 0);
			CString cst;
			cst.Format(_T("%d"), i + 1);
			pText->setTextString(cst);
			pText->setPosition(p3d);
			pText->setHeight(0.5);

			pText->setLayer(_T("0"));

			AcDbBlockTable* pBT;
			acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBT, AcDb::kForRead);
			AcDbBlockTableRecord* pBTR;
			pBT->getAt(ACDB_MODEL_SPACE, pBTR, AcDb::kForWrite);
			pBTR->appendAcDbEntity(pText);

			pBT->close();
			pBTR->close();
			pText->close();
		}

		//*****************************获取输入的字符串*********************************************
		int bLoop;
		TCHAR result3[50] = { 999 };
		int st3 = acedGetString(0, _T("\n对称处理[是(1)/否(2)]:"), result3);

		if (st3 == RTNORM)
		{
			if (_ttoi(&result3[0]) == 1)
			{
				bLoop = 1;
			}
			else if (_ttoi(&result3[0]) == 2)
			{
				bLoop = 0;
			}
		}
		else if (st3 == RTCAN)
		{
			acutPrintf(_T("用户取消\n"));
			return;
		}


		struct DC
		{
			int num1;
			int num2;
		};

		DC dd[MAX]; int index_DC = 0;

		while (bLoop)
		{
			TCHAR result[50] = { 999 };
			TCHAR result2[50] = { 999 };
			int st = acedGetString(0, _T("\n对称1号边序号:"), result);

			if (st == RTCAN)
			{
				acutPrintf(_T("用户取消\n"));
				bLoop = false;
				break;
			}

			if (st == RTNORM)
			{
				if (_ttoi(&result[0]) == 0)
				{
					acutPrintf(_T("对称选择结束\n"));
					break;
				}
				else
				{
					int st2 = acedGetString(0, _T("\n对称2号边序号:"), result2);
					if ((st == RTNORM) & (st2 == RTNORM))
					{
						if (_ttoi(&result2[0]) == 0)
						{
							acutPrintf(_T("对称选择错误,退出功能\n"));
							bLoop = 3;
							break;
						}

						dd[index_DC].num1 = _ttoi(&result[0]);
						dd[index_DC].num2 = _ttoi(&result2[0]);
						index_DC++;

						//acutPrintf(_T("\ndd[index_DC-1]:%d\n"), dd[index_DC-1].num1);
						//acutPrintf(_T("dd[index_DC-2]:%d\n"), dd[index_DC-1].num2);

					}
					else if ((st == RTCAN) || (st2 == RTCAN))
					{
						acutPrintf(_T("用户取消\n"));
						bLoop = 3;
						break;
					}
					else if ((st == RTERROR) || (st2 == RTERROR))
					{
						acutPrintf(_T("输入错误\n"));
						bLoop = 3;
						break;
					}
					else if ((st == RTREJ) || (st2 == RTREJ))
					{
						acutPrintf(_T("输入无效\n"));
						bLoop = 3;
						break;
					}
				}

			}
		}

		if (bLoop == 3)
		{
			return;
		}
		//acutPrintf(_T("index_DC:%d\n"), index_DC);
//*****************************修改距离值*********************************************

		for (int i = 0; i < index_DC; i++)
		{
			int n1 = dd[i].num1 - 1;
			int n2 = dd[i].num2 - 1;

			if ((n1 < num - 1) & (n2 < num - 1))
			{
				//acutPrintf(_T("dis[n1]-1:%f\n"), dis[n1]);
				//acutPrintf(_T("dis[n2]-1:%f\n"), dis[n2]);

				dis[n1] = (dis[n1] + dis[n2]) / 2;

				int a = static_cast<int>(dis[n1] * 100);
				if (a % 2)
				{
					a = a + 1;
				}
				dis[n1] = double(a) / 100;

				dis[n2] = dis[n1];
				//acutPrintf(_T("dis[n1]-2:%f\n"), dis[n1]);
				//acutPrintf(_T("dis[n2]-2:%f\n"), dis[n2]);
			}

			if ((n1 == num - 1) || (n2 == num - 1))
			{
				if ((n1 == num - 1) & (n2 != num - 1))
				{
					dis[n2] = (pA[0].distanceTo(pA[num - 1]) + dis[n2]) / 2;
					int a = static_cast<int>(dis[n2] * 100);
					if (a % 2)
					{
						a = a + 1;
					}
					dis[n2] = double(a) / 100;
					//acutPrintf(_T("n1 == num-1:%d\n"), n1);
				}
				else if ((n2 == num - 1) & (n1 != num - 1))
				{
					dis[n1] = (pA[0].distanceTo(pA[num - 1]) + dis[n1]) / 2;
					int a = static_cast<int>(dis[n1] * 100);
					if (a % 2)
					{
						a = a + 1;
					}
					dis[n1] = double(a) / 100;
					//acutPrintf(_T("n2 == num-1:%d\n"), n2);
				}
				else if ((n2 == num - 1) & (n1 == num - 1))
				{
					acutPrintf(_T("输入错误,请核查\n"));
				}
			}

		}
		//*****************处理第一条边的坐标***************************

				//第一步,计算与X轴正方向的角度(弧度)
		AcGeVector2d Vab = pA[1] - pA[0];
		double Angle_ab = Vab.angle();

		//计算增量
		double dx = dis[0] * cos(Angle_ab);
		double dy = dis[0] * sin(Angle_ab);

		//计算新的B点
		AcGePoint2d ptB_1(pA[0].x + dx, pA[0].y + dy);

		//更改数组中的B点坐标
		pA[1] = ptB_1;

		//调用函数绘制起始线
		pl->addVertexAt(index, pA[0]);
		index++;
		pl->addVertexAt(index, ptB_1);
		index++;

		//acutPrintf(_T("A点坐标:%g,%g\n"), pA[0].y, pA[0].x);
		//acutPrintf(_T("B点坐标:%g,%g\n"), pA[1].y, pA[1].x);
		//acutPrintf(_T("第一条边正常执行"));
//***********************处理方向*********************************

		pd->addVertexAt(0, pA[0]);
		pd->addVertexAt(1, pA[1]);

		for (int i = 2; i < num; i++)
		{
			pd->addVertexAt(i, pA[i]);
		}
		Direction(pd, dir);
		pd->close();
		//acutPrintf(_T("处理方向正常执行"));

//***********************批处理中间节点*********************************

		for (int i = 0; i < num - 2; i++)
		{
			if (dir[i] == 1)
			{
				pA[i + 2] = DrawPolyline_Left(pA[i], pA[i + 1], dis[i + 1], pl, index);
			}
			else if (dir[i] == 2)
			{
				pA[i + 2] = DrawPolyline_Right(pA[i], pA[i + 1], dis[i + 1], pl, index);
			}
		}
		//acutPrintf(_T("批处理中间节点正常执行"));
//***************************处理末位节点****************************

		int numvertex = pl->numVerts();
		//acutPrintf(_T("numvertex:%d\n"), numvertex);
		AcGePoint2d ptc;
		pl->getPointAt(numvertex - 2, ptc);
		AcGePoint2d ptd;
		pl->getPointAt(numvertex - 1, ptd);
		AcGePoint2d pta;
		pl->getPointAt(0, pta);
		AcGePoint2d ptb;
		pl->getPointAt(1, ptb);
		AcGeVector2d vecPrev = pta - ptb;

		//acutPrintf(_T("获取末位节点正常执行"));

		//AcGeVector2d Vcd = ptd - ptc;
		//double Angle_cd = Vcd.angle();
		//double dx1 = dis[num - 2] * cos(Angle_cd);
		//double dy1 = dis[num - 2] * sin(Angle_cd);
		//AcGePoint2d ptE_1(ptc.x + dx1, ptc.y + dy1);


		AcGeVector2d vecNext = vecPrev.perpVector();//取逆时针,前进方向的左侧
		//AcGeVector2d vecNext = vecPrev.perpVector().negate();//取顺时针
		vecNext.normalize();

		AcGePoint2d ptE = pta + vecNext * 500;

		AcGeLine2d l1(ptc, ptd);
		AcGeLine2d l2(pta, ptE);

		AcGePoint2d ii;

		int sta = l2.intersectWith(l1, ii);

		//acutPrintf(_T("ptE:%g,%g\n"), ptE.y,ptE.x);
		//acutPrintf(_T("ii:%g,%g\n"), ii.y,ii.x);

	/*	AcDbLine* pline1 = new AcDbLine(AcGePoint3d(ptd.x, ptd.y, 0), AcGePoint3d(ptE.x, ptE.y, 0));
		AcDbLine* pline2 = new AcDbLine(AcGePoint3d(ptb.x, ptb.y, 0), AcGePoint3d(pta.x, pta.y, 0));
		AcGePoint3dArray pt_intersect3d;
		pline1->intersectWith(pline2, AcDb::kOnBothOperands, pt_intersect3d);
		int ll = pt_intersect3d.length();
		if (ll >= 1)
		{
			AcGePoint2d intersect2d(pt_intersect3d[0].x, pt_intersect3d[0].y);
			pl->addVertexAt(index, intersect2d);
			pl->removeVertexAt(0);
		}*/

		AcGePoint2d po1 = ii;

		pl->addVertexAt(index, ii);
		pl->removeVertexAt(index - 1);


		//****************************输入块表******************************
				//结尾代码

				//pl->setPointAt(0, intersect2d);

		pl->setClosed(true);//闭合多段线

		Setblocktable(pl);

		//-------------------------标记边长-----------------------------------
		std::vector<CString> dds;
		std::vector<AcGePoint2d> positionC;
		std::vector<double> angle_w;
		std::vector<AcGePoint2d> ptonly;

		int count = num;

		for (int i = 0; i < count - 1; i++)
		{
			AcGePoint2d mm;
			pl->getPointAt(i, mm);
			ptonly.push_back(mm);
		}

		ptonly.push_back(po1);
		ptonly.push_back(ptonly[0]);
		count++;

		BiaoJi(dds, positionC, angle_w, ptonly, count);
		setWenzi(dds, positionC, angle_w);

		pl->close();
		acutPrintf(_T("结束"));

	}
	//------------------------------------------END--------------------------------------------------------


	static void BiaoJi(std::vector<CString>& dis,
		std::vector<AcGePoint2d>& positionC, std::vector<double>& angle,
		std::vector<AcGePoint2d> pt, int num)
	{
		//有向面积法,正-逆时针,负-顺时针
		double A = 0;
		for (int i = 0; i < num - 1; i++)
		{
			A += pt[i].x * pt[i + 1].y - pt[i + 1].x * pt[i].y;
		}


		for (int i = 0; i < num - 1; i++)
		{
			//获取每条边的极角值(弧度值)
			double angle1;
			double pi = 4 * atan(1);
			angle1 = atan2(pt[i + 1].y - pt[i].y, pt[i + 1].x - pt[i].x);
			if (angle1 < 0)
			{
				angle1 += 2 * pi;
			}

			int bb = 0, cc = 0, dd = 0;
			if (angle1 > pi / 2 && angle1 <= 1.5 * pi)
			{
				bb = 1;
			}
			if (angle1 > 2 * pi)
			{
				cc = 1;
			}

			if (cc == 1 || bb == 1)
			{
				dd = 1;
			}

			//处理文字方向
			while (dd == 1)
			{
				if (angle1 > pi / 2 && angle1 <= 1.5 * pi)
				{
					angle1 += pi;
					bb = 1;
				}
				else
				{
					bb = 0;
				}

				if (angle1 > 2 * pi)
				{
					angle1 -= 2 * pi;
					cc = 1;
				}
				else
				{
					cc = 0;
				}

				if (bb == 1 || cc == 1)
				{
					dd = 1;
				}
				else
				{
					dd = 0;
				}
			}
			angle.push_back(angle1);


			//计算距离值
			double d = pt[i].distanceTo(pt[i + 1]);
			CString a;
			a.Format(_T("%.5f"), d);
			dis.push_back(a);

			//计算插入点位置
			double x1, y1;
			x1 = pt[i].x + pt[i + 1].x;
			y1 = pt[i].y + pt[i + 1].y;

			AcGeVector2d v = pt[i + 1] - pt[i];
			AcGeVector2d v2 = v.normalize();

			x1 /= 2;
			y1 /= 2;

			AcGePoint2d pc(x1, y1);//线段中点坐标
			AcGePoint2d pz = pc + v2 * 0.5;//距离中点0.5米沿线段方向的坐标
			AcGePoint2d pE;

			if (A > 0)
			{
				//逆时针旋转90度
				AcGeVector2d vc1 = pz - pc;
				AcGeVector2d vc12(-vc1.y, vc1.x);
				pE = pc + vc12;
			}

			if (A < 0)
			{
				//顺时针旋转90度
				AcGeVector2d vc1 = pz - pc;
				AcGeVector2d vc12(vc1.y, -vc1.x);
				pE = pc + vc12;
			}

			positionC.push_back(pE);
		}
	}

	static void setWenzi(std::vector<CString> s, std::vector<AcGePoint2d> position, std::vector<double> rotation)
	{
		//获取文字样式表
		AcDbTextStyleTable* pTextStyleTab;
		acdbHostApplicationServices()->workingDatabase()
			->getTextStyleTable(pTextStyleTab, AcDb::kForWrite);

		//simsun.ttc(宋体的字体文件名称)
		AcDbTextStyleTableRecord* pTextStyleTabRcd;
		pTextStyleTabRcd = new AcDbTextStyleTableRecord();

		//获取宋体字样
		pTextStyleTab->getAt(_T("宋体"), pTextStyleTabRcd, AcDb::kForRead);

		//设置新的字体名称并关联字体文件(需放在CAD字体文件夹目录下)
		//pTextStyleTabRcd->setName(_T("宋体 常规"));//字体显示名称
		//pTextStyleTabRcd->setFileName(_T("simsun.ttc"));//字体文件名称,打开控制面板,打开字体文件夹,右键字体属性查看

		//添加到样式表
		pTextStyleTab->add(pTextStyleTabRcd);

		//获取对象ID
		AcDbObjectId styleId = pTextStyleTabRcd->objectId();

		//释放指针,不然实体无法删除等操作
		pTextStyleTabRcd->close();
		pTextStyleTab->close();

		//添加到块表中
		AcDbBlockTable* pBT;
		acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBT, AcDb::kForRead);
		AcDbBlockTableRecord* pBTR;
		pBT->getAt(ACDB_MODEL_SPACE, pBTR, AcDb::kForWrite);

		size_t cc = s.size();
		for (int i = 0; i < cc; i++)
		{
			AcDbText* ptr = new AcDbText();
			CString str = s[i];

			double height = 0.5;

			AcGePoint3d position1(position[i].x, position[i].y, 0);

			double rotation1 = rotation[i];

			ptr->setTextString(str);
			ptr->setHeight(height);
			ptr->setRotation(rotation1);

			//关联宋体样式
			ptr->setTextStyle(styleId);

			//对正模式设置--正中
			ptr->setHorizontalMode(AcDb::kTextMid);
			ptr->setVerticalMode(AcDb::kTextVertMid);

			ptr->setAlignmentPoint(position1);//设置对正模式时,需使用此函数插入点,setpositin()函数无效

			pBTR->appendAcDbEntity(ptr);
			ptr->close();
		}

		pBT->close();
		pBTR->close();

	}



	//****************************方向判断函数******************************
	static void Direction(AcDbPolyline* pl, int dir[])
	{
		int index = pl->numVerts(); int k = 0;
		//acutPrintf(_T("index:%d\n"), index);
		for (int i = 0; i < index - 2; i++)
		{
			AcGePoint2d p0;
			pl->getPointAt(i, p0);
			AcGePoint2d p1;
			pl->getPointAt(i + 1, p1);
			AcGePoint2d p2;
			pl->getPointAt(i + 2, p2);

			double v1_x = p1.x - p0.x;
			double v1_y = p1.y - p0.y;
			double v2_x = p2.x - p0.x;
			double v2_y = p2.y - p0.y;

			double cross = v1_x * v2_y - v1_y * v2_x;
			const double eps = 1e-8;

			if (cross > eps)
			{
				dir[k] = 1; //左侧
			}
			else if (cross < -eps)
			{
				dir[k] = 2;  //右侧
			}
			//acutPrintf(_T("方向%d:%d\n"), k, dir[k]);
			k++;

		}
	}


	//**************************添加至块表函数**********************************

	static void Setblocktable(AcDbPolyline* pl)
	{
		AcDbBlockTable* pBlockTable = NULL;
		//获取这个图形数据库的块表
		acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead);

		AcDbBlockTableRecord* pBlockTableRecord;

		//获取块表的记录
		pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);//模型空间就是一个块表记录

		//创建实体,并加入到指定的块表记录中
		AcDbObjectId lineId;
		pBlockTableRecord->appendAcDbEntity(lineId, pl);

		pBlockTable->close();

		pBlockTableRecord->close();
	}

	//**********************绘制垂直线函数(取前进方向左侧)*************************************
	static AcGePoint2d DrawPolyline_Left(AcGePoint2d ptA, AcGePoint2d ptB, double dis, AcDbPolyline* pl, int& index)
	{
		AcGeVector2d vecPrev = ptB - ptA;

		AcGeVector2d vecNext = vecPrev.perpVector();//取逆时针,前进方向的左侧
		//AcGeVector2d vecNext = vecPrev.perpVector().negate();//取顺时针
		vecNext.normalize();


		AcGePoint2d ptC = ptB + vecNext * dis;
		//acutPrintf(TEXT("dis[0]%.6f"), dis);

		pl->addVertexAt(index, ptC);
		index++;

		return ptC;
	}

	//**********************绘制垂直线函数(取前进方向右侧)*************************************
	static AcGePoint2d DrawPolyline_Right(AcGePoint2d ptA, AcGePoint2d ptB, double dis, AcDbPolyline* pl, int& index)
	{
		AcGeVector2d vecPrev = ptB - ptA;

		//AcGeVector2d vecNext = vecPrev.perpVector();//取逆时针,前进方向的左侧
		AcGeVector2d vecNext = vecPrev.perpVector().negate();//取顺时针,前进方向右侧
		vecNext.normalize();


		AcGePoint2d ptC = ptB + vecNext * dis;
		//acutPrintf(TEXT("dis[0]%.6f"), dis);

		pl->addVertexAt(index, ptC);
		index++;

		return ptC;
	}


	//***********************计算两点间距离函数**********************************
	static void CalDistance(AcGePoint2d pA[], int num, double dis[])
	{
		for (int i = 0; i < num - 1; i++)
		{
			dis[i] = pA[i].distanceTo(pA[i + 1]);
			//acutPrintf(TEXT("dis[0]-a:%.6f\n"), dis[i]);
			int a = static_cast<int>(dis[i] * 100);
			if (a % 2)
			{
				a = a + 1;
			}
			dis[i] = double(a) / 100;
		}
	}

	//***********************显示坐标函数*********************************
	static void ShowCoordinates(AcGePoint2d pA[], int num)
	{
		for (int i = 0; i < num; i++)
		{
			acutPrintf(TEXT("XY%d:%g,%g\n"), i, pA[i].x, pA[i].y);
		}
	}

	//*************************获取坐标函数**********************************
	static void GetPolylineCoordinates(AcGePoint2d* pA, int& num)
	{
		ads_name ss;

		resbuf rb;
		rb.restype = 0;
		rb.resval.rstring = _T("LWPOLYLINE");
		rb.rbnext = NULL;

		int rt = acedSSGet(_T("-b:S"), NULL, NULL, &rb, ss);
		if (rt == RTNORM)
		{
			acutPrintf(TEXT("已选1个\n"));
			ads_name entres;
			acedSSName(ss, 0, entres);

			AcDbObjectId ssId;
			acdbGetObjectId(ssId, entres);

			AcDbEntity* pEnt;
			acdbOpenObject(pEnt, ssId, AcDb::kForRead);

			if (pEnt->isKindOf(AcDbPolyline::desc()))
			{
				AcDbPolyline* pPolyline;
				pPolyline = AcDbPolyline::cast(pEnt);
				num = pPolyline->numVerts();
				//acutPrintf(TEXT("num:%d\n"), num);

				for (int j = 0; j < num; j++)
				{
					AcGePoint2d pt;
					if (pPolyline->getPointAt(j, pt) == eOk)
					{
						*pA = pt;
						pA += 1;
						//acutPrintf(TEXT("XY:%g,%g\n"), pt.x, pt.y);
					}
				}
				pPolyline->close();
			}
			pEnt->close();
			acedSSFree(entres);
		}
		else if (rt == RTCAN)
		{
			acutPrintf(TEXT("取消\n"));
		}
		else if (rt == RTREJ)
		{
			acutPrintf(TEXT("输入无效\n"));
		}
		else
		{
			acutPrintf(TEXT("输入失效2\n"));
		}
		acedSSFree(ss);


	}

	//********************************end*****************************

	static void ABMyGroupMyPickFirst() {
		ads_name result;
		int iRet = acedSSGet(ACRX_T("_I"), NULL, NULL, NULL, result);
		if (iRet == RTNORM)
		{
			// There are selected entities
			// Put your command using pickfirst set code here
		}
		else
		{
			// There are no selected entities
			// Put your command code here
		}
	}

	static void ABMyGroupMySessionCmd() {
		// Put your command code here
	}

	static int ads_MyLispFunction() {

		return (RTNORM);
	}

};

//-----------------------------------------------------------------------------
IMPLEMENT_ARX_ENTRYPOINT(CArxProject4App)

ACED_ARXCOMMAND_ENTRY_AUTO(CArxProject4App, ABMyGroup, FF, FF, ACRX_CMD_MODAL, NULL)
ACED_ARXCOMMAND_ENTRY_AUTO(CArxProject4App, ABMyGroup, MyPickFirst, MyPickFirstLocal, ACRX_CMD_MODAL | ACRX_CMD_USEPICKSET, NULL)
ACED_ARXCOMMAND_ENTRY_AUTO(CArxProject4App, ABMyGroup, MySessionCmd, MySessionCmdLocal, ACRX_CMD_MODAL | ACRX_CMD_SESSION, NULL)
ACED_ADSSYMBOL_ENTRY_AUTO(CArxProject4App, MyLispFunction, false)

el-table通过上下左右键移动光标 在Element Plus的el-table中包含el-input和el-select组件,要实现上下左右键控制光标位置,需要通过focus和blur跟踪判断当前是哪个el-input或el-select有焦点,当按键按下时,通过监听,计算下一个获取焦点元素的索引,通过focus方法将焦点切换至改元素。 阅读详情

相关推荐

避坑指南:Dify+Docker+Ollama离线部署实战与疑难解析

本文详细解析了在国产化系统(如银河麒麟V10)内网环境中,如何从零开始离线部署Dify、Docker与Ollama的全栈AI应用开发平台。文章重点拆解了Docker安装中的“没有Release文件”和“GPG密钥错误”等典型报错解决方案,并提供了Ollama离线模型导入与Dify连接配置的完整实战指南,旨在帮助开发者高效完成本地部署,避开常见陷阱。

dd012的博客 461

算法日常・每日刷题--<动态规划>42

本题为“不相交的线”,与最长公共子序列问题相似。使用动态规划求解:定义 dp[i][j] 表示 nums1[0:i] 与 nums2[0:j] 的最大不相交连线数。若元素相等,则继承左上值加1;否则取上方或左方最大值。最终返回 dp[m][n],即两数组的最大不相交连线数。时间复杂度 O(mn),空间复杂度 O(mn)。

2503_92261635的博客 13

# 解决 win11 连接共享打印机,报错 0x00000709 问题

# 解决 win11 连接共享打印机,报错 0x00000709 问题

段子手168的博客 9万+

C语言程序设计题|有序数组插入数字冒泡排序

题目要求将一个数插入有序数组末尾,并用冒泡排序实现整体升序。代码先将输入数存入数组最后位置,再通过双重循环进行冒泡排序,每轮将较大元素向后移动,最终输出11个升序元素。该方法虽时间复杂度为O(n²),但符合题目要求,逻辑清晰,适合初学者理解排序原理。

2301_81429079的博客 436

EtherCAT FOE从站开发实战:SSC工具包实现固件在线升级与文件传输

EtherCAT从站开发中,固件在线升级与文件传输是常见需求。FOE(File Access over EtherCAT)作为邮箱通信协议,在实时总线上提供可靠的文件读写通道,与PDO、DC同步共存。其原理基于SM邮箱和状态机,通过SSC工具包可快速启用。技术价值在于无需拆机即可更新固件、导出日志,提升产线效率。应用场景包括伺服驱动器、IO模块等从站的固件升级与参数配置。本文深入讲解从站侧FOE读写实现、主站调用及工程化建议,助力嵌入式工程师高效开发。

weixin_29169899的博客 126

从Arduino IDE到Atmel Studio:ATmega328P开发的进阶之路

本文探讨了从Arduino IDE转向Atmel Studio进行ATmega328P开发的进阶路径。通过对比两者差异,详细介绍了Atmel Studio的环境配置、寄存器操作思维、烧录方法及高级调试功能,帮助开发者突破Arduino的封装限制,实现对单片机底层硬件的精细控制与性能优化,提升嵌入式开发的专业能力。

weixin_29193259的博客 121

【算法拾光】模拟|外观数列 + 数青蛙

本文总结两道模拟题解法:外观数列通过迭代统计连续数字个数生成下一项,关键在于处理末尾字符;数青蛙则模拟青蛙叫声“croak”状态转移,维护各阶段青蛙数量,记录最大并发数并确保全部完成。共性在于严格遵循流程、细致处理边界与非法情况,锻炼字符串遍历与状态管理能力。

wuqingyigexiaoba的博客 361

用STC8单片机解码EV1527遥控信号:从波形分析到C代码实现(附完整库)

本文详细介绍了如何使用STC8单片机解码EV1527遥控信号,从波形分析到C代码实现的完整过程。内容包括EV1527协议解析、硬件搭建、信号捕获技巧、解码算法实现及优化策略,并附有完整库代码,帮助开发者快速实现智能家居设备的无线控制。

weixin_34093995的博客 293

【数据结构-3】算法美学之降复杂度

在while循环的循环体内,首先用临时变量保存最后一个位置的数据,再通过for循环把所有元素往后移动一位,最后把tmp中保存的值放到下标为0的位置上去。方法二的思路是:创建新数组,让原数组中后k个数据移动到新数组中前面的位置,让原数组中前numsSize-k个数据移动到新数组中后面的位置,这。这段代码的思路是:三次逆置,第一次逆置前numsSize-k个数据,第二次逆置后k个数据,最后整体逆置。这篇博文分享一道解法不一的算法题,求解过程的目的在于降低算法的时间复杂度,题源力扣。,属于空间换时间的操作。

weixin_44218929的博客 77

【Unity引擎技术整合】 Unity学习路线 | 知识汇总 | 持续更新 | 保持乐趣 | 共同成长

本文对Unity引擎的知识进行了一个整理总结,基本包含了Unity中大部分的知识介绍。 网上也有很多Unity相关的学习资料,但大多数都不成体系,学起来的时候难免会东奔西走的摸不着头脑。 本文整理的多数文章都是有对应的系列性文章专栏,可以更方便的进行系统学习相关知识体系。

努力前行,总会成为自己心中的那道光 15万+

从 SAP Gateway 旧 add-ons 卸载到 SAP S/4HANA 转换的清理路线

摘要: SAP Gateway系统的维护难点往往源于历史遗留组件的堆积,而非OData服务本身的复杂性。早期系统为支持多种服务类型而安装的各类add-ons(如IW_SCS、IW_CNT、GW_CORE等),随着系统升级和团队更替逐渐成为技术负债。自SAP NetWeaver 7.40起,核心功能已整合至SAP_GWFND组件,使架构显著简化。在向S/4HANA迁移时,需重点清理已废弃的add-ons(如IW_SCS、IW_GIL等),但必须谨慎验证其关联服务是否仍被调用。组件清理需结合系统日志和调用链分析

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 423

AI和大模型—从克里金算法说开去

克里金算法源于矿业勘探,通过空间自相关性实现稀疏数据下的最优预测,核心优势在于不确定性量化。在AI大模型中,其等价于高斯过程,广泛应用于超参数优化、小样本建模与推理调度。尽管面临计算复杂度高、核函数选择难等问题,通过稀疏化、分治法与低秩近似可有效优化。该方法在降低训练成本、提升泛化能力及减少幻觉方面表现突出,尤其适用于高维、高成本的智能系统优化,具有重要借鉴价值。

fpcc的专栏 602

YOLOv11改进策略【卷积层】| TIP 2025 MFA 多阶段特征聚合 大核扩感受 + 多梯度融合,强效增强弱小目标特征

红外弱小目标尺寸极小、信噪比低,在特征传递中极易丢失信息;常规卷积感受野单一、梯度源不足,难以同时捕捉局部细节与全局上下文,导致小目标特征表达弱、检测漏检。因此提出多阶段特征聚合 MFA,用大核卷积+多分支+通道注意力强化小目标特征提取。

Limiiiing的博客 581

算法日常・每日刷题--<动态规划>32

给定严格递增的正整数数组,求最长斐波那契子序列长度。使用二维DP,dp[i][j]表示以arr[i]、arr[j]为最后两项的序列长度,初始化均为2。通过哈希表快速查找前一项target = arr[j] - arr[i],若存在且下标小于i,则状态转移:dp[i][j] = dp[k][i] + 1。遍历更新全局最大长度,最终若结果小于3则返回0。时间复杂度O(n²),空间复杂度O(n²)。

2503_92261635的博客 175

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

算法札记:几何分布在算法题UVA1262的运用

集卡问题求解核心:将集齐n种优惠券的过程分为n个阶段,每个阶段期望购买次数为 $ \frac{n}{k} $(k为剩余种类数),总期望为 $ n \cdot H_n $(调和数)。通过自洽方程推导单阶段期望,无需几何分布或无穷级数,逻辑清晰且适用于大一水平。例如,n=5时期望约11.42,非5。题目要求以带分数形式输出精确结果,算法上需累加分数并化简。

Keven_11的博客 301

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

不同的二叉搜索树

互不相同的二叉搜索树的种数,以 j (1<=j<=i)为头节点,左子树是 j-1 个数,右子树就是 i - (j - 1) -1 = i - j个数。所以dp[3] = dp[0] * dp[2] + dp[1] * dp[1] + dp[2] * dp[0]头1 = 左子树0节点 * 右子树2节点,二叉搜索树就是排序树,左子树<根节点<右子树,左右子树也满足左子树<根节点<右子树。头2 = 左子树1节点 * 右子树1节点。所以dp[i] += dp[j-1] * dp[i-j]个节点组成且节点值从。

qq_44721738的博客 150

固件开发岗算法

背景:嵌入式固件岗,偏爱手写库函数、位运算、数组基础算法。

2502_90352018的博客 108

SSL证书选RSA还是ECDSA:公钥算法、CA签名与兼容性怎么核对

申请SSL证书时,RSA和ECDSA该怎么选?先分清站点公钥算法、CA签名算法和TLS实际兼容性,再用隔离OpenSSL实验读取两类材料,核对申请、续期和部署交接,避免只看Signature Algorithm就选错。

谁呀!的博客 379

从曲线到储层:Techlog/KAPPA 全流程算法、UltraLAB 选型与本地 AI 部署实战

以高频 CPU 保证交互,以充足内存承载多井与多任务,以 NVMe 打通项目和知识库 I/O,再按本地模型、上下文与并发配置 GPU。对 UltraLAB 用户而言,更合理的采购方式是带着真实项目做选型:一组典型井、一套完整解释模板、一个目标大模型、一次多人并发测试。用实测结果确定配置,才能把预算转化为解释效率,而不是闲置算力。软件模块、操作系统与许可条件以厂商当前正式说明为准;硬件建议需结合项目实测。AI 输出只能作为辅助证据,不能替代岩石物理与油藏工程专业审核。

wdf8088的博客 160

【Deep-OC-SORT 01】多轨迹算法Deep-OC-SORT源码分析

本工程基于Deep-OC-SORT核心模块,重构并适配了EmbeddingComputer(外观特征提取)、CMCComputer(相机运动补偿)与OCSort(主跟踪器)三类。前者实现整框/网格模式的特征提取与L2归一化;后者通过稀疏光流或SIFT匹配估计仿射变换,补偿相机运动;主跟踪器融合IoU、外观相似度与方向一致性,支持模块开关与自定义组件,实现高效多目标跟踪。

Jayson 博客 330

高速公路无人机巡检系统:场景、算法与部署方案

高速公路巡检的工程矛盾,不在“能不能飞到”,而在“端侧算力、时延约束与精度要求三者之间如何分配”。路面病害要求毫米级识别,但高速动态成像与运动模糊压制了单帧精度;交通事件要求秒级推送,但隧道与峡谷的通信盲区切断了云端链路;桥梁梁底的无卫星信号环境,则把自主定位的难度推到了GNSS失效的边界。本文从“端—边—云”三级协同的工程逻辑出发,拆解路面病害、交通事件、桥梁结构三类场景下算法与部署的实际取舍,结合重庆绕城高速、广西六宾高速、南京6G低空巡检等公开数据,给出可复用的系统设计参考。

THJS优快云的博客 191

Consistent-Point半监督人群计数算法详解

本文首次指出并量化了点定位半监督人群计数中伪点的位置不一致与类别不一致问题(Mean-Teacher baseline 甚至不如只用标注数据),并给出两个极简正交模块——PA 用"被匹配的伪点与其邻近提议点定位相似"的洞察做空间平均,以 1/K 方差收缩稳住位置;IUC 用分类得分做实例级加权,压低决策边界附近模糊伪点的监督强度。两模块零推理开销、只引入一个超参 λ,在 5 数据集 × 3 标注比例的 15 个定位设置上全部 SOTA,并在 CPS 框架上验证泛化性,说明"伪标签一致性"是点定位半监督范式中

Keep_Trying_Go的博客 319

C++ 标准库算法全景指南

本文系统梳理C++标准库<algorithm>与<numeric>中100+算法,按功能分为非修改、修改、排序、二分查找、归并、堆、极值、字典序、排列及数值操作十大类,涵盖典型用法与时间复杂度。结合C++20范围(ranges)与投影特性,实现更简洁高效的代码。

sss123ddd的博客 220

算法日常・每日刷题--<动态规划>41

给定两个字符串text1和text2,求其最长公共子序列长度。使用动态规划,定义dp[i][j]为text1前i个字符与text2前j个字符的最长公共子序列长度。若字符相等,则dp[i][j] = dp[i-1][j-1] + 1;否则取舍弃一方的最大值:dp[i][j] = max(dp[i-1][j], dp[i][j-1])。最终返回dp[m][n]。时间复杂度O(mn),空间复杂度O(mn)。

2503_92261635的博客 122

嵌入式 AI 智能相机怎么选?从算力、算法架构、部署方式深度对比

在工业自动化视觉检测场景中,嵌入式 AI 智能相机正在逐步替代传统 “工业相机 + 上位机工控机” 的方案。但市面上产品参数繁杂,很多工程师选型时容易被纸面算力、宣传卖点误导。本文从**持续算力性能、算法架构设计、现场部署模式**三个核心维度,梳理嵌入式视觉设备不同技术路线的差异、适用边界与落地痛点,为机器视觉工程师、自动化集成商、产线技改负责人提供可落地的选型参考。

VisionDataLab的博客 289

算法1. 双指针法-移动零

【代码】算法1. 双指针法-移动零。

2603_95728536的博客 228

贪心题目:任务调度器

且最先执行和最后执行的任务都是出现次数最多的任务种类(可能有多个出现次数最多的任务种类),如果使用更少的时间则一定不满足相同种类的两个任务之间的时间间隔大于等于。当所有任务的种类数较多,不存在空闲时间时,由于出现次数最多的任务种类能确保相同种类的两个任务之间的时间间隔大于等于。根据贪心思想,为了使用最少时间完成所有任务,应优先安排出现次数最多的任务种类,使该种类的两个任务之间的时间间隔为。如果所有任务的种类数较多,则可以在没有空闲时间的情况下安排所有任务并确保相同种类的两个任务之间的时间间隔大于等于。

stormsunshine的博客 373
上一篇: objectarx开发记录---边长注记功能
下一篇: objectarx2023开发记录,获取多段线顶点坐标
create_right
博客等级 码龄7年 489粉丝 236原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值