Aller au contenu

Trapeze


Messages recommandés

Salut,

 

C'était mon premier message sur CADxp.

Cette routine LISP a été écrite pour dessiner les triangulations ou contreventements dont la construction peut parfois être un peu fastidieuse (CF le screencast). Elle peut en fait servir à dessiner tout contour trapézoïdal à partir d'une hauteur (la largeur du contreventement), d'un point à chacune des extrémités (situés sur la même base ou non) et de l'angle depuis chacun de ces points, soit 4 clics une fois la hauteur paramétrée. Pratiquement, pour dessiner tout profil dont les coupes aux extrémités peuvent être de fausse équerre.

 

J'ai repris cette routine en .NET pour en faire un plugin (AutoCAD 2013 et plus) que je propose ici en test.

Télécharger et exécuter TrapezeSetup.msi pour installer le plugin sur toutes les versions d'AutoCAD (et verticaux) de 2013 à 2018.
Télécharger Trapezoid.zip depuis cette page, débloquer puis extraire et exécuter TrapezeSetup.msi pour installer le plugin sur toutes les versions d'AutoCAD (et verticaux) depuis 2013.

Lancer la commande TRZ.

La hauteur est enregistrée avec le dessin.

 

 

Le code :

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using static System.Math;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof(Trapeze.Commands))]

namespace Trapeze
{
   public class Commands
   {
       Document doc;
       Database db;
       Editor ed;
       double height;

       public Commands()
       {
           doc = AcAp.DocumentManager.MdiActiveDocument;
           db = doc.Database;
           ed = doc.Editor;
           height = GetHeight();
           db.BeginSave += (s, e) => SaveHeight();
       }

       [CommandMethod("TRZ")]
       public void Trapeze()
       {
           PromptPointOptions ppo;
           PromptPointResult ppr;
           Point3d pt1;
           while (true)
           {
               ppo = new PromptPointOptions($@"
Hauteur courante = {height}
Spécifiez le premier coin ou [Hauteur du trapeze]: ", "Hauteur");
               ppo.Keywords.Default = "Hauteur";
               ppr = ed.GetPoint(ppo);
               if (ppr.Status == PromptStatus.Keyword)
               {
                   var pdo = new PromptDistanceOptions("\nSpécifiez la hauteur: ");
                   pdo.DefaultValue = height;
                   pdo.UseDefaultValue = true;
                   var pdr = ed.GetDistance(pdo);
                   if (pdr.Status != PromptStatus.OK)
                       return;
                   height = pdr.Value;
               }
               else
               {
                   if (ppr.Status != PromptStatus.OK)
                       return;
                   pt1 = ppr.Value;
                   break;
               }
           }

           ppo.Message = "\nSpécifiez un point dans la direction de ce côté: ";
           ppo.AppendKeywordsToMessage = false;
           ppo.BasePoint = pt1;
           ppo.UseBasePoint = true;
           ppr = ed.GetPoint(ppo);
           if (ppr.Status != PromptStatus.OK)
               return;
           var pt2 = ppr.Value;

           ppo.Message = "\nSpécifiez l'autre extémité de la base ou de la diagonale: ";
           ppr = ed.GetPoint(ppo);
           if (ppr.Status != PromptStatus.OK)
               return;
           var pt3 = ppr.Value;

           using (var tr = db.TransactionManager.StartTransaction())
           using (var pline = new Polyline(4))
           {
               pline.AddVertexAt(0, new Point2d(pt1.X, pt1.Y), 0.0, 0.0, 0.0);
               pline.AddVertexAt(1, new Point2d(pt1.X, pt1.Y), 0.0, 0.0, 0.0);
               pline.AddVertexAt(2, new Point2d(pt3.X, pt3.Y), 0.0, 0.0, 0.0);
               pline.AddVertexAt(3, new Point2d(pt3.X, pt3.Y), 0.0, 0.0, 0.0);
               pline.Closed = true;
               pline.Elevation = pt1.Z;
               var ucs = ed.CurrentUserCoordinateSystem;
               pline.TransformBy(ucs);
               var jig = new TrapezeJig(pline, height, pt1.TransformBy(ucs), pt2.TransformBy(ucs), pt3.TransformBy(ucs));
               var pr = ed.Drag(jig);
               if (pr.Status == PromptStatus.OK)
               {
                   var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                   curSpace.AppendEntity(pline);
                   tr.AddNewlyCreatedDBObject(pline, true);
               }
               tr.Commit();
           }
       }

       private void SaveHeight()
       {
           using (var tr = db.TransactionManager.StartOpenCloseTransaction())
           {
               var NOD = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
               DBDictionary dict;
               if (NOD.Contains("GILE_TRAPEZE"))
               {
                   dict = (DBDictionary)tr.GetObject(NOD.GetAt("GILE_TRAPEZE"), OpenMode.ForRead);
               }
               else
               {
                   NOD.UpgradeOpen();
                   dict = new DBDictionary();
                   NOD.SetAt("GILE_TRAPEZE", dict);
                   tr.AddNewlyCreatedDBObject(dict, true);
               }
               Xrecord xrec;
               if (dict.Contains("TrapezeHeight"))
               {
                   xrec = (Xrecord)tr.GetObject(dict.GetAt("TrapezeHeight"), OpenMode.ForWrite);
               }
               else
               {
                   xrec = new Xrecord();
                   dict.SetAt("TrapezeHeight", xrec);
                   tr.AddNewlyCreatedDBObject(xrec, true);
               }
               xrec.Data = new ResultBuffer(new TypedValue(40, height));

               tr.Commit();
           }
       }

       private double GetHeight()
       {
           using (var tr = db.TransactionManager.StartOpenCloseTransaction())
           {
               var NOD = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
               if (NOD.Contains("GILE_TRAPEZE"))
               {
                   var dict = (DBDictionary)tr.GetObject(NOD.GetAt("GILE_TRAPEZE"), OpenMode.ForRead);
                   if (dict.Contains("TrapezeHeight"))
                   {
                       var xrec = (Xrecord)tr.GetObject(dict.GetAt("TrapezeHeight"), OpenMode.ForWrite);
                       return (double)xrec.Data.AsArray()[0].Value;
                   }
               }
               return 10.0;
           }
       }

       class TrapezeJig : EntityJig
       {
           Polyline pline;
           Plane plane;
           Point3d dragPt, basePt;
           Point2d p1, p2, p3;
           Vector2d v1, v2, v3;
           double width, a1;

           public TrapezeJig(Polyline pline, double width, Point3d pt1, Point3d pt2, Point3d pt3) : base(pline)
           {
               this.pline = pline;
               this.width = width;
               plane = new Plane(Point3d.Origin, pline.Normal);
               basePt = pline.GetPoint3dAt(2);
               p1 = pt1.Convert2d(plane);
               p2 = pt2.Convert2d(plane);
               p3 = pt3.Convert2d(plane);
               v1 = p1.GetVectorTo(p3);
               v2 = p1.GetVectorTo(p2).GetNormal();
               a1 = v2.Angle - v1.Angle;
           }

           protected override SamplerStatus Sampler(JigPrompts prompts)
           {
               var options = new JigPromptPointOptions("\nSpécifiez un point dans la direction de ce côté: ");
               options.UseBasePoint = true;
               options.BasePoint = basePt;
               options.Cursor = CursorType.RubberBand;
               options.UserInputControls =
                   UserInputControls.Accept3dCoordinates |
                   UserInputControls.UseBasePointElevation;
               var result = prompts.AcquirePoint(options);
               if (result.Value.IsEqualTo(dragPt))
                   return SamplerStatus.NoChange;
               dragPt = result.Value;
               return SamplerStatus.OK;
           }

           protected override bool Update()
           {
               v3 = p3.GetVectorTo(dragPt.Convert2d(plane)).GetNormal();
               double a2 = v3.Angle - v1.Angle;
               Point2d pt1, pt2, pt3, pt4;
               if (Sign(Sin(a1)) == Sign(Sin(a2)))
               {
                   double d1 = Abs(width / Sin(a1));
                   double d2 = Abs(width / Sin(a2));
                   pt1 = p1 + v2 * d1;
                   pt2 = p3 + v3 * d2;
                   pt3 = p3;
                   pt4 = p1;
               }
               else
               {
                   double a0 = Acos(width / v1.Length);
                   double d1, d2;
                   if (Sin(a1) < 0)
                   {
                       d1 = Abs(width / Cos(a0 + a1));
                       d2 = Abs(width / Cos(a0 + a2));
                   }
                   else
                   {
                       d1 = Abs(width / Cos(a0 - a1));
                       d2 = Abs(width / Cos(a0 - a2));
                   }
                   pt1 = p1;
                   pt2 = p1 + v2 * d1;
                   pt3 = p3;
                   pt4 = p3 + v3 * d2;
               }
               if (IsConvex(pt1, pt2, pt3, pt4))
               {
                   pline.SetPointAt(0, pt1);
                   pline.SetPointAt(1, pt2);
                   pline.SetPointAt(2, pt3);
                   pline.SetPointAt(3, pt4);
               }
               return true;
           }

           private bool IsConvex(Point2d pt1, Point2d pt2, Point2d pt3, Point2d pt4)
           {
               var a1 = (pt2 - pt1).Angle;
               var a2 = (pt3 - pt2).Angle;
               var a3 = (pt4 - pt3).Angle;
               var a4 = (pt1 - pt4).Angle;
               var sign = Sign(Sin(a1 - a2));
               return Sign(Sin(a2 - a3)) == sign && Sign(Sin(a3 - a4)) == sign;
           }
       }
   }
}
 

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

 

L'ami Tramber n'a pas que programmé dans son coin. Il parait que les enfants ça occupe, surtout quand ils sont petits !

 

Perso, mon premier lisp a consisté à dessiner un béton de propreté sous une semelle, avec l'épaisseur et les petits débords qui vont bien. Ce qui me fait plaisir, c'est que je m'en sers toujours. Ce qui est moins bien, c'est que je serai incapable de le transcrire en .NET

 

Amicalement

Vincent

C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme)

C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)

Lien vers le commentaire
Partager sur d’autres sites

Salut (gile)

 

Franchement, nickel, cette routine http://www.smileys-gratuits.com/smiley-content/content-3.gif

 

Merci wink.gif

Steven________________________________________

Pour le taf; Windows (et ses emmerdes) sinon pas d'AutoCAD.

Pour le perso Linux Mint et pas de problèmes. Mais pas d'AutoCAD.

En rêve; AutoCAD sous Linux.

Lien vers le commentaire
Partager sur d’autres sites

  • 4 ans après...

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité