Matt666 Posté(e) le 25 février 2019 Posté(e) le 25 février 2019 Ah oui c'est marrant, j'y pensais (le cadr) lors de l'écriture du programme ! Mais voyant que ça fontionnait je n'ai pas corrigé. BricsCad quoi ah ah Pour le trim, les options "_edge" et "_extend" sont activées dans ce but, justement : Elle permettent d'étendre les entités pour "forcer" la coupure non physiques. Oui, le fameux changement de SCU. J'avoue avoir encore du mal avec ces maudites coordonnées qui sont pourtant le coeur du logiciel ! La fonction trans est puissante et un peu compliquée à la fois, faut vraiiiiment que je m'y colle une bonne fois pour toute. Merci encore pour tes précieux retours. "Chacun compte pour un, et nul ne compte pour plus d'un."
(gile) Posté(e) le 26 février 2019 Posté(e) le 26 février 2019 Salut, C'est juste un début. Pour l'instant, ça ne fonctionne qu'avec des lignes sur le plan XY du SCG. Le sens de l'arc dépend de la position du curseur par rapport au premier point cliqué. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Matt666 Posté(e) le 26 février 2019 Posté(e) le 26 février 2019 ah oui ok... Comme d'habitude, c'est impressionant ! Bien impatient de voir comment tu fais ce genre de choses.. Bravo (gile). "Chacun compte pour un, et nul ne compte pour plus d'un."
lecrabe Posté(e) le 26 février 2019 Auteur Posté(e) le 26 février 2019 Hello Gilles C TIP-TOP ! ... On se croirait sous MicroStation !!!Voir la Video de Mr lrdb@home du 24 Fevrier 19h55 ... Dans l'attente de la version definitive de cette merveilleuse Routine !? Merci d'avance, Bye, lecrabe Autodesk Expert Elite Team
didier Posté(e) le 26 février 2019 Posté(e) le 26 février 2019 Coucou Ah ben si (gile) est dans la course !!! on fait quoi nous ?????Bien sûr que c'est bien fait, c'est (gile) De mon côté je travaille (quand je peux et je peux peu) sur ce type de raccordement.J'arrive à faire l'arc par le calcul mais c'est pas dynamique et je ne gère que des lignes pour l'instantJe ne lâche pas l'affaire même si, comme c'est arrivé souvent, je ne remets pas ma copie en temps et en heure. Au fait, (gile) c'est en quoi ton truc, en C# ou en lisp ? Amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
lecrabe Posté(e) le 26 février 2019 Auteur Posté(e) le 26 février 2019 Hello OUI quand le Supreme Leader Gilles CAUSE, tout le monde ecoute et admire ! Bye, lecrabe PS: ça m énerve GRAVE de voir que Microstation a "pique" dans AutoCAD plein de choses !Et de l autre cote, Autodesk n a jamais regarde Microstation !! Autodesk Expert Elite Team
(gile) Posté(e) le 26 février 2019 Posté(e) le 26 février 2019 Merci pour les compliments, mais je ne suis pas sûr d'arriver à faire tout ce qu'il faudrait implémenter pour imiter correctement ce que fait Microstation (je me suis mis la barre assez haut : fonctionnement dynamique dans tous les plans avec des lignes polylignes, arcs et cercles). J'ai un peu avancé, toujours avec des segments droits (ligne ou polyligne), toujours dans le plan XY et avec la possibilité de changer le sens de l'arc par validation de d'une option, mais il reste du boulot... C'est, bien sûr, écrit en C#/.NET. Je pense qu'en LISP on peut écrire (plus rapidement) quelque chose qui fonctionne sans fioritures, ni effets visuels. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
zebulon_ Posté(e) le 1 mars 2019 Posté(e) le 1 mars 2019 Ma contribution avec deux segment droits, sans fonctionnement dynamique et sans contrôle des cas particuliers (defun vlax-list->3D-point (lst / nlst) (while lst (setq nlst (cons (list (car lst) (cadr lst) (caddr lst)) nlst)) (setq lst (cdddr lst)) ) (reverse nlst) ) (defun c:cttp () (setq AcDoc (vla-get-activeDocument (vlax-get-acad-object)) Space (if (= (getvar "CVPORT") 1) (vla-get-PaperSpace AcDoc) (vla-get-ModelSpace AcDoc) ) ) (setq S (getpoint "\nSommet : ")) (setq SG (trans S 1 0)) (setq d1 (trans (getpoint S "\nExtrémité d1 : ") 1 0)) (setq seg1 (vla-addLine space (vlax-3d-point SG) (vlax-3d-point d1))) (setq d2 (trans (getpoint S "\nExtrémité d2 : ") 1 0)) (setq seg2 (vla-addLine space (vlax-3d-point SG) (vlax-3d-point d2))) (setq A (trans (getpoint "\nPoint de passage : ") 1 0)) ;; bissectrice (setq PT1 (polar SG (angle SG d1) 1)) (setq PT2 (polar SG (angle SG d2) 1)) (setq PTC (polar PT1 (angle PT1 PT2) (/ (distance PT1 PT2) 2.0))) (setq bissec (vla-addXline space (vlax-3d-point SG) (vlax-3d-point PTC))) ;; cercle de centre J (setq J (vlax-curve-getClosestPointTo bissec A)) (setq C1 (vla-addCircle Space (vlax-3d-point J) (distance A J))) ;; Cercle de centre I (setq I1 (inters J A SG d1 nil)) (setq I2 (inters J A SG d2 nil)) (if (< (distance A I1) (distance A I2)) (setq I I1 seg seg1) (setq I I2 seg seg2) ) (setq C2 (vla-addCircle Space (vlax-3d-point (polar J (angle J I) (/ (distance I J) 2.0))) (/ (distance I J) 2.0) ) ) ;; points d'intersection des deux cercles (setq lstpt (vlax-list->3d-point (vlax-invoke C1 'IntersectWith C2 acExtendNone))) ;; on prend le premier point d'intersection (setq K (car lstpt)) ;; et on trace le cercle de centre I qui passe par K (setq C3 (vla-addCircle Space (vlax-3d-point I) (distance I K))) ;; on trouve les points d'intersection avec seg, je considère qu'il y en a deux sauf cas particuliers que je n'étudie pas (setq lstpt (vlax-list->3d-point (vlax-invoke seg 'IntersectWith C3 acExtendBoth))) (setq T1 (car lstpt)) (setq T2 (cadr lstpt)) ;; tracer les perpendiculaires (setq perp1 (vla-addXline Space (vlax-3d-point T1) (vlax-3d-point (polar T1 (+ (angle T1 SG) (/ pi 2)) 1)))) (setq perp2 (vla-addXline Space (vlax-3d-point T2) (vlax-3d-point (polar T2 (+ (angle T2 SG) (/ pi 2)) 1)))) ;; trouver les centres (setq lstpt (vlax-list->3d-point (vlax-invoke perp1 'IntersectWith bissec acExtendNone))) (setq O1 (car lstpt)) (setq lstpt (vlax-list->3d-point (vlax-invoke perp2 'IntersectWith bissec acExtendNone))) (setq O2 (car lstpt)) ;; points symétriques (setq T10 (vlax-curve-getClosestPointTo bissec T1)) (setq T20 (vlax-curve-getClosestPointTo bissec T2)) (setq T11 (polar T10 (angle T1 T10) (distance T1 T10))) (setq T21 (polar T20 (angle T2 T20) (distance T2 T20))) ;; tracer les arcs (setq arc1 (vla-addArc Space (vlax-3d-point O1) (distance O1 T1) (angle O1 T1) (angle O1 T11))) (setq arc11 (vla-addArc Space (vlax-3d-point O1) (distance O1 T1) (angle O1 T11) (angle O1 T1))) (if (< (distance A (vlax-curve-getClosestPointTo arc1 A)) (distance A (vlax-curve-getClosestPointTo arc11 A))) (vla-delete arc11) (vla-delete arc1) ) (setq arc2 (vla-addArc Space (vlax-3d-point O2) (distance O2 T2) (angle O2 T21) (angle O2 T2))) (setq arc21 (vla-addArc Space (vlax-3d-point O2) (distance O2 T2) (angle O2 T2) (angle O2 T21))) (if (< (distance A (vlax-curve-getClosestPointTo arc2 A)) (distance A (vlax-curve-getClosestPointTo arc21 A))) (vla-delete arc21) (vla-delete arc2) ) ;; supprimer les constructions (vla-delete bissec) (vla-delete C1) (vla-delete C2) (vla-delete C3) (vla-delete perp1) (vla-delete perp2) (princ) ) AmicalementVincent 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)
didier Posté(e) le 1 mars 2019 Posté(e) le 1 mars 2019 Coucou Je suis parti dans les mêmes directions que Zebulon_Je n'ai pas encore terminé mais je viendrai proposer ma solution terminée Merci du challenge, merci du partageÇa m'a donné l'idée de faire un menu spécifique aux "arcs" sur da-code.fr car il y a de la matière à creuser... Amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
lecrabe Posté(e) le 1 mars 2019 Auteur Posté(e) le 1 mars 2019 Hello WAOUH !! Merci les Pros du Lisp / VLisp / Dotnet ... Neanmoins quand je revois la Video MicroStation, JE PLEURE !! Bon WE, Bye, lecrabe PS: cela fait plusieurs fois que je fais des formations dans des collectivités Microstation qui passent sur AutoCAD / AutoCAD MAP... Et ce pour 2 raisons :1) La Principale : Covadis n'existe que sur AutoCAD / AutoCAD MAP !2) Politique tarifaire de Bentley (L Éditeur de Microstation) "non satisfaisante" ! J'aimerais bien qu'on m'explique ?! Autodesk Expert Elite Team
zebulon_ Posté(e) le 1 mars 2019 Posté(e) le 1 mars 2019 J'ai commencé à travailler avec MicroStation 3.0, puis V4 dans les années 1990. Mais comme, au bout d'un moment, les clients du bureau d'études qui m'employait voulaient récupérer des fichiers dwg, notre patron a décidé de nous passer sur Autocad V12. Je me souviens d'avoir pleuré amèrement également... 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)
didier Posté(e) le 2 mars 2019 Posté(e) le 2 mars 2019 Coucou Certes ce discours a été maintes fois entendu, mais, mais, mais...Dans Microstation quand on veut créer "améliorer" avec une commande perso : y'-a-t'il un langage de programmation digne de ce nom ? Amicalement PS : j'ai pas retravaillé sur le lisp de raccord en question et en plus maintenant que je sais qu'une solution est donnée je me connais...il va finir sous le coude... Éternel débutant... Mon site perso : Programmer dans AutoCAD
lrdb@home Posté(e) le 2 mars 2019 Posté(e) le 2 mars 2019 Bonjour,Oui didier, il y a des langages dignes de ce nomVBA, MDL, C++ Sur ce lien , un site très riche en informationsJ'entends souvent que le vba est mort etc.. , j'ai un douteVoici une vidéo de modestes réalisations faites en vba justement write a book about what ??
lecrabe Posté(e) le 2 mars 2019 Auteur Posté(e) le 2 mars 2019 Hello Au fait n'oubliez pas le PS dans mon message d'hier a 4h47... Vos remarques sont les bienvenues ?! Et au fait dans quels domaines / fonctions AutoCAD est "meilleur" que USTN (SANS ajout de routines LSP) ?? Bye, lecrabe Autodesk Expert Elite Team
lrdb@home Posté(e) le 2 mars 2019 Posté(e) le 2 mars 2019 Re,lecrabe, par rapport à ton PSJ'en sais rien J'attends que GEOMEDIA développe sur Microstation !Fin de la parenthèsePour revenir au sujet, une nouvelle vidéo faite avec une version SS3 de powerdraft write a book about what ??
(gile) Posté(e) le 2 mars 2019 Posté(e) le 2 mars 2019 Bonjour,Oui didier, il y a des langages dignes de ce nomVBA, MDL, C++ Sur ce lien , un site très riche en informationsJ'entends souvent que le vba est mort etc.. , j'ai un douteVoici une vidéo de modestes réalisations faites en vba justement Juste un petit bémol,ce ne sont pas tant les langages supportés que les APIs et les fonctionnalités exposées qui importent. Par exemple, l'API COM d'AutoCAD (la seule utilisable par le VBA AutoCAD) présente, à mon sens de graves lacunes (absence d'objets Point2D ou Point3d, pitoyable gestion des jeux de sélection, ...). Heureusement, en LISP on peut mixer les accès à l'API COM (fonctions vla-*) avec du "pur AutoLISP" pour palier à ces lacunes.Et donc, à mon sens, ce qui fait la force d'AutoCAD, c'est de proposer, avec AutoLISP, un environnement de programmation à la fois très bien intégré et accessible au plus grand nombre (malgré les spécificités du langage LISP). Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
didier Posté(e) le 2 mars 2019 Posté(e) le 2 mars 2019 Coucou Réponse au PS du message #35 Assurément Covadis a développé un partenariat avec AutoDesk et de ce fait ils participent à la situation de monopole de cette société (et en plus ils travaillent sur MAP)Je n'ai aucune idée des tarifs ni de la façon de faire de Bentley à propos de MicroStation, impossible de te répondre Amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
(gile) Posté(e) le 2 mars 2019 Posté(e) le 2 mars 2019 Revenons à nos moutons. Tout d'abord un grand bravo à ceux qui s'accrochent en LISP. Je pense que challenge est difficile mais très intéressant. De mon côté j'ai un peu avancé, ça fonctionne désormais avec les droites, les demi-droites, les lignes et les segments droits de polyligne (toujours dans le plan XY du SCG). J'ai aussi essayé de rendre le code plus robuste pour pouvoir gérer tout éventualité et préparer le terrain pour les arcs (même s'il n'est pas sûr que je le fasse). Plutôt que de déterminer l'arc généré en fonction des points de sélection des segments (comme semble le faire Microstation) j'ai préféré proposer la possibilité de parcourir les différentes solutions (uniquement 2 pour les segments droits) en validant l'option par défaut : "arc Suivant". Pour ceux qui veulent tester, télécharger et installer ArcExtensionSetup.msi. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
lrdb@home Posté(e) le 2 mars 2019 Posté(e) le 2 mars 2019 Par exemple, l'API COM d'AutoCAD (la seule utilisable par le VBA AutoCAD) présente, à mon sens de graves lacunes (absence d'objets Point2D ou Point3D, pitoyable gestion des jeux de sélection, ...) Ok gile , je comprends mieux ton avis sur vba avec AutoCAD Sur Microstation, je n'ai utilisé que le vba , mdl c++, bien trop compliqué pour moi et ce n'est pas mon métiermais le vba ou plutot mvba y est très complet à mes yeux , voici l'aide incomplète , des point 2d 3d , des matrices , des matrices de transformation intégrées ... Ton œil expert y trouvera , je pense, pas mal de choses intéressantes , ou pas write a book about what ??
(gile) Posté(e) le 2 mars 2019 Posté(e) le 2 mars 2019 Pour ceux que ça intéresse, le code avec quelques commentaires. La classe Commands où est définie la commande ARCTAN et des méthodes pour la sélection des segments. using System.Collections.Generic; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.GraphicsInterface; using Autodesk.AutoCAD.Runtime; using AcAp = Autodesk.AutoCAD.ApplicationServices.Core.Application; using AcDb = Autodesk.AutoCAD.DatabaseServices; [assembly: CommandClass(typeof(Gile.AutoCAD.ArcExtension.Commands))] namespace Gile.AutoCAD.ArcExtension { public class Commands { static TransientManager transientMgr; static List<Drawable> drawables; /// <summary> /// Commande pour dessiner un arc tangent à deux entités rectilignes. /// </summary> [CommandMethod("ARCTAN")] public static void ArcTangent() { var doc = AcAp.DocumentManager.MdiActiveDocument; var db = doc.Database; var ed = doc.Editor; var ucs = ed.CurrentUserCoordinateSystem; transientMgr = TransientManager.CurrentTransientManager; drawables = new List<Drawable>(); try { string errMsg; if (!TrySelectSegment(ed, "\nSélectionnez le premier segment: ", out Line2d line1, out errMsg)) { ed.WriteMessage(errMsg); return; } if (!TrySelectSegment(ed, "\nSélectionnez le second segment: ", out Line2d line2, out errMsg)) { ed.WriteMessage(errMsg); return; } if (line1.IsColinearTo(line2)) { ed.WriteMessage("Les segments sont colinéaires"); return; } using (var tr = db.TransactionManager.StartTransaction()) using (var arc = new Arc()) { var jig = new ArcJig(arc, line1, line2); var status = PromptStatus.Keyword; while (status == PromptStatus.Keyword) { var result = ed.Drag(jig); status = result.Status; if (status == PromptStatus.OK && arc.EndAngle - arc.StartAngle != 0.0) { var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); curSpace.AppendEntity(arc); tr.AddNewlyCreatedDBObject(arc, true); } } tr.Commit(); } } catch(System.Exception ex) { ed.WriteMessage($"\n{ex.Message}\n{ex.StackTrace}"); } finally { if (drawables.Count > 0) { foreach (var drawable in drawables) { transientMgr.EraseTransient(drawable, new IntegerCollection()); drawable.Dispose(); } } } } /// <summary> /// Invite l'utilisateur à sélectionner une entité ou un segment linéaire. /// </summary> /// <param name="ed">Editeur courant.</param> /// <param name="message">Message d'invite.</param> /// <param name="line2d">Droite directrice du segment (output).</param> /// <param name="errMsg">Message d'erreur (output).</param> /// <returns>true, si la sélection est valide ; false, sinon.</returns> static bool TrySelectSegment(Editor ed, string message, out Line2d line2d, out string errMsg) { line2d = null; errMsg = null; var peo = new PromptEntityOptions(message); peo.SetRejectMessage("\nL'objet séléctionné n'est pas une droite, une demi droite, une ligne ou une polyligne."); peo.AddAllowedClass(typeof(Line), true); peo.AddAllowedClass(typeof(AcDb.Polyline), true); peo.AddAllowedClass(typeof(Xline), true); peo.AddAllowedClass(typeof(Ray), true); var per = ed.GetEntity(peo); if (per.Status != PromptStatus.OK) { errMsg = "*Annuler*"; return false; } var id = per.ObjectId; var ucs = ed.CurrentUserCoordinateSystem; var plane = new Plane(); using (var tr = new OpenCloseTransaction()) { if (id.ObjectClass == RXObject.GetClass(typeof(Xline))) { var xline = (Xline)tr.GetObject(id, OpenMode.ForRead); if (xline.BasePoint.Z != 0.0 || xline.UnitDir.Z != 0) { errMsg = "La droite n'est pas sur le plan XY du SCG"; return false; } line2d = new Line2d(xline.BasePoint.Convert2d(plane), xline.UnitDir.Convert2d(plane)); } else if (id.ObjectClass == RXObject.GetClass(typeof(Ray))) { var ray = (Ray)tr.GetObject(id, OpenMode.ForRead); if (ray.BasePoint.Z != 0.0 || ray.UnitDir.Z != 0) { errMsg = "La demi-droite n'est pas sur le plan XY du SCG"; return false; } line2d = new Line2d(ray.BasePoint.Convert2d(plane), ray.UnitDir.Convert2d(plane)); AddTransientRay(ray.BasePoint, ray.UnitDir.Negate()); } else if (id.ObjectClass == RXObject.GetClass(typeof(Line))) { var line = (Line)tr.GetObject(id, OpenMode.ForRead); if (line.StartPoint.Z != 0.0 || line.EndPoint.Z != 0.0) { errMsg = "La ligne n'est pas sur le plan XY du SCG"; return false; } line2d = new Line2d(line.StartPoint.Convert2d(plane), line.EndPoint.Convert2d(plane)); AddTransientRay(line.StartPoint, line.EndPoint.GetVectorTo(line.StartPoint).GetNormal()); AddTransientRay(line.EndPoint, line.StartPoint.GetVectorTo(line.EndPoint).GetNormal()); } else { var pline = (AcDb.Polyline)tr.GetObject(id, OpenMode.ForRead); if (pline.Normal != Vector3d.ZAxis || pline.Elevation != 0) { errMsg = "La polyligne n'est pas sur le plan XY du SCG"; return false; } var pt = pline.GetClosestPointTo(per.PickedPoint.TransformBy(ucs), false); int index = (int)pline.GetParameterAtPoint(pt); if (pline.GetSegmentType(index) != SegmentType.Line) { errMsg = "Le segment sélectionné n'est pas linéaire"; return false; } line2d = pline.GetLineSegment2dAt(index).GetLine(); AddTransientRay(pline.GetPoint3dAt(index), pline.GetPoint3dAt(index + 1).GetVectorTo(pline.GetPoint3dAt(index)).GetNormal()); AddTransientRay(pline.GetPoint3dAt(index + 1), pline.GetPoint3dAt(index).GetVectorTo(pline.GetPoint3dAt(index + 1)).GetNormal()); } return true; } } /// <summary> /// Ajoute une demi-droite transitoire. /// </summary> /// <param name="point">Point de départ de la demi-droite.</param> /// <param name="vector">Direction de la demi-droite.</param> static void AddTransientRay(Point3d point, Vector3d vector) { var ray = new Ray() { BasePoint = point, UnitDir = vector }; ray.ColorIndex = 8; drawables.Add(ray); transientMgr.AddTransient(ray, TransientDrawingMode.Highlight, 128, new IntegerCollection()); } } } La classe ArcJig, c'est là que tout se passe. using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; namespace Gile.AutoCAD.ArcExtension { /// <summary> /// Fournit les méthodes pour afficher dynamiquement un arc tangent à deux segments passant par la position du curseur. /// </summary> class ArcJig : EntityJig { Arc arc; Point3d dragPt; Line2d line1, line2, axis; int index = 0; /// <summary> /// Crée une nouvelle instance de ArcJig. /// </summary> /// <param name="arc">Instance de Arc à mettre à jour dynamiquement.</param> /// <param name="line1">Première droite de tangence.</param> /// <param name="line2">Seconde droite de tangence.</param> public ArcJig(Arc arc, Line2d line1, Line2d line2) : base(arc) { this.arc = arc; this.line1 = line1; this.line2 = line2; axis = new Line2d(); } /// <summary> /// Invite l'utilisateur à spécifier un point ou à faire défiler les arcs possibles. /// </summary> /// <param name="prompts">Aquisition des données.</param> /// <returns>Le résultat de l'invite.</returns> protected override SamplerStatus Sampler(JigPrompts prompts) { var options = new JigPromptPointOptions("\nSpécifiez un point sur l'arc ou [arc Suivant]: ", "Suivant"); options.Keywords.Default = "Suivant"; options.UserInputControls = UserInputControls.NullResponseAccepted; var result = prompts.AcquirePoint(options); if (result.Status == PromptStatus.Keyword) { index++; return SamplerStatus.OK; } else { if (result.Value.IsEqualTo(dragPt)) return SamplerStatus.NoChange; dragPt = result.Value; return SamplerStatus.OK; } } /// <summary> /// Met à jour l'arc en fonction du résultat à l'invite. /// </summary> /// <returns>true.</returns> protected override bool Update() { var point = dragPt.Convert2d(new Plane()); var arcs = GetTangentArcs(point); if (arcs == null) { arc.StartAngle = arc.EndAngle = 0.0; } else { var arc2d = arcs[index % arcs.Length]; arc.Center = new Point3d(arc2d.Center.X, arc2d.Center.Y, 0.0); if (arc2d.Radius > 0.0) arc.Radius = arc2d.Radius; arc.StartAngle = arc2d.StartAngle + arc2d.ReferenceVector.Angle; arc.EndAngle = arc2d.EndAngle + arc2d.ReferenceVector.Angle; } return true; } /// <summary> /// Définit l'axe de symétrie entre les deux droites en fonction de la position du point. /// </summary> /// <param name="point">Point déterminant le secteur de l'axe.</param> void SetAxis(Point2d point) { if (line1.IsOn(point) || line2.IsOn(point)) return; if (line1.IsParallelTo(line2)) { var pt = line1.PointOnLine; var segment = new LineSegment2d(pt, line2.GetClosestPointTo(pt).Point); axis = new Line2d(segment.MidPoint, line1.Direction); } else { var intersPt = line1.IntersectWith(line2)[0]; if (intersPt.IsEqualTo(point)) return; var dir = intersPt.GetVectorTo(point); var dir1 = line1.Direction; var dir2 = line2.Direction; if (IsClockWise(dir, dir1)) { if (IsClockWise(dir, dir2)) axis = new Line2d(intersPt, dir1 + dir2.Negate()); else axis = new Line2d(intersPt, dir1 + dir2); } else { if (IsClockWise(dir, dir2)) axis = new Line2d(intersPt, dir1 + dir2); else axis = new Line2d(intersPt, dir1 + dir2.Negate()); } } } /// <summary> /// Evalue si les vecteurs tournent en sens horaire. /// </summary> /// <param name="v1">Premier vecteur.</param> /// <param name="v2">Second vecteur.</param> /// <returns>true, si le sens de rotation est le sens horaire ; false, sinon.</returns> bool IsClockWise(Vector2d v1, Vector2d v2) => v1.X * v2.Y - v2.X * v1.Y < 0.0; /// <summary> /// Calcule les arcs tangents aux deux droites passant par le point. /// </summary> /// <param name="point">Point de passage des arcs.</param> /// <returns>Une collection d'arcs ou null en cas d'impossibilité géométrique</returns> CircularArc2d[] GetTangentArcs(Point2d point) { SetAxis(point); var perp = axis.GetPerpendicularLine(point); var inters = axis.IntersectWith(perp); if (inters == null) return null; var cen = inters[0]; inters = perp.IntersectWith(line1); if (inters == null) return null; var pt1 = inters[0]; inters = perp.IntersectWith(line2); if (inters == null) return null; var pt2 = inters[0]; var tol = new Tolerance(1e-8, 1e-6); double radius; CircularArc2d arc2d; if (point.IsEqualTo(pt1, tol)) { cen = line1.GetPerpendicularLine(pt1).IntersectWith(axis)[0]; radius = cen.GetDistanceTo(pt1); if (radius == 0.0) return null; var vector = axis.Direction * radius; pt2 = pt1.Mirror(axis); arc2d = new CircularArc2d(pt1, cen - vector, pt2); if (arc2d.IsClockWise) return new[] { new CircularArc2d(pt2, cen - vector, pt1), new CircularArc2d(pt1, cen + vector, pt2) }; else return new[] { arc2d, new CircularArc2d(pt2, cen + vector, pt1) }; } if (point.IsEqualTo(pt2, tol)) { cen = line2.GetPerpendicularLine(pt2).IntersectWith(axis)[0]; radius = cen.GetDistanceTo(pt2); if (radius == 0.0) return null; var vector = axis.Direction * radius; pt1 = pt2.Mirror(axis); arc2d = new CircularArc2d(pt1, cen - vector, pt2); if (arc2d.IsClockWise) return new[] { new CircularArc2d(pt2, cen - vector, pt1), new CircularArc2d(pt1, cen + vector, pt2) }; else return new[] { arc2d, new CircularArc2d(pt2, cen + vector, pt1) }; } if (point.IsEqualTo(cen)) { radius = pt1.GetDistanceTo(cen); } else { var c1 = new CircularArc2d(cen, cen.GetDistanceTo(point)); var seg = new LineSegment2d(cen, pt1); var c2 = new CircularArc2d(seg.MidPoint, seg.Length / 2.0); inters = c1.IntersectWith(c2); if (inters == null) return null; radius = pt1.GetDistanceTo(inters[0]); } pt2 = pt1 - line1.Direction * radius; pt1 += line1.Direction * radius; arc2d = new CircularArc2d(pt1, point, pt1.Mirror(axis)); if (arc2d.IsClockWise) return new[] { new CircularArc2d(pt1.Mirror(axis), point, pt1), new CircularArc2d(pt2, point, pt2.Mirror(axis)) }; else return new[] { arc2d, new CircularArc2d(pt2.Mirror(axis), point, pt2) }; } } } 2 Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
lecrabe Posté(e) le 2 mars 2019 Auteur Posté(e) le 2 mars 2019 Hello Gilles (et Didier) *** Pour Gilles *** 1) C BEAU ! 2) Presenter les multiples solutions (2 en fait) C TOP ! 3) Si jamais tu reussis a le faire depuis des Arcs ou Cercles (ou Arcs dans des Polylignes), ce sera presque comme sur MicroStation !? *** Pour Didier et TOUS *** 4) RAPPEL COVADIS 1 : COVADIS n'exige pas un AutoCAD MAP !Environ 70-80% des Covadis tournent par dessus AutoCAD MAP Et le reste par dessus : ACAD , ACAD Architecture , ACAD CIVIL ... 5) RAPPEL COVADIS 2 : Mais la preparation SIG ESRI Shape, Import / Export IMX pour communiquer avec InfraWorks, exigent un AutoCAD MAP !! Bye, lecrabe 1 Autodesk Expert Elite Team
lrdb@home Posté(e) le 2 mars 2019 Posté(e) le 2 mars 2019 Et au fait dans quels domaines / fonctions AutoCAD est "meilleur" que USTN (SANS ajout de routines LSP) ?? se vendre ?? write a book about what ??
Matt666 Posté(e) le 2 mars 2019 Posté(e) le 2 mars 2019 Dac avec lecrabe, C'est beau.. @gile : Pardonne mon ignorance, je ne connais rien en C#/.NET : - De manière générale quel est l'intérêt d'écrire en .net plutôt qu'en Lisp en dehors du côté "temps réel" (là tu vas me sortir un sujet écrit en 2012, je le sens bien ! ^^ )- Tu écris ça sur quoi ? J'ai cru lire ici que tu conseillais les versions Express gratuites Visual C# Express ou Visual VB Express. - Je suppose que tu compiles en .msi (ou .exe d'ailleurs) avec ce même outil ? Merci ! "Chacun compte pour un, et nul ne compte pour plus d'un."
(gile) Posté(e) le 2 mars 2019 Posté(e) le 2 mars 2019 - De manière générale quel est l'intérêt d'écrire en .net plutôt qu'en Lisp en dehors du côté "temps réel" (là tu vas me sortir un sujet écrit en 2012, je le sens bien ! ^^ )L'intérêt principal, c'est la puissance, pas tant en terme de rapidité d'exécution qu'en possibilités (APIs) offertes. Ici, par exemple, j'utilise les méthodes et propriétés d'objets purement géométriques (Point2d, Vector2d, Line2d, CircularArc2d, etc) qui facilitent grandement les différentes opérations tout en allégeant considérablement les besoins en ressource. Tu peux lire ce sujet. - Tu écris ça sur quoi ? J'ai cru lire ici que tu conseillais les versions Express gratuites Visual C# Express ou Visual VB Express.J'utilise Visual Studio Community 2017, l'IDE gratuit de Microsoft reconnu (même par des anti M$) comme étant le meilleur IDE du moment. - Je suppose que tu compiles en .msi (ou .exe d'ailleurs) avec ce même outil ?Les plugins AutoCAD sont compilé en DLL, mais on peut aussi compiler des EXE, des MSI etc. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Matt666 Posté(e) le 2 mars 2019 Posté(e) le 2 mars 2019 Super, merci gile. C'est vrai que le .net semble intéressant et surtout l'apprendre peut s'avérer non négligeable puisqu'utilisé un peu partout. "Chacun compte pour un, et nul ne compte pour plus d'un."
Messages recommandé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 compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant