Check if the polyline segments are on the same side

Check if the polyline segments are on the same side

ChuotSieuNhan
Contributor Contributor
673 Views
10 Replies
Message 1 of 11

Check if the polyline segments are on the same side

ChuotSieuNhan
Contributor
Contributor

Hello guys, I'm having a bit of a problem determining the direction of a polyline segment, how do I know if the segments have the same direction or in different directions? How to determine if a polyline belongs to case 1 or case 2 ? thanks you  😍

ChuotSieuNhan_0-1700817538088.png

 

0 Likes
674 Views
10 Replies
Replies (10)
Message 2 of 11

cuongtk2
Advocate
Advocate

IsClockWise(p1, p2, p3) == IsClockWise(p2, p3, p4)

0 Likes
Message 3 of 11

ChuotSieuNhan
Contributor
Contributor

anh cho em thêm chút thông tin keyword để tìm hiểu được không anh, em seach theo từ khoá của anh nhưng chưa ra thông tin

0 Likes
Message 4 of 11

kerry_w_brown
Advisor
Advisor

@ChuotSieuNhan 

 

Show us how you are determining the segments ?

You could compare the unitVectors of

startVertex => secondVertex

with

secondlastVector => lastVector

 


// Called Kerry or kdub in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect. ~ kdub
Sometimes the question is more important than the answer. ~ kdub

NZST UTC+12 : class keyThumper<T> : Lazy<T>;      another  Swamper
0 Likes
Message 5 of 11

ChuotSieuNhan
Contributor
Contributor

Thank you, I have found the solution according to your instructions @cuongtk2 

0 Likes
Message 6 of 11

cuongtk2
Advocate
Advocate
public static bool IsClockWise (this Point2d p1, Point2d p2, Point2d p3 )
{
    double num =(p1.Y - p3.Y) * (p3.X - p2.X) - (p3.Y - p2.Y) * (p1.X - p3.X);
    return num < 0;
}

var seg1 = pline.GetLineSegment2dAt(i);
var seg2 = pline.GetLineSegment2dAt(j);

var bool1 = seg2.StartPoint.IsClockWise(seg1.StartPoint, seg1.EndPoint);
var bool2 = seg1.EndPoint.IsClockWise(seg2.StartPoint, seg2.EndPoint);
string str = bool1 == bool2 ? "Same side" : "Other side";
0 Likes
Message 7 of 11

ChuotSieuNhan
Contributor
Contributor

Dạ vâng anh, em cảm ơn anh, em cũng đã tìm được giải pháp tương tự từ Gille ^^ Cảm ơn anh nhiều 

0 Likes
Message 8 of 11

kerry_w_brown
Advisor
Advisor

@ChuotSieuNhan 

The code suggested by @cuongtk2 and @_gile is nice.

. . . a bit cleaner than what I'd imagined.

This was my Vector solution

 

private bool DetermineSameLegDirection(LineSegment2d firstSegment,
                                       LineSegment2d lastSegment,
                                       Tolerance tolerance)
{
   var diff = firstSegment.EndPoint - firstSegment.StartPoint;
   Vector2d v1 = new Vector2d(diff.X, diff.Y);

   diff = lastSegment.StartPoint - lastSegment.EndPoint;
   Vector2d v2 = new Vector2d(diff.X, diff.Y);

   return v1.IsEqualTo(v2, tolerance);
}

 

 

Test usage:

 

[CommandMethod("Answer_11_25_b")]
public void Answer_11_25_b()
{
   Document doc = CadApp.DocumentManager.MdiActiveDocument;
   Database db = doc.Database;
   Editor ed = doc.Editor;

   PromptEntityOptions peo = new PromptEntityOptions("\nSelect a polyline: ");
   peo.SetRejectMessage("Not a polyline.");
   peo.AddAllowedClass(typeof(Polyline), true);
   PromptEntityResult per = ed.GetEntity(peo);
   if (per.Status != PromptStatus.OK)
      return;

   using (Transaction tr = db.TransactionManager.StartTransaction())
   {
      Polyline pline = (Polyline)tr.GetObject(per.ObjectId, OpenMode.ForWrite);
      var firstIndex = 0;
      var lastIndex = 2;
      var firstSegment = pline.GetLineSegment2dAt(firstIndex);
      var lastSegment = pline.GetLineSegment2dAt(lastIndex);
      Tolerance t = new Tolerance(Tolerance.Global.EqualVector, 
                                 Tolerance.Global.EqualPoint);
      ed.WriteMessage($"\nTolerance => {t.EqualVector}\n");
      bool result = DetermineSameLegDirection(firstSegment, lastSegment, t);
      tr.Commit();

      ed.WriteMessage(
         $"{(result ? "Legs same direction" : "Legs Different direction")}");
   }

 

 

Regards,

 

 

 

 

 

 


// Called Kerry or kdub in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect. ~ kdub
Sometimes the question is more important than the answer. ~ kdub

NZST UTC+12 : class keyThumper<T> : Lazy<T>;      another  Swamper
0 Likes
Message 9 of 11

kerry_w_brown
Advisor
Advisor

The complexity of my last post bothered me a bit, so I thought about it a little more  :

 

The LineSegment2d derives from LineEntity2d which has a Direction property which is a Vector2d.
and ,
The Vector2d Method   v1.IsEqualTo(v2)  defaults to using  Tolerance.Global.EqualVector  so I didn't need to include the Tolerance parameter in the call.

 

Not needing to create 2 new Vector2d's and a new Tolerance cleaned up the functionality considerably.

. . . in effect , to a simple one-line statement. 

 

This means the code actually doing the work can be reduced to :

 

 

 

 

bool result = pline.GetLineSegment2dAt(firstIndex).Direction.IsEqualTo(
               pline.GetLineSegment2dAt(lastIndex).Direction.Negate());

 

 

 

 

and the full transaction can now be :

 

 

 

using (Transaction tr = db.TransactionManager.StartTransaction())
{
   Polyline pline = (Polyline)tr.GetObject(per.ObjectId, OpenMode.ForWrite);
   var firstIndex = 0;
   var lastIndex = 2;

   bool result = pline.GetLineSegment2dAt(firstIndex).Direction.IsEqualTo(
                  pline.GetLineSegment2dAt(lastIndex).Direction.Negate());

   ed.WriteMessage(
      $"{(result ? "Legs same direction" : "Legs Different direction")}\n");

   tr.Commit();
}

 

 

 

This, of course, assumes the orientation of the legs is intended to be 'parallel' ie extending in the same direction, equidistant at all points, and never converging or diverging, not just on the same side of the center segment.

 

Regards,


// Called Kerry or kdub in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect. ~ kdub
Sometimes the question is more important than the answer. ~ kdub

NZST UTC+12 : class keyThumper<T> : Lazy<T>;      another  Swamper
0 Likes
Message 10 of 11

ChuotSieuNhan
Contributor
Contributor

Thank you for your interest in my article. Your solution applies well to the case where the angles are 90 degrees. In case the angle error is 1 to 2 degrees more, the result will be wrong. So I still use it the way @cuongtk2 . 

 Thank you very much

z4918884891094_455f33902f9c801672140c9490c9fb05.jpg

0 Likes
Message 11 of 11

kerry_w_brown
Advisor
Advisor

Yes, that was the conditional . . .

[quote]This, of course, assumes the orientation of the legs is intended to be 'parallel' [/quote]

 

 


// Called Kerry or kdub in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect. ~ kdub
Sometimes the question is more important than the answer. ~ kdub

NZST UTC+12 : class keyThumper<T> : Lazy<T>;      another  Swamper
0 Likes