Пересечение с Другими примитивами
IntersectWith () функция имеет две формы:
virtual Acad::ErrorStatus
intersectWith(
const AcDbEntity* ent,
AcDb::Intersect intType,
AcGePoint3dArray& points,
int thisGsMarker = 0,
int otherGsMarker = 0) const;
virtual Acad::ErrorStatus
intersectWith(
const AcDbEntity* ent,
AcDb::Intersect intType,
const AcGePlane& projPlane,
AcGePoint3dArray& points,
int thisGsMarker = 0,
int otherGsMarker = 0) const;
Первая форма intersectWith () функциональные испытания на простое пересечение двух объектов. Вторая форма вычисляет пересечение на проекционную плоскость. Однако, обе функции возвращают перекрестные пункты{*точки*} на объекте непосредственно.
Использовать проекционную плоскую форму intersectWith () функция
1 Проектируют ваш объект и объект параметра на плоскость.
2 Проверяют объекты на пересечение на проекционной плоскости.
3 Проектируют перекрестные пункты{*точки*} назад на объект и возвращают их.
Заказной AsdkPoly класс перегружает обеих формы intersectWith () функция.
Acad::ErrorStatus
AsdkPoly::intersectWith(
const AcDbEntity* ent,
AcDb::Intersect intType,
AcGePoint3dArray& points,
int /*thisGsMarker*/,
int /*otherGsMarker*/) const
{
assertReadEnabled();
Acad::ErrorStatus es = Acad::eOk;
if (ent == NULL)
return Acad::eNullEntityPointer;
// The idea is to intersect each side of the polygon
// with the given entity and return all the points.
//
// For non-R12-entities with intersection methods defined,
// we call that method for each of the sides of the polygon.
// For R12-entities, we use the locally defined intersectors,
// since their protocols are not implemented.
//
if (ent->isKindOf(AcDbLine::desc())) {
if ((es = intLine(this, AcDbLine::cast(ent),
intType, NULL, points)) != Acad::eOk)
{
return es;
}
} else if (ent->isKindOf(AcDbArc::desc())) {
if ((es = intArc(this, AcDbArc::cast(ent), intType,
NULL, points)) != Acad::eOk)
{
return es;
}
} else if (ent->isKindOf(AcDbCircle::desc())) {
if ((es = intCircle(this, AcDbCircle::cast(ent),
intType, NULL, points)) != Acad::eOk)
{
return es;
}
} else if (ent->isKindOf(AcDb2dPolyline::desc())) {
if ((es = intPline(this, AcDb2dPolyline::cast(ent),
intType, NULL, points)) != Acad::eOk)
{
return es;
}
} else if (ent->isKindOf(AcDb3dPolyline::desc())) {
if ((es = intPline(this, AcDb3dPolyline::cast(ent),
intType, NULL, points)) != Acad::eOk)
{
return es;
}
} else {
AcGePoint3dArray vertexArray;
if ((es = getVertices3d(vertexArray))
!= Acad::eOk)
{
return es;
}
if (intType == AcDb::kExtendArg
|| intType == AcDb::kExtendBoth)
{
intType = AcDb::kExtendThis;
}
AcDbLine *pAcadLine;
for (int i = 0; i < vertexArray.length() - 1; i++) {
pAcadLine = new AcDbLine();
pAcadLine->setStartPoint(vertexArray[i]);
pAcadLine->setEndPoint(vertexArray[i + 1]);
pAcadLine->setNormal(normal());
if ((es = ent->intersectWith(pAcadLine, intType,
points)) != Acad::eOk)
{
delete pAcadLine;
return es;
}
delete pAcadLine;
}
}
return es;
}
Acad::ErrorStatus
AsdkPoly::intersectWith(
const AcDbEntity* ent,
AcDb::Intersect intType,
const AcGePlane& projPlane,
AcGePoint3dArray& points,
int /*thisGsMarker*/,
int /*otherGsMarker*/) const
{
assertReadEnabled();
Acad::ErrorStatus es = Acad::eOk;
if (ent == NULL)
return Acad::eNullEntityPointer;
// The idea is to intersect each side of the polygon
// with the given entity and return all the points.
//
// For non-R12-entities, with intersection methods defined,
// we call that method for each of the sides of the polygon.
// For R12-entities, we use the locally defined intersectors,
// since their protocols are not implemented.
//
if (ent->isKindOf(AcDbLine::desc())) {
if ((es = intLine(this, AcDbLine::cast(ent),
intType, &projPlane, points)) != Acad::eOk)
{
return es;
}
} else if (ent->isKindOf(AcDbArc::desc())) {
if ((es = intArc(this, AcDbArc::cast(ent), intType,
&projPlane, points)) != Acad::eOk)
{
return es;
}
} else if (ent->isKindOf(AcDbCircle::desc())) {
if ((es = intCircle(this, AcDbCircle::cast(ent),
intType, &projPlane, points)) != Acad::eOk)
{
return es;
}
} else if (ent->isKindOf(AcDb2dPolyline::desc())) {
if ((es = intPline(this, AcDb2dPolyline::cast(ent),
intType, &projPlane, points)) != Acad::eOk)
{
return es;
}
} else if (ent->isKindOf(AcDb3dPolyline::desc())) {
if ((es = intPline(this, AcDb3dPolyline::cast(ent),
intType, &projPlane, points)) != Acad::eOk)
{
return es;
}
} else {
AcGePoint3dArray vertexArray;
if ((es = getVertices3d(vertexArray))
!= Acad::eOk)
{
return es;
}
if (intType == AcDb::kExtendArg
|| intType == AcDb::kExtendBoth)
{
intType = AcDb::kExtendThis;
}
AcDbLine *pAcadLine;
for (int i = 0; i < vertexArray.length() - 1; i++) {
pAcadLine = new AcDbLine();
pAcadLine->setStartPoint(vertexArray[i]);
pAcadLine->setEndPoint(vertexArray[i + 1]);
pAcadLine->setNormal(normal());
if ((es = ent->intersectWith(pAcadLine, intType,
projPlane, points)) != Acad::eOk)
{
delete pAcadLine;
return es;
}
delete pAcadLine;
}
// All the points that we selected in this process are on
// the other curve; we are dealing with apparent
// intersection. If the other curve is 3D or is not
// on the same plane as poly, the points are not on
// poly.
//
// In this case, we need to do some more work. Project the
// points back onto the plane. They should lie on
// the projected poly. Find points on real poly
// corresponding to the projected points.
//
AcGePoint3d projPt, planePt;
AcGePoint3dArray pts;
AcGeLine3d line;
AcGePlane polyPlane;
AcDb::Planarity plnrty;
getPlane(polyPlane,plnrty);
for (i = 0; i < points.length(); i++) {
// Define a line starting from the projPt and
// along the normal. Intersect the polygon with
// that line. Find all the points and pick the
// one closest to the given point.
//
projPt = points[i].orthoProject(projPlane);
line.set(projPt, projPlane.normal());
if ((es = intLine(this, line, pts))
!= Acad::eOk)
{
return es;
}
planePt = projPt.project(polyPlane,
projPlane.normal());
points[i] = pts[0];
double length = (planePt - pts[0]).length();
double length2;
for (int j = 1; j < pts.length(); j++) {
if ((length2 = (planePt - pts[j]).length())
< length)
{
points[i] = pts[j];
length = length2;
}
}
}
}
return es;
}