ARX测试_绘制道路横断面

本文迁移自本人网易博客,写于2011年1月12日,ARX测试_绘制道路横断面 - lysygyy的日志 - 网易博客 (163.com)

1、已提供道路的图形,获取用户输入的两点,并在两点间画一条虚线。

计算这条直线与多少条直线相交,若数量不等于7,提示用户,非二板块道路并返回。

//获取用户输入点

ads_point pt1, pt2;

if (acedGetPoint(NULL, "请选择一个点:", pt1) != RTNORM)

{

return;

}

//以第一点为基点,从用户处获得第二点

if (acedGetPoint(pt1, "请选择一个点:", pt2) != RTNORM)

{

return;

}

//创建直线

AcDbLine *pLine = new AcDbLine(asPnt3d(pt1), asPnt3d(pt2));

//设置线性为虚线

char linetype[30];

strcpy(linetype, "DASHED");

AcDbLinetypeTable *pLinetypeTbl;

AcDbObjectId ltId;

acdbCurDwg()->getLinetypeTable(pLinetypeTbl, AcDb::kForRead);

if ((pLinetypeTbl->getAtlinetype, ltId)) != Acad::eOk)

{

pLinetypeTbl-> close();

acdbCurDwg()-> loadLineTypeFile(linetype, "acadiso.lin");

acdbCurDwg()-> getLinetypeTable(pLinetypeTbl, AcDb::kForRead);

pLinetypeTbl-> getAt(linetype, ltId);

}

pLinetypeTbl-> close();

pLine-> setLinetype(ltId);

//将虚线添加到当前数据库中

AcDbObjectId objId;

postToDatabase(pLine, objId);

//计算这条直线与多少条直线相交,并且这些直线都互相平行

//将图形中凡是与虚线相交的直线添加到组中

//创建新组

AcDbGroup *pGroup = new AcDbGroup();

//将新组添加到组字典中

AcDbDictionary *pGroupDict;

acdbHostApplicationServices()->workingDatabase()->getGroupDictionary(pGroupDict, AcDb::kForWrite);

AcDbObjectId goupId;

pGroupDict->setAt("grouptest", pGroup, groupId);

pGroupDict->close();

pGroup->close();

AcDbBlockTable pBlockTbl;

acDbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTbl, AcDb::kForRead);

AcDbBlockTableRecord *pBlockRecord;

if (pBlockTbl->getAt(ACDB_MODEL_SPACE,

pBlockTableRecord, AcDb::kForRead) == Acad::eOk)

{

pBlockTbl->close();

AcDbObject *pObj;

AcDbBlockTableRecordIterator *pIter = pBlockRecord->newIterator();

AcGePoint3dArray pointArray;

AcDbLine *pTempLine;

int i = 0;

while (!pIter->done())

{

pIter->getObject(pObj, AcDbForRead);

if (pObj->isKindOf(AcDbLine::desc())

{

//判断当前直线是否与虚线相交

AcGePoint3dArray tempArray;

pLine->intersectWith(pObj, AcDb::kOnBothOperands, tempArray) ;

if (!tempArray->isEmpty())

{

//判断当前直线是否与上一直线平行,即当前直线与上一条直线是否没有交点

if (i == 0)

{

pTempLine = pObj->copy();

}

else if (i > 0)

{

AcGePoint3dArray tempArray1;

pTempLine->intersectWith(pObj, AcDb::kOnBothOperands, tempArray1) ;

if (!tempArray1->isEmpty())

{

return;

}

pointArray->append(tempArray[i]);

pGroup->append(pObj->objectId());

pointArray[i]

pObj->close();

pTempLine =

i++;

}

}

}

else

{

pObj->close();

return;

}

pTempLine->close();

pBlockRecord->close();

pGroup->close();

//若组中实体数量不等于7,返回

if (pGroup->count() != 7)

{

return;

}

2、获取虚线与道路的交点(x坐标最小的,排序坐标点,若虚线是Y轴方向的,判断Y的大小),从该坐标点画一条粗直线,与道路线垂直。

double x;

AcGePoint3d firstPoint;

AcGePoint3dArray sortArray;

for (int i = 0; i < pointArray->length(); i ++)

{

int x1 = pointArray[i][X];

for (int j = i; j < pointArray->length(); j++)

{

if (i = j)

{

x = x1;

firstPoint = pointArray[j];

}

else

{

if (x > x1)

{

x = x1;

firstPoint = pointArray[j];

}

}

}

sortArray[i] = firstPoint;

}

//若交点数量不等于7,返回

int length = pointArray->length();

if(length != 7)

{

return;

}

//交点坐标排序后,删除最中间的点

pointArray->removeAt(length / 2);

//画一个圆,求得另外一个交点(垂足)

firstPoint = pointArray[0];

AcGePoint3d lastPoint = pointArray[length - 1];

double pX = lastPoint[X] - firstPoint[X];

double pY = lastPoint[Y] - firstPoint[Y];

AcGePoint3d centerPoint = {pX, pY, 0.0);

AcDbCircle *pCircle = new AcDbCircle();

pCircle->setCenter(centerPoint);

double r = sqrt(pX * pX / 4 + pY *pY / 4);

pCircle->setRadius(r);

AcDbObjectId ocircleId;

//将实体圆添加到块表记录中

postToDatabase(pCircle, ocircleId);

//新建一个组,将各平行线排序

//新建组的代码略,只写关键代码

//找到经过最后一个点的直线,并求圆与该直线的交点(不包含在交点数组中的点)

AcDbGroupIterator *pIter = pGroup->newIterator();

AcDbObject *pObj;

AcDbLine *pLastline;

for (; !pIter->done(); pIter->next())

{

pIter->getObject(pObj, AcDb::kForRead);

//判断lastPoint是否在该直线上

AcGePoint3dArray tempArray2;

lastPoint->intersectWith(pObj, AcDb::kOnBothOperands, tempArray2);

if (!tempArray2->isEmpty())

{

pLastLine = pObj->copy();

pObj->close();

}

}

//求圆与最后一条直线的交点

AcGePoint3d endPoint;

AcGePoint3dArray tempArray3;

pLastLine->intersectWith(pCircle, AcDb::kOnBothOperands, tempArray3);

if (tempArray3->length() < 2)

{

return;

}

if (tempArray3[0][X] == lastPoint[X] && tempArray3[0][Y] == lastPoint[Y])

{

endPoint = tempArray3[1];

}

else

{

endPoint = tempArray3[0];

}

//延伸法线(延伸长度为5),并获取到起点和终点,画粗直线

double d = 5.0;

double x1 = firstPoint[X];

double y1 = firstPoint[Y];

double x2 = endPoint[X];

double y2 = endPoint[Y];

double k = (y1 - y2) / (x1 - x2);

double b1 = y1 - k * x1;

double a = (k*k + 1);

double b = -2 * (x1 + k * y1 - k * b1);

double c = x1 * x1 + (y1 - b1) * (y1 - b1) - d * d;

double m = b * b - 4 * a * c;

if ( m < 0)

{

return;

}

double x3 = ( - b + sqrt(m)) / 2 / a;

double x4 = ( - b - sqrt(m)) / 2 / a;

double firstx;

if ( x3 > x1 && x3 > x2 || x3 < x1 && x3 < x2)

{

firstx = x3;

}

else

{

firstx = x4;

}

double firsty = k * firstx + b1;

AcGePoint3d Point1 = {firstx, firsty, 0.0);

//同样方法求得Point2,略

AcGePoint3d Point2;

//画粗直线

AcDbLine *pNewLine = new AcDbLine(Point1, Point2);

AcDbObjectId objId;

//将实体添加到块表记录中

postToDatabase(pNewLine, objId);

//将粗直线与组中各直线的交点写入一个数组中,并排序,略

AcGePoint3dArray ptArray;

//将各段距离写入一个double型数组中

double dArray[5];

for (int i = 0; i < 5; i++)

{

dArray[i] = acutDistance(ptArray[i], ptArray[i + 1]);

}

//获取用户输入的横断面名称,横断面名称必须不多于2个字符

string str;

bool flag = false;

while (!flag)

{

if (acedGetString(2, "请输入横断面名称(不多于2个字符):", &str) != RTNORM)

{

if (str == "")

{

AfxMessageBox("输入字符不能为空!");

}

else if ( str.length() > 2)

{

AfxMessageBox("名称不能多于2个字符!");

}

else if (FALSE == 遍历图形实体,判断是否有扩展数据与输入名称相同的)//没有相同名称

{

flag = TRUE;

}

}

}

}

//遍历图形中实体,判断扩展数据是否与输入的横断面名称相同

LPCTSTR szAppName = "RNAME";

TCHAR* pszRetDat;

AcDbBlockTableRecordIterator *pIterator = new AcDbBlockTableRecordIterator;

pBlockRec->newIterator(pIterator);

for (; !pIterator->done(); pIterator->step)

{

pIterator->getObject(pObj, AcDb::kForRead);

//得到指定对象、指定应用名下的扩展数据(DXF1000处)

GetXData1000(pObj, szAppName, &pszRetDat);

if (pszRetDat == str)

{

return TRUE;//名称相同

}

}

return FALSE;

//获取第一个文本的位置坐标,距离粗直线3

AcGePoint3d textPoint1;

int x1 = textPoint1[X];

int y1 = textPoint[Y];

int a = - 1 / k;

int b = y1 - a * x1;

//根据求延伸点的方法求出点坐标,略

//获取第二个文本的位置坐标,与上同,略;

AcGePoint3d textPoint2;

//将粗直线的第一个端点坐标转换为WCS

struct resbuf to, from;

from.restype = RTSHORT;

from.resval.rint = 1;//UCS

to.restype = RTSHORT;

to.resval.rint = 0; //WCS

acedTrans(asDblArray(textPoint1), &from, &to, Adesk::kFalse, asDblArray(textPoint1));

//将粗直线的第二个端点坐标转换为WCS

acedTrans(asDblArray(textPoint2), &from, &to, Adesk::kFalse, asDblArray(textPoint2));

//绘制粗直线上的第一个端点处的文字

AcDbText *PText = new AcDbText;

pText->setTextString(str);

pText->setPosition(textPoint1);

pText->setRotation(acutAngle(Point1, textPoint1));

pText->setHeight(8);

//绘制粗直线上第二个端点处的文字,略

//擦除辅助圆,虚线与其相同,略

ads_name objName;

circleName = acdbGetAdsName(&objName, objId);

acdbEntDel(objName);

4、绘制多段线,并描绘出距离。

//用户输入多段线起点

ads_point basePoint;

if (acedGetPoint(NULL, "请选择横断面的基点:", basePoint) != RTNORM)

{

return;

}

//新建一个数组,将各端点坐标值放入其中

AcGePoint2dArray *newArray = new AcGePoint2dArray;

newArray->append(basePoint);

//找到第二个端点

AcGePoint2d (newPoint);

acutPolar(basePoint, -2, 5, newPoint);

newArray->append(newPoint);

//第3个点

acutPolar(newPoint, -1, 10, newPoint);

newArray->append(newPoint);

//第4个点,距离数组

acutPolar(newPoint, 0, distArray[0], newPoint);

newArray->append(newPoint);

//第5个点

acutPolar(newPoint, -1, 1, newPoint);

newArray->append(newPoint);

//第6个点

acutPolar(newPoint, 0, distArray[1], newPoint);

newArray->append(newPoint);

//第7个点

acutPolar(newPoint, 1, 1, newPoint);

newArray->append(newPoint);

//第8个点

acutPolar(newPoint, 0, distArray[2], newPoint);

newArray->append(newPoint);

//第9个点

acutPolar(newPoint, -1, 1, newPoint);

newArray->append(newPoint);

//第10个点

acutPolar(newPoint, 0, distArray[3], newPoint);

newArray->append(newPoint);

//第11个点

acutPolar(newPoint, 1, 1, newPoint);

newArray->append(newPoint);

//第12个点

acutPolar(newPoint, 0, distArray[4], newPoint);

newArray->append(newPoint);

//第13个点

acutPolar(newPoint, 1, 10, newPoint);

newArray->append(newPoint);

//第14个点

acutPolar(newPoint, 0.5, 5, newPoint);

newArray->append(newPoint);

//绘制多段线

AcDbPolyline *pPolyline = new AcDbPolyline;

//将数组中的点添加到多段线中

for (int i = 0; i < newArray->length(); i++)

{

pPolyline->addVertexAt(i, *newArray[i], 0);

}

//新建一个组,将多段线及后面创建的直线和文本全都添加到组中

pGroup->append(pPolyline);

//获取多段线下第一条横线的起点和终点

AcGePoint3d *startPoint, *endPoint;

acutPolar(newArray[0], -1, 20, startPoint);

acutPolar(newArray[newArray->length() - 1], -1, 20, endPoint);

//创建起点到终点的直线,并将其加入组中,略

//获取多段线下第二条横线的起点和终点,距离为30,并将其加入组中,略

//获取左边第一条垂直线的起点和终点

AcGePoint3d *topPoint = (basePoint[X], newArray[1][Y], 0);

startPoint = (topPoint[X], newArray[2][Y, 0);

acutPolar(topPoint, -1, 30, endPoint);

//获取左边第二条垂直线的起点和终点

topPoint = (basePoint[X], newArray[3][Y], 0);

startPoint = (topPoint[X], startPoint[Y], 0);

acutPolar(topPoint, -1, 20, endPoint);

//获取左边第三条垂直线的起点和终点

topPoint = (basePoint[X], newArray[5][Y], 0);

startPoint = (topPoint[X], startPoint[Y], 0);

acutPolar(topPoint, -1, 20, endPoint);

//获取左边第4条垂直线的起点和终点

topPoint = (basePoint[X], newArray[7][Y], 0);

startPoint = (topPoint[X], startPoint[Y], 0);

acutPolar(topPoint, -1, 20, endPoint);

//获取左边第5条垂直线的起点和终点

topPoint = (basePoint[X], newArray[9][Y], 0);

startPoint = (topPoint[X], starPoint[Y], 0);

acutPolar(topPoint, -1, 20, endPoint);

//获取最后一条垂直线的起点和终点

topPoint = (basePoint[X], newArray[11][Y], 0);

startPoint = (topPoint[X], startPoint[Y], 0);

acutPolar(topPoint, -1, 30, endPoint);

//设置第一段距离的文本,并将其添加到组中

//获取文本位置的基点

topPoint = ((newArray[1][X] + newArray[3][X]) / 2, newArray[0][Y], 0);

acutPolar(topPoint, -1, 17, basePoint);

//文本内容为textArray[0],创建文本实体的函数略

//设置第二段距离的文本

topPoint = ((newArray[3][X] + newArray[5][X]) / 2, newArray[0][Y], 0);

acutPolar(topPoint, -1, 17, basePoint);

//设置第3、4、5段距离的文本,与上同,略

//设置总长度的文本

topPoint = ((newArray[0][X] + newArray[newArray->length() - 1]) / 2, newArray[0][Y], 0);

acutPolar(topPoint, -1, 27, basePoint);

//设置横断面的名称,A1-A1,设置其文本为粗体,高度

acutPolar(topPoint, -1,50, basePoint);

//遍历组中所有实体添加扩展数据A1

addXdata(pObj, appName, str);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值