Message 1 of 9
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
hi i have closed polyline in the drawing now i want to create a perpendicular ray from each line to outside polyline
Solved! Go to Solution.
hi i have closed polyline in the drawing now i want to create a perpendicular ray from each line to outside polyline
Solved! Go to Solution.
So you have a closed polyline that contains only lines, right?
First you have to find out whether your polyline runs clockwise (cw) or counter-clockwise (ccw).
This can be done easily by calculating the sum of the signed angles between the lines. If the sum is +2PI (+360°) it is ccw if it is -2PI (-360°) it is cw. For three AcGePoint3d p1, p2, p3 the signed angle can be calculated like this:
AcGeVector3d v12(p2-p1);
AcGeVector3d v23(p3-p2);
double signedAngle = v12.angleTo(v23, AcGeVector3d::kZAxis); // 0..2PI
if (signedAngle > PI)
signedAngle -= 2*PI; // -PI..+PI
For the ray you need a starting point pt and a direction vector v.
Let ps and pe be start/endpoint of a segment.
AcGePoint3d ps, pe; // in
bool ccw; // in
AcGeVector3d v, vse(pe - ps);
AcGeVector3d v(-vse.y, vse.x, vse.z);
//v points to the left side of [ps-->pe] which is the outside if clockwise
if (ccw)
v = -v;
AcGePoint3d pt(ps + 0.5*vse);
AcDbRay *ray = new AcDbRay()
ray->setBasePoint(pt);
v.normalize();
ray->setUnitDir(v);
first thing from where to take 3 points p1,p2 and p3
second thing is i want to get perpendicular outside ray
something is missing in logic
I explained:
All you have to do is write loops and put the parts together.
Each point of the closed polygon has a predecessor and a successor. In (p1, p2, p3) p1 is the predecessor of p2 and p3 is it's successor. In a closed poylgon the successor of the last point is the first point. ps, pe stand for start-/endpoint of a line segment.
So this is ist all together:
// 1.) Clockwise or counter-clockwise?
double TurtleAngle(const AcGePoint3dArray &p)
{
double sumAngles = 0.0; // out
int iPrev, iNext;
int N = p.length();
for (int i=0; i<N; ++i)
{
iPrev = i-1;
iNext = i+1;
if (iPrev < 0)
iPrev = N-1;
if (iNext >= N)
iNext = 0;
const AcGePoint3d &p1 = p[iPrev];
const AcGePoint3d &p2 = p[i];
const AcGePoint3d &p3 = p[iNext];
AcGeVector3d v12(p2-p1);
AcGeVector3d v23(p3-p2);
double signedAngle = v12.angleTo(v23, AcGeVector3d::kZAxis); // 0..2PI
if (signedAngle > PI)
signedAngle -= 2*PI; // -PI..+PI
sumAngles += signedAngle
}
return sumAngles;
}
void CreateRays(const AcGePoint3dArray &p)
{
// 1.) Clockwise or counter-clockwise?
double ang = TurtleAngle(p);
bool ccw = (ang > 0.0);
// 2.) Create rays
int N = p.length();
for (int i=0; i<N; ++i)
{
int iNext = i+1;
if (iNext >= N)
iNext = 0;
const AcGePoint3d &ps = p[i];
const AcGePoint3d &pe = p[iNext];
// Edited 03.20.2023: This must be within the for loop!
AcGeVector3d v, vse(pe - ps);
AcGeVector3d v(-vse.y, vse.x, vse.z);
//v points to the left side of [ps-->pe] which is the outside if clockwise
if (ccw)
v = -v;
AcGePoint3d pt(ps + 0.5*vse);
AcDbRay *ray = new AcDbRay();
ray->setBasePoint(pt);
v.normalize();
ray->setUnitDir(v);
postToDb(ray); // add the ray to the DB
}
}
Maybe I should have named the points p, pPrev and pNext.
Just implement a loop that runs for
first thing is how to access pe and ps out side the loop ?
second thing is to consider only last pe and ps from all points(p) ?
The complete code is in my previous reply. See function CreateRays(AcGePoint3dArray &p).
I just edited the code because a part of it had to be moved into the for {} loop. It should be clear now.
but how could you assume all points (p) are in sequance ?
because it is possible if p[i] is 1st line segment start or end point in polyline and p[iNext] will be 3rd or 4th or any other no. of segment's point then how this logic will work ?
You wrote: ".. i have closed polyline in the drawing".
So you have all the polyline vertex points in a sequence.
iNext is always the index of the vertex that follows to i: Either i+1 or 0 if i is the index of the last vertex.
thank you so much sir it' working fine