TheSwamp

Code Red => .NET => Topic started by: nobody on August 18, 2017, 09:48:18 PM

Title: Stacking Mtext
Post by: nobody on August 18, 2017, 09:48:18 PM
Trying to restack some text appropriately.  I've tried a few different ways but at a loss. See below. Started by checking if the first text item had "two" in it, then checked if the position.X was < then position of the 2nd text, then swapped them. Tried a few different checks which worked for the most part except when the text was at a strange angle.

I know there has to be a more efficient way to do this.  Below code updated from original post and works for many cases but not all. Any ideas welcome. Thanks!

Code - C#: [Select]
  1.  
  2.  
  3.         private void swaptext()
  4.         {
  5.             using (help.AcadDocumentLock)
  6.             {
  7.                 using (var t = help.StartTransaction)
  8.                 {
  9.                     try
  10.                     {
  11.                         MText tx1 = (MText)ids[0].GetObject(OpenMode.ForRead);
  12.                         MText tx2 = (MText)ids[1].GetObject(OpenMode.ForRead);
  13.  
  14.                         string cont1 = tx1.Contents;
  15.                         string cont2 = tx2.Contents;
  16.  
  17.                         Point3d pos1 = tx1.Location;
  18.                         Point3d pos2 = tx2.Location;
  19.  
  20.                         if ((tx1.Contents.Contains("TWO")) && (pos1.X < pos2.X))
  21.                         {
  22.                             tx1.UpgradeOpen();
  23.                             tx2.UpgradeOpen();
  24.                             tx1.Contents = cont2;
  25.                             tx2.Contents = cont1;
  26.                         }
  27.  
  28.                         else if ((tx2.Contents.Contains("TWO")) && (pos2.X < pos1.X))
  29.                         {
  30.                             tx1.UpgradeOpen();
  31.                             tx2.UpgradeOpen();
  32.                             tx1.Contents = cont2;
  33.                             tx2.Contents = cont1;
  34.                         }
  35.  
  36.                         else if ((tx1.Contents.Contains("TWO")) && (pos1.Y > pos2.Y))
  37.                         {
  38.                             tx1.UpgradeOpen();
  39.                             tx2.UpgradeOpen();
  40.                             tx1.Contents = cont2;
  41.                             tx2.Contents = cont1;
  42.                         }
  43.  
  44.  
  45.                         else if ((tx2.Contents.Contains("TWO")) && (pos2.Y > pos1.Y))
  46.                         {
  47.                             tx1.UpgradeOpen();
  48.                             tx2.UpgradeOpen();
  49.                             tx1.Contents = cont2;
  50.                             tx2.Contents = cont1;
  51.                         }
  52.  
  53.  
  54.  
  55.                         ids.Clear();
  56.  
  57.                     }
  58.                     caTWOh (System.Exception ex)
  59.                     {
  60.                         help.AcadDocument.Editor.WriteMessage("Error: ==>\n{0}\nTrace: ==>\n{1}", ex.Message, ex.StackTrace);
  61.                     }
  62.                     t.Commit();
  63.  
  64.                 }
  65.             }
  66.         }
  67.  
  68.  
  69.                


- Modified code to match closest working solution
Title: Re: Stacking Mtext
Post by: nobody on August 18, 2017, 10:01:32 PM
Actually the graphic I made for this post gave me some ideas... I think if I check the angle from the first string position to the second string is not in the first 180-degrees might work :)
Title: Re: Stacking Mtext
Post by: nobody on August 18, 2017, 10:24:15 PM
Oy...eludes me again :(  Any help appreciated.  Thank you!

Code - C#: [Select]
  1. public static double anglefromxpos(Point3d pt1, Point3d pt2)
  2.         {
  3.             CoordinateSystem3d systemd = Application.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem.CoordinateSystem3d;
  4.             Plane plane = new Plane(systemd.Origin, systemd.Xaxis, systemd.Yaxis);
  5.             Vector3d vectord = (Vector3d)(pt2 - pt1);
  6.             return vectord.AngleOnPlane(plane);
  7.         }
  8.  
  9.  
  10.  private void swaptext()
  11.         {
  12.             using (help.AcadDocumentLock)
  13.             {
  14.                 using (var t = help.StartTransaction)
  15.                 {
  16.                     try
  17.                     {                        
  18.                         MText tx1 = (MText)ids[0].GetObject(OpenMode.ForRead);
  19.                         MText tx2 = (MText)ids[1].GetObject(OpenMode.ForRead);
  20.                         string conts1 = tx1.Contents;
  21.                         string conts2 = tx2.Contents;
  22.  
  23.                         Point3d pos1 = tx1.Location;
  24.                         Point3d pos2 = tx2.Location;
  25.  
  26.                         if ((tx1.Contents.Contains("TWO")) && (anglefromxpos(pos1,pos2) < 3.14159) && (pos1.Y > pos2.Y))
  27.                         {
  28.                             tx1.Contents = conts2;
  29.                             tx2.Contents = conts1;
  30.                         }
  31.  
  32.                         if ((tx2.Contents.Contains("TWO")) && (anglefromxpos(pos2, pos1) < 3.14159) && (pos2.Y > pos1.Y))
  33.                         {
  34.                             tx2.Contents = conts1;
  35.                             tx1.Contents = conts2;
  36.                         }
  37.  
  38.  
  39.                         ids.Clear();
  40.                     }
  41.                     catch (System.Exception ex)
  42.                     {
  43.                      help.AcadDocument.Editor.WriteMessage("Error: ==>\n{0}\nTrace: ==>\n{1}", ex.Message, ex.StackTrace);
  44.                     }
  45.                     t.Commit();
  46.                 }
  47.             }
  48.         }
  49.  
  50.  
Title: Re: Stacking Mtext
Post by: Bryco on August 19, 2017, 11:42:59 AM
anglefromxpos(pos1,pos2)-tx1.rotation < 3.14159)   sounds better to find if it is left or right
Title: Re: Stacking Mtext
Post by: nobody on August 19, 2017, 03:13:46 PM
The first I post I modified seems to get better results...though still fails on some.
Title: Re: Stacking Mtext
Post by: nobody on August 19, 2017, 03:31:17 PM
This response seemed to do the trick :)

https://stackoverflow.com/questions/45767320/stack-text-in-cad-based-on-what-it-contains-and-coordinates/45770048#45770048
Title: Re: Stacking Mtext
Post by: kdub_nz on August 19, 2017, 06:03:38 PM
I can't make time to have a good look, but :

There will be some cases where the algorithm will fail ...
for instance the second example looks suspect.

May be better if both are rotated from the same point rather than their unique individual points.

My initial thought was to use a vector from txt1 to txt2 and test it's direction.

Regards,
Title: Re: Stacking Mtext
Post by: nobody on August 20, 2017, 04:16:12 PM
Thanks Kdub, you're correct.  It seems to fail in that case.  Much much better than what I tried though XD
Title: Re: Stacking Mtext
Post by: Bryco on August 20, 2017, 09:02:16 PM
/you only need to know if it is left or right of the mtext.rotation.
adapting
 //gile

        public static int isLeft(Point3d p1, Point3d p2, Point3d p3, Vector3d normal)
        {
            const double pi = 3.141592653589793;
            Vector3d v1 = p1.GetVectorTo(p2);
            Vector3d v2 = p1.GetVectorTo(p3);
            double angle = v1.GetAngleTo(v2, normal);
            if (angle == 0.0 || angle == pi)
                return 0;//aligned
            else
            {
                if (v1.GetAngleTo(v2, normal) < pi)
                    return -1;//counterclockwise
                else
                    return 1;//clockwise
            }
        }

I seems anglefromxpos(pos1,pos2)-tx1.rotation < 3.14159) should give you a left or right answer (And add the check for aligned)
So no need for  && (pos1.Y > pos2.Y)) etc, maybe I missed something
Title: Re: Stacking Mtext
Post by: BIGAL on August 21, 2017, 12:53:41 AM
I know this is lisp but sorts the two lines as required so can swap the text around using current text even if mtext just strip to multi line.

Code: [Select]
(setq lst (list "this is line two" "this is line one"))

Command: (setq lst (VL-SORT lst '(lambda (a b) (> a b))))
("this is line two" "this is line one")

Command: (setq lst (VL-SORT lst '(lambda (a b) (< a b))))
("this is line one" "this is line two")