ObjectARX
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

regarding create perpendicular ray

8 REPLIES 8
SOLVED
Reply
Message 1 of 9
jignesh.rana
386 Views, 8 Replies

regarding create perpendicular ray

hi i have closed polyline in the drawing now i want to create a perpendicular ray from each line to outside polyline

 

 

8 REPLIES 8
Message 2 of 9
tbrammer
in reply to: jignesh.rana

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);

 


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

Message 3 of 9
jignesh.rana
in reply to: tbrammer

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

Message 4 of 9
tbrammer
in reply to: jignesh.rana

I explained:

  1. how to determine whether the polygon runs cw or ccw. Full function code is below.
  2. how to construct a ray "to the outside" when you know whether the polygon is cw or ccw.

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

 


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

Message 5 of 9
jignesh.rana
in reply to: tbrammer

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) ?

Message 6 of 9
tbrammer
in reply to: jignesh.rana

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.

 


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

Message 7 of 9
jignesh.rana
in reply to: tbrammer

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 ?

Message 8 of 9
tbrammer
in reply to: jignesh.rana

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.


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

Message 9 of 9
jignesh.rana
in reply to: tbrammer

thank you so much sir it' working fine 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost