Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 12/15/2025 in all areas

  1. Attempt number 2: This code is intended to always return a centerline whose points are all perfectly equidistant from the margins. This should happen in all cases where two LWPOLYLINEs are provided, one for each margin. The case of islands has not been considered yet. The resulting centerline is geometrically dense. This can probably be simplified in a future version. The approach taken in this code has been to obtain points from the normals and the bisectors of each margin, which are then combined at the end to build a list of points. Therefore, it is a fragmentary and massive approach. For this reason, the code is not very fast. However, there is another, more elegant approach, based on dynamically relating the geometry of both margins. It is more complex, but it would also be faster, and the error margins would be “bridgable”. If this thread has enough life in it, I may feel sufficiently motivated to finish it. That’s all for now. ;|*********************** CENTER-LINE ************************* ************************ G L A V C V S ************************* ************************** F E C I T *************************** |; (defun c:CLG (/ PI/2 lst e1 e2 l1 l2 lp lp1 lp2 p0 p> p< r1? x m a tol autoInt? ordenaPts interCpta ptEqd) (defun autoInt? (l lp / p0 p1 p2);autointersecci贸n? (if l (setq p1 (polar (car l) (setq a (angle (car l) (cadr l))) 0.001) p2 (polar (cadr l) (+ a PI) 0.001) x (if (not (vl-some '(lambda (p) (if p0 (inters p0 (setq p0 p) p1 p2) (not (setq p0 p)))) lp)) l) ) ) ) (defun ordenaPts (lst / pIni dm d ps? ps lr); puntos en orden (setq pIni (mapcar '(lambda (a b) (/ (+ a b) 2.0)) (car lp1) (car lp2))) (while lst (foreach p lst (if (and dm (/= (min (setq d (distance (if ps ps pIni) p)) dm) dm)) (setq dm d ps? p) (if (not dm) (setq dm (distance (if ps ps pIni) p) ps? p)) ) ) (setq ps ps? ps? nil dm nil lst (vl-remove ps lst) lr (cons (cadr ps) (cons (car ps) lr))) ) lr ) (defun interCpta (pM p1 p2 lp / i? i1 i2 d a b); captura de los m谩rgenes (defun i? (pA pB lp / p0 i dm is a) (foreach p lp (if p0 (if (setq i (inters p0 (setq p0 p) pA pB)) (if (and dm (/= (min (setq d (distance pM i)) dm) dm)) (setq dm d is i) (if (not dm) (setq dm (distance pm i) is i)) ) ) ) (setq p0 p) ) (if is (list (car is) (cadr is) 0.0)) ) (if (and (setq a (i? p1 p2 lp1)) (setq b (i? p1 p2 lp2))) (list a b) ) ) (defun ptEqd (A B e1 e2 / eqDist-f t0 t1 f0 f1 tm fm n i v+- v*); captura punto equidistante (defun v+- (o a b) (mapcar o a b)) (defun v* (p s) (mapcar '(lambda (x) (* x s)) p)) (defun eqDist-f (ds A B e1 e2 / pt d1 d2) (setq pt (v+- '+ A (v* (v+- '- B A) ds)); Punto sobre AB: P(ds) = A + ds (B - A) d1 (distance pt (vlax-curve-getClosestPointTo e1 pt)) d2 (distance pt (vlax-curve-getClosestPointTo e2 pt)) ) (- d1 d2) ) (setq t0 0.0 t1 1.0) (while (and (< (setq n (if n (1+ n) 0)) 100) (> (- t1 t0) 1e-6));m茅todo de bisecci贸n (setq tm (/ (+ t0 t1) 2.0) fm (eqDist-f tm A B e1 e2) ) (if (< (abs fm) 1e-9) (setq n 100 t1 tm t0 tm) (if (< (* (if f0 f0 (eqDist-f t0 A B e1 e2)) fm) 0.0) (setq t1 tm f1 fm) (setq t0 tm f0 fm) ) ) ) (if (< t1 1.0) ; par谩metro final y punto equidistante (v+- '+ A (v* (v+- '- B A) (/ (+ t0 t1) 2.0))) ) ) (if (and (setq e1 (car (entsel "\nSelect FIRST LWPolyline..."))) (= (cdr (assoc 0 (setq l1 (entget e1)))) "LWPOLYLINE") ) (if (and (setq e2 (car (entsel "\nSelect SECOND LWPolyline..."))) (= (cdr (assoc 0 (setq l2 (entget e2)))) "LWPOLYLINE") ) (progn (foreach l l1 (if (= (car l) 10) (setq lp1 (cons (cdr l) lp1)))) (foreach l l2 (if (= (car l) 10) (setq lp2 (cons (cdr l) lp2)))) (setq r1? (> (distance (car lp1) (car lp2)) (distance (car lp1) (last lp2)))) (setq tol 0.01 PI/2 (/ PI 2.) lp1 (if r1? (reverse lp1) lp1)) (foreach e (list e1 e2) (setq p0 nil m nil r? (if (equal e e1) r1?) lp (if (equal e e1) lp2 lp1)) (while (setq p (vlax-curve-getPointAtParam e (setq m (if m ((if r? 1- 1+) m) (if r? (vlax-curve-getEndParam e) 0))))) (if p0 (progn (setq lAB (autoInt? (interCpta p (polar p (setq a (+ (angle p0 p) PI/2)) 10000) (polar p (+ a PI) 10000) lp) (if (equal e e1) lp1 lp2));NORMAL AL COMIENZO DEL SEGMENTO lst (if lAB (cons (ptEqd (car lAB) (cadr lAB) e1 e2) lst) lst) ) (if (setq p> (vlax-curve-getPointAtParam e ((if r? 1- 1+) m))) (setq lAB (autoInt? (interCpta p (polar p (setq a (/ (+ (angle p p0) (angle p p>)) 2.)) 10000) (polar p (+ a PI) 10000) lp) (if (equal e e1) lp1 lp2)) ; Bisectriz lst (if lAB (cons (ptEqd (car lAB) (cadr lAB) e1 e2) lst) lst) lAB (autoInt? (interCpta p (polar p (setq a (+ (angle p p>) PI/2)) 10000) (polar p (+ a PI) 10000) lp) (if (equal e e1) lp1 lp2));NORMAL AL FINAL DEL SEGMENTO lst (if lAB (cons (ptEqd (car lAB) (cadr lAB) e1 e2) lst) lst) ) ) (setq p< p0 p0 p) ) (if (setq p> (vlax-curve-getPointAtParam e ((if r? 1- 1+) m))) (setq lAB (autoInt? (interCpta p (polar (setq p0 p) (setq a (+ (angle p0 p>) PI/2)) 10000) (polar p0 (+ a PI) 10000) lp) (if (equal e e1) lp1 lp2)) lst (if lAB (cons (ptEqd (car lAB) (cadr lAB) e1 e2) lst) lst) ) ) ) ) ) (vla-AddLightWeightPolyline (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))) (vlax-Make-Variant (vlax-SafeArray-Fill (vlax-Make-SafeArray 5 (cons 0 (- (length (setq lst (reverse (ordenaPts lst)))) 1))) lst)) ) ) ) ) (princ) )
    5 points
  2. Note that you can use my Layer Director to preset & reset a layer (including layer creation) for both standard and custom commands: https://lee-mac.com/layerdirector.html
    2 points
  3. (vl-catch-all-apply) is used to catch the error when the user presses Esc during the selection prompt, ensuring NOMUTT is set back to 0.
    1 point
  4. I know this is an old thread but here it is my fifty cents attempt, I was looking for a created solution but had to complete it, thanks to all ;;; By Isaac A. 20251219 ;;; https://www.cadtutor.net/forum/topic/73414-select-all-points-on-polyline/ ;;; Point on Polyline 'ptopl' (vl-load-com) (defun c:ptopl (/ a b c d dw l oc os) (vla-startundomark (setq dw (vla-get-activedocument (vlax-get-acad-object)))) (setq oc (getvar 'cmdecho) os (getvar 'osmode) ) (setvar 'cmdecho 0) (setvar 'osmode 0) (princ "\nSelect the polylines that touch the points") (setq l (ssget (list (cons 0 "LWPOLYLINE")))) (if l (progn (setq a 0 ) (while (< a (sslength l)) (setq b (entget (ssname l a)) c (append c (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) b))) a (1+ a) ) (setq d (ssget "F" c (list (cons 0 "Point")))) (sssetfirst nil d) ) ) (princ "\nThere are no selected polylines") ) (setvar 'cmdecho oc) (setvar 'osmode os) (vla-endundomark dw) (princ) ) ;;; End ptopl
    1 point
  5. I am like others as suggested dont use a command word, as your wanting to use a defun then why not just call the defun something shorter, like CENTL.You can use AUTOLOAD to load the actual lisp at the first time you type centl. You would put the "Autoload" in say a custom lisp that is loaded on startup, along with your other AUTOLOAD's (autoload "CENTL" '("CENTL")) (autoload "COPY0" '("COPY0")) (autoload "COPYCOMMAND" '("ZZZ")) (autoload "COVER" '("COVER"))
    1 point
  6. Why did you report my post? It was meant for an example for you to learn to help yourself. Do you even know what you want? Your first example drawing doesn't show XYZ for the "NEED SOMETHING LIKE AT ALL POINT". Not sure why you want someone to do a bunch of work for you for free and you can't be bothered to provide a well though out request and provide appropriate examples and comments.
    1 point
  7. Not quite sure what the question is to be 'exactly like 2' - is it the text to be offset to one side? (only difference I can see really), else EnM4st3r works for me. If you want to offset the text from the selected point, use the mapcar function, have a go at changing the code offered perhaps changing this line (vla-addmtext (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))) (vlax-3d-point pt) 0 str) use (mapcar '+ '(x y z) pt) instead of pt where x, y and z are the offset distances (numbers) in each direction Hint with LISPs, 'pt' or very similar is often used as a variable for a point, you can check earlier in the code to confirm, getpoint is the LISP command to return a selected point, pt is set to be the output from getpoint... so a good guess would be this is the point to change Have a go, your first steps to write LISPs is to try, if it all goes wrong ask and we are all more than happy to guide you if you are happy to change things yourself.
    1 point
  8. @pavanetc he meant for you to try it yourself. since its not that difficult. Just look into ssget and selectionset looping
    1 point
  9. If the points are not to be moved @EnM4st3r has given you an answer, a little homework for you is a lisp task, change the (while to use a Selection set and a (repeat then all done.
    1 point
  10. If you have multiple viewports in a layout, then using chspace have to nominate which viewport you are looking at. Will see if can edit code bit busy at moment.
    1 point
  11. Are you using AutoCAD 2010? Along with previous suggestions and to add, you can do a lot of cleaning with the WBLOCK @ReMark, best method for true cleaning is to WBLOCK just the selected/visible objects you need, that way some of the things mentioned by @CyberAngel are hopefully not carried to the new drawing. I always start with -EXPORTTOAUTOCAD to clean up objects left by verticals, etc.
    1 point
  12. You can just use the following entry in the layer list to achieve the result you require: ("CENTERLINE" "CENTERLINE" "" 7 "Continuous" -3 1 nil )
    1 point
  13. The " . " is the only thing stopping your lisp from running the first 25 lines of your code in an infinite loop. If you gave that lisp to someone them typing centerline in the command prompt would run your code not the default centerline command. as it is "overwritten" I'll post some examples tonight. but off the top of my head I created shortcuts to commands like ;;----------------------------------------------------------------------------;; ;; Create Cricle from picking 3 Points (defun C:C3P () (command "._CIRCLE" "_3P"))
    1 point
  14. One I can think of is to WBLOCK the entire drawing out to a new file name (temporarily) then compare the file sizes.
    1 point
  15. mhupp, Your suggestion and generous code submission are both very well received: Thank you! I will rework the "robot" program code to include your superior code lines. Questions Outside of the important warning applied to LISP programming and variables, Can you or others give an example(s) of instances of how a programmer/customizer can modify default commands? Would this action be limited to creating macro code lines to assign to custom buttons? Future After stalling out, I am now at a DWG-based design environment and will resume my LISP programming studies. I was recently encouraged by understanding how to use the built-in IDE. P.S.: My thanks go out to the excellent developer and programmed systems just developed from a longtime fellow member of other forums and entrepreneur running https://cadprograms.ca/ Thanks, Clint
    1 point
  16. Just use a point and insert Field in Mtext and format it how you want. When copying both point and text it will keep the new copied items linked. Regen to update the coordinates.
    1 point
  17. You can also use fields with selection of points? (defun make_field (ent / pt obj) (setq pt (trans (cdr (assoc 10 (entget ent))) 1 0)) (mapcar '(lambda (lx) (apply '(lambda (ins_point value_field att_point txt_height dwg_dir name_layer txt_rot / nw_obj) (setq nw_obj (vla-addMtext Space (vlax-3d-point (trans ins_point 1 0)) 0.0 (strcat "{\\f@Arial Unicode MS|b0|i0|c0|p34;\\Q15;" "%<\\AcObjProp.16.2 Object(%<\\_ObjId " (itoa (vla-get-ObjectID (vlax-ename->vla-object ent))) value_field "}" ) ) ) (mapcar '(lambda (pr val) (vlax-put nw_obj pr val) ) (list 'AttachmentPoint 'Height 'DrawingDirection 'InsertionPoint 'Layer 'Rotation) (list att_point txt_height dwg_dir ins_point name_layer txt_rot) ) ) lx ) ) (list (list (mapcar '+ (trans pt 1 0) (list (getvar "TEXTSIZE") (+ (* (getvar "TEXTSIZE") 1.25) (getvar "TEXTSIZE")) 0.0)) ">%).Coordinates \\f \"%lu2%pt1%pr3%ps[X:,]\">%" 4 (getvar "TEXTSIZE") 5 "Id-XY" rtx ) (list (mapcar '+ (trans pt 1 0) (list (getvar "TEXTSIZE") 0.0 0.0)) ">%).Coordinates \\f \"%lu2%pt2%pr3%ps[Y:,]\">%" 4 (getvar "TEXTSIZE") 5 "Id-XY" rtx ) (list (mapcar '- (trans pt 1 0) (list (- (getvar "TEXTSIZE")) (+ (* (getvar "TEXTSIZE") 1.25) (getvar "TEXTSIZE")) 0.0)) ">%).Coordinates \\f \"%lu2%pt4%pr3%ps[Z:,]\">%" 4 (getvar "TEXTSIZE") 5 "Id-Z" rtx ) ) ) ) (defun c:point-xyz_field ( / htx rtx AcDoc Space ncol ss n) (initget 6) (setq htx (getdist (getvar "VIEWCTR") (strcat "\nSpecify the height of the field <" (rtos (getvar "TEXTSIZE")) ">: "))) (if htx (setvar "TEXTSIZE" htx)) (if (not (setq rtx (getorient (getvar "VIEWCTR") "\nSpecify the orientation of the field <0.0>: "))) (setq rtx 0.0)) (vl-load-com) (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object)) Space (if (= 1 (getvar "CVPORT")) (vla-get-PaperSpace AcDoc) (vla-get-ModelSpace AcDoc) ) ncol '(96 174) ) (foreach n '("Id-XY" "Id-Z") (cond ((null (tblsearch "LAYER" n)) (vlax-put (vla-add (vla-get-layers AcDoc) n) 'color (car ncol)) ) ) (setq ncol (cdr ncol)) ) (while (null (setq ss (ssget '((0 . "POINT")))))) (repeat (setq n (sslength ss)) (make_field (ssname ss (setq n (1- n)))) ) (prin1) )
    1 point
  18. Yes. I know. I already mentioned that this problem could arise on some long segments during turns. I didn't want to delay posting again to fix this. But I already have an idea of how to solve it. I'll post the solution as soon as I can.
    1 point
  19. I tested the code. All the points are equidistant, but there are two long segments where the equidistance is drastically broken. In the last screenshot Dexus attached, you can see approximately where the center line should be in that area. The center line returned by the GLAVCVS code is shown in magenta. And the approximate location where it should be is shown in red. I've attached an image of this
    1 point
  20. Obviously, this has now become something more than just the search for a solution to a single user’s problem. First of all, I should say that I myself was also reluctant to accept the concept of equidistance advocated by @GP_ and @dexus For the simple reason that applying this principle forced me to accept that the centerline should be the same in these two drawings. Equidistance requires ignoring those areas of the margins that do not geometrically affect the axis. This, which initially caused me some resistance, I eventually came to accept conceptually when I realized that it could serve as a criterion for defining what is a “recodo/inlet” and what is not. So I have abandoned my previous approach and adapted it to this new situation. Having made this clarification, I must say that this concept of equidistance makes the calculation of a centerline more feasible. I’ve been running some tests with Dexus’s latest code, which is the best so far. However, I’ve discovered some “holes” that I hadn’t noticed before. I’m attaching a few images showing this. In my view, these are conceptual errors rather than geometric limitations. And what can we consider “geometric limitations”? I believe that, in any case, every vertex of the centerline must be equidistant from both margins. If this is not the case, the result is not correct. However, the intermediate regions along each segment may be subject to geometric limitations depending on the desired precision. Therefore, in bends or turns, the points taken within the adjustment or “problematic” segments may deviate (within a tolerance) from strict equidistance. The goal, therefore (in my opinion), should be to achieve equidistance at every vertex and to remain within a tolerance in the intermediate zone of each segment. After everything written here so far, some might wonder: is it really possible to obtain a centerline that meets these requirements? As far as I’m concerned, I’m running some tests. GusanoAcad.mp4 I’ll post something over the weekend
    1 point
  21. One option is to xref both drawings into a third, plotting only, drawing. You can then control the layer states, transparency, and draw order of both without affecting the originals. A similar option is to create two viewports, one for each plan. You can change the transparency of the layer your xref is on, and the viewport will inherit it. You still have the option to change layer states and draw order.
    1 point
  22. Another: (defun c:foo (/ n p s) (if (setq s (ssget '((0 . "LWPOLYLINE")))) (foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex s))) (setq n 0) (while (setq p (vlax-curve-getpointatparam e n)) (entmakex (list '(0 . "POINT") (cons 10 p))) (setq n (+ n 0.5)) ) ) ) (princ) )
    1 point
  23. When you are trying tricks like these AutoCAD is very fussy that you do things correctly, in your block there are no actions that match up with you linear parameters, there also needs to be an object selected for those actions, watch that second video you linked too at about the 5.30 minute position your parameters also need to be set as a list of defined measurements. This is a tricky subject to get the hang of, but well worth the effort. And a tip it is much easier to keep your linear parameters horizontal and stacked above each other as in that video it just makes it easier to see what is what and keep your actions organised as well.
    1 point
  24. I recently had a student message me regarding the title block and border asking for help drawing it. Of everything the student is asked to draw for this project the title block and border should be the easiest task to accomplish. The full instructions are on page 16 under the heading "Preparing the plat map for plotting." The student is given the overall size of the drawing (24x36), the minimum offset from the cutting edge to the border (1/2") and the offsets for the title block area at the bottom of the sheet. Note that I elected to increase the left hand offset from 1/2" to 1". I've reproduced them here for your benefit. Note: the colors I used are for display purposes only and may not be those called for in the instructions. Keep in mind that when you are finished the title block and border are going to be the size of a postage stamp compared to the subdivision or plat map. It has to be scaled up. A scale factor of 50 will do quite nicely. Once the title block and border has been saved as a block insert the block and specify the scale I just gave you then move the block into position around your plat map. Oleson Village and the surrounding streets should fit quite nicely in the area where you see the yellow "X" in the image above. The red dashed line is considered the cut line. The cyan colored lines are the border. Got it? Good. Now go do it. Warning: do NOT ask me to give my title block and border block. Ain't going to happen. No how...no way.
    1 point
×
×
  • Create New...