For those still interesting in ARX and C++, here are some functions I'm porting from AutoLisp to ARX
The lisp functions belong to a routine about to draw automatically walls from a selection of lines (autowalls lisp was posted in show your stuff forum)
lisp function to find the max or min point on a list of points
(defun lbx-getmimmax-pt (lst1 pt1 cve / lth cont d d1 pmx)
(setq lth (length lst1)
cont 0
pmx (car lst1)
d (distance pmx pt1)
)
(while (< cont lth)
(setq d1 (distance (nth cont lst1) pt1))
(if (= cve "min")
(if (< d1 d)
(setq d d1
pmx (nth cont lst1)
)
)
)
(if (= cve "max")
(if (> d1 d)
(setq d d1
pmx (nth cont lst1)
)
)
)
(setq cont (1+ cont))
)
(if (> lth 1)
pmx
(car lst1)
)
)
version in arx
AcGePoint3d getMinMaxPt (AcGePoint3dArray points, AcGePoint3d pt1, int option)
{
AcGePoint3d result;
long lth = points.length();
int cont = 0;
AcGePoint3d pmx = points.at(0);
double d = acutDistance(asDblArray(pmx), asDblArray(pt1));
while (cont < lth)
{
double d1 = acutDistance(asDblArray(points.at(cont)), asDblArray(pt1));
switch (option)
{
case 0:
if (d1 < d)
{
d = d1;
pmx = points.at(cont);
}
break;
case 1:
if (d1 > d)
{
d = d1;
pmx = points.at(cont);
}
break;
}//end of switch
cont = 1 + cont;
}//end of while cont < lth
if (lth > 1)
result.set(pmx.x, pmx.y, pmx.z);
else
result.set(points.at(0).x, points.at(0).y, points.at(0).z);
return result;
}
arx function to emulate the auto lisp subst function
AcGePoint3dArray subst (AcGePoint3d newitem, AcGePoint3d olditem, AcGePoint3dArray lst)
{
int index;
if (lst.find(olditem, index))
{
lst.removeAt(index);
lst.append(newitem);
}
return lst;
}
lisp function to sort a list of points base on a point
(defun lbx-sort->pts-bspt
(lst pt / lth cont cont1 px dmx lst1 lst2 d1 d p pt1)
(setq lth (length lst)
cont 0
px (lbx-getmimmax-pt lst pt "max")
dmx (distance px pt)
lst2 lst
)
(while (< cont lth)
(setq cont1 0
d dmx
p px
)
(while (< cont1 lth)
(setq d1 (distance (setq pt1 (nth cont1 lst2)) pt))
(if (< d1 d)
(setq d d1
p pt1
)
)
(setq cont1 (1+ cont1))
)
(setq lst1 (append lst1 (list p))
lst2 (subst px p lst2)
cont (1+ cont)
)
)
lst1
)
version in arx
AcGePoint3dArray sortPtsBspt (AcGePoint3dArray lst, AcGePoint3d pt)
{
long lth = lst.length();
int cont = 0;
AcGePoint3d px = getMinMaxPt(lst, pt, 1);
double dmx = acutDistance(asDblArray(px), asDblArray(pt));
AcGePoint3dArray list1, list2;
// pass all the lst items to list2
for (int i = 0; i < lst.length(); i++)
list2.append(lst.at(i));
while (cont < lth)
{
int cont1 = 0;
double d = dmx;
AcGePoint3d p;
p.set(px.x, px.y, px.z);
while (cont1 < lth)
{
AcGePoint3d pt1 = list2.at(cont1);
double d1 = acutDistance(asDblArray(pt1), asDblArray(pt));
if (d1 < d)
{
d = d1;
p.set(pt1.x, pt1.y, pt1.z);
}
cont1 = 1 + cont1;
}//end of while cont1<lth
list1.append(p);
list2 = subst(px, p, list2);
cont = 1 + cont;
}//end of while cont<lth
return list1;
}
lisp function to define all the points that pass over a node of two or more lines
(defun lbx-node-line (pt / sel lth cont ent1 dat1 obj1
tst1 tst2 v01 v11 v02 v12 ang1 pa1
pb1 pa2 pb2 pv) ;pa pb
(setq sel sel3
lth (sslength sel)
cont 0
tst nil
pv1 nil
pv2 nil
pv3 nil
pv4 nil)
(while (< cont lth)
(setq ent1 (ssname sel cont)
dat1 (entget ent1)
obj1 (lbx-dxf 0 dat1)
tst1 nil
tst2 nil)
(if (and (= obj "LINE") (= obj1 "LINE"))
(progn
(setq v01 (polar v0 (+ ang ort) mw)
v11 (polar v1 (+ ang ort) mw)
v02 (polar v0 (- ang ort) mw)
v12 (polar v1 (- ang ort) mw)
pa (trans (lbx-dxf 10 dat1) 0 1)
pb (trans (lbx-dxf 11 dat1) 0 1)
ang1 (angle pa pb)
pa1 (polar pa (+ ang1 ort) mw)
pb1 (polar pb (+ ang1 ort) mw)
pa2 (polar pa (- ang1 ort) mw)
pb2 (polar pb (- ang1 ort) mw))
(if (lbx-equal-point (inters pa pb p0 p1) pt)
(progn
(if (or (lbx-equal-point pt p0)
(lbx-equal-point pt p1))
(progn
(if
(lbx-pt-on-vector
(inters pa1 pb1 p0 p1 nil)
p0
p1)
(setq p pa2
pa2 pa1
pa1 p
p pb2
pb2 pb1
pb1 p))
(if (setq pv (inters pa2 pb2 v01 v11))
(setq pv1 (append pv1 (list pv))))
(if (setq pv (inters pa2 pb2 v02 v12))
(setq pv2 (append pv2 (list pv))))
(if (setq pv (inters pa1 pb1 v01 v11 nil))
(setq pv3 (append pv3 (list pv))
tst1 T))
(if (setq pv (inters pa1 pb1 v02 v12 nil))
(setq pv4 (append pv4 (list pv))
tst2 T))
)
(progn
(if (setq pv (inters pa1 pb1 v01 v11))
(setq pv1 (append pv1 (list pv))))
(if (setq pv (inters pa2 pb2 v01 v11))
(setq pv1 (append pv1 (list pv))))
(if (setq pv (inters pa1 pb1 v02 v12))
(setq pv2 (append pv2 (list pv))))
(if (setq pv (inters pa2 pb2 v02 v12))
(setq pv2 (append pv2 (list pv))))
))))
))
(setq cont (1+ cont))
(if (and tst1 tst2)
(setq tst T))
))
version in arx
static void nodeLine (AcGePoint3d pt,
ads_name sel,
double ang,
double ort,
double mw,
AcGePoint3d v0,
AcGePoint3d v1,
AcGePoint3d p0,
AcGePoint3d p1,
AcGePoint3dArray pointsV1,
AcGePoint3dArray pointsV2,
AcGePoint3dArray pointsV3,
AcGePoint3dArray pointsV4)
{
long lth = 0;
if (acedSSLength(sel, <h) != RTNORM || lth == 0)
{
acedSSFree(sel);
//return;
}
int cont = 0, tst = 0;
//AcGePoint3dArray pointsV1, pointsV2, pointsV3, pointsV4;
while (cont < lth)
{
int tst1 = 0, tst2 = 0;
AcDbObjectId objId;
ads_name ename;
acedSSName(sel, cont, ename);
if (acdbGetObjectId(objId, ename) != Acad::eOk) return;
AcDbObjectPointer<AcDbLine> ent1(objId, AcDb::kForRead);
if (ent1.openStatus() == Acad::eOk)
{
ads_point v01, v11, v02, v12, pa, pb;
acutPolar(asDblArray(v0), (ang + ort), mw, v01);
acutPolar(asDblArray(v1), (ang + ort), mw, v11);
acutPolar(asDblArray(v0), (ang - ort), mw, v02);
acutPolar(asDblArray(v1), (ang - ort), mw, v12);
AcGePoint3d startPoint, endPoint;
ent1->getStartPoint(startPoint);
ent1->getEndPoint(endPoint);
ads_point_set(asDblArray(startPoint), pa);
ads_point_set(asDblArray(endPoint), pb);
acdbWcs2Ucs(pa, pa, false);
acdbWcs2Ucs(pb, pb, false);
double ang1 = acutAngle(pa, pb);
ads_point pa1, pb1, pa2, pb2;
acutPolar(pa, (ang1 + ort), mw, pa1);
acutPolar(pb, (ang1 + ort), mw, pb1);
acutPolar(pa, (ang1 - ort), mw, pa2);
acutPolar(pb, (ang1 - ort), mw, pb2);
ads_point pin;
if (acdbInters(pa, pb, asDblArray(p0), asDblArray(p1), 1, pin) == RTNORM)
{
// convert intersection point to AcGePoint3d
AcGePoint3d ptInt(pin[X], pin[Y], pin[Z]);
double fuzz = 0.00001;
// check for equality of points ptInt == v0
if (ptInt.distanceTo(pt) <= fuzz)
{
// verify if any of the pair of points are equal
if (pt.distanceTo(p0) <= fuzz ||
pt.distanceTo(p1) <= fuzz)
{
//ads_point pin;
if (acdbInters(pa1, pb1, asDblArray(p0), asDblArray(p1), 0, pin) == RTNORM)
{
AcGePoint3d ptInt(pin[X], pin[Y], pin[Z]);
// check if the point is on the vector p0-p1
if (eqDoubles(
p0.distanceTo(ptInt) + p1.distanceTo(ptInt),
p0.distanceTo(p1), fuzz))
{
ads_point p;
ads_point_set(pa2, p);
ads_point_set(pa1, pa2);
ads_point_set(p, pa1);
ads_point_set(pb2, p);
ads_point_set(pb1, pb2);
ads_point_set(p, pb1);
}
}//end of acdbInters(pa1, pb1, p0, p1, 0, pin)
ads_point pv;
if (acdbInters(pa2, pb2, v01, v11, 1, pv) == RTNORM)
pointsV1.append(asPnt3d(pv));
if (acdbInters(pa2, pb2, v02, v12, 1, pv) == RTNORM)
pointsV2.append(asPnt3d(pv));
if (acdbInters(pa1, pb1, v01, v11, 0, pv) == RTNORM)
{
pointsV3.append(asPnt3d(pv));
tst1 = 1;
}
if (acdbInters(pa1, pb1, v02, v12, 0, pv) == RTNORM)
{
pointsV4.append(asPnt3d(pv));
tst2 = 1;
}
}//end of v0.distanceTo
else
{
ads_point pv;
if (acdbInters(pa1, pb1, v01, v11, 1, pv) == RTNORM)
pointsV1.append(asPnt3d(pv));
if (acdbInters(pa2, pb2, v01, v11, 1, pv) == RTNORM)
pointsV1.append(asPnt3d(pv));
if (acdbInters(pa1, pb1, v02, v12, 1, pv) == RTNORM)
pointsV2.append(asPnt3d(pv));
if (acdbInters(pa2, pb2, v02, v12, 1, pv) == RTNORM)
pointsV2.append(asPnt3d(pv));
}
}//end of ptInt.distanceTo
}//end of acdbInters(pa, pb, p0, p1, 1, pin)
}//end of ent1.openStatus
cont = 1 + cont;
if (tst1 == 1 && tst2 == 1)
tst = 1;
}//end of while cont<lth
}
It is a job in progress, your comments are welcome.