Author Topic: Stacking Mtext  (Read 2137 times)

0 Members and 1 Guest are viewing this topic.

nobody

  • Swamp Rat
  • Posts: 861
  • .net stuff
Stacking Mtext
« 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
« Last Edit: August 19, 2017, 03:12:42 PM by FriendFromArea51 »

nobody

  • Swamp Rat
  • Posts: 861
  • .net stuff
Re: Stacking Mtext
« Reply #1 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 :)

nobody

  • Swamp Rat
  • Posts: 861
  • .net stuff
Re: Stacking Mtext
« Reply #2 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.  

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Stacking Mtext
« Reply #3 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

nobody

  • Swamp Rat
  • Posts: 861
  • .net stuff
Re: Stacking Mtext
« Reply #4 on: August 19, 2017, 03:13:46 PM »
The first I post I modified seems to get better results...though still fails on some.

nobody

  • Swamp Rat
  • Posts: 861
  • .net stuff

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2132
  • class keyThumper<T>:ILazy<T>
Re: Stacking Mtext
« Reply #6 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,
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

nobody

  • Swamp Rat
  • Posts: 861
  • .net stuff
Re: Stacking Mtext
« Reply #7 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

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Stacking Mtext
« Reply #8 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

BIGAL

  • Swamp Rat
  • Posts: 1409
  • 40 + years of using Autocad
Re: Stacking Mtext
« Reply #9 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")
A man who never made a mistake never made anything