'cal button

Discussion in 'AutoCAD' started by Huw, Mar 2, 2004.

  1. Huw

    Huw Guest

    I use a custom button:

    _non;'cal;(cur+cur)/2;

    to pick a point midway between two cursor points. I know that I can change it to, for example:

    _non;'cal;(cur+cur+cur)/3;
    _non;'cal;(cur+cur+cur+cur)/4;

    etc.

    Is there an easy way to have one button that would work for any number of cursor points?
     
    Huw, Mar 2, 2004
    #1
  2. Huw

    TCEBob Guest

    From help:

    The following example uses the Center and Endpoint Snap modes in a CAL
    expression:

    (cen+end)/2

    CAL prompts for a circle or arc and an object. It then determines the
    midpoint between the center of the circle or arc and the end of the
    selected object.

    Using the Midpoint Snap mode, in the following example CAL prompts for
    an object and returns a point one unit in theY direction from the
    midpoint of the selected object:

    mid+[,1]

    The following example uses the Endpoint Snap mode to calculate the
    centroid of a triangle defined by three endpoints:

    (end+end+end)/3

    rs




    message I use a custom button:

    _non;'cal;(cur+cur)/2;

    to pick a point midway between two cursor points. I know that I can
    change it to, for example:

    _non;'cal;(cur+cur+cur)/3;
    _non;'cal;(cur+cur+cur+cur)/4;

    etc.

    Is there an easy way to have one button that would work for any number
    of cursor points?
     
    TCEBob, Mar 2, 2004
    #2
  3. Huw

    zeha Guest

    ;with this function perhaps
    ;the button command is
    (if middle (princ)(load "middle")) (middle)

    ;save the source code below to middle.lsp
    ;and place them in the search path

    (defun Middle ( / i pt ptlst)
    (setq i 0)
    (while (setq i (1+ i) pt (getpoint (if pt pt (getvar "lastpoint"))
    (strcat "\nPick "(itoa i) "e point for middle <return for stop> ")))
    (if (= (type pt) 'LIST)(setq ptlst (cons pt ptlst)))
    )
    (if ptlst
    (progn
    (setq itms (length ptlst))
    (list (/ (apply '+ (mapcar 'car ptlst)) itms)
    (/ (apply '+ (mapcar 'cadr ptlst)) itms)
    (/ (apply '+ (mapcar 'caddr ptlst)) itms))
    )
    )
    )
     
    zeha, Mar 2, 2004
    #3
  4. Huw

    nalsur8 Guest

    zeha u kat mana
     
    nalsur8, Mar 2, 2004
    #4
  5. Huw

    OLD-CADaver Guest

    I think he knows that. I think he's looking ofr a routine that will find the center of 3 picks or 7 picks or 15 picks. Something that will count the number of picks, then divide by that number.
     
    OLD-CADaver, Mar 2, 2004
    #5
  6. Huw

    TCEBob Guest

    Ok, he is looking for a button that will find the centroid of any number
    of picks. Sounds like a lisp routine to me unless there is some way to
    tell cal that you're done picking points. I believe you can use cal
    within lisp but haven't tried it. If so it should be easy to set up.

    rs

    find the center of 3 picks or 7 picks or 15 picks. Something that will
    count the number of picks, then divide by that number.
     
    TCEBob, Mar 2, 2004
    #6
  7. Huw

    Huw Guest

    I'm affraid that just freezes and eventually crashes AutoCAD for me. (Map 2004 on Win2K)
     
    Huw, Mar 2, 2004
    #7
  8. Huw

    Huw Guest

    ... unless there is some way to
    That's what would be needed, and it doesn't sound likely put like that. (I was thinking in terms of replacing the repeats of CUR+ and the divisor, with some sort of 'n' expression.)

    Thanks for thinking about it.

    Cheers,
    Huw
     
    Huw, Mar 2, 2004
    #8
  9. Huw

    Joe Burke Guest

    Just a thought... if anyone cares.

    Obviously the midpoint between two points returns a point equidistant between two
    points. In this case something like 'cal (cur+cur) / 2 is valid. Or the same thing
    using LISP.

    (defun MidPoint (p1 p2)
    (mapcar '* (mapcar '+ p1 p2) '(0.5 0.5 0.5))
    )

    But the same idea doesn't apply to three or more points, if you expect an equidistant
    point returned. Something like 'cal (cur+cur+cur) / 3 simply averages the point list.
    IMO it returns a useless point. You can find an equidistant point given three points,
    but not using this method.

    Joe Burke

    I use a custom button:

    _non;'cal;(cur+cur)/2;

    to pick a point midway between two cursor points. I know that I can change it to, for
    example:

    _non;'cal;(cur+cur+cur)/3;
    _non;'cal;(cur+cur+cur+cur)/4;

    etc.

    Is there an easy way to have one button that would work for any number of cursor
    points?
     
    Joe Burke, Mar 4, 2004
    #9
  10. Huw

    David Bethel Guest

    If the points are not collinear, why use CIRCLE->3P and the find the
    center of the circle. -David
     
    David Bethel, Mar 4, 2004
    #10
  11. Huw

    Joe Burke Guest

    Hi David,

    That's exactly what I meant, given three random points.

    I suspect Huw's original question is a bit off-target. It seems to assume the idea of
    averaging two points applies to more than two points. For example, zeha's function.

    Joe Burke
     
    Joe Burke, Mar 4, 2004
    #11
  12. Huw

    BillZ Guest

    It's a lisp and
    Not tested fully by me...
    May be what you want.

    ;3/13/03
    ;Joe Burke
    ;
    (defun AveragePts (ptlist)
    (if (null (caddr (car ptlist))) ;test first point for 2D point
    (setq ptlist (mapcar '(lambda (x) (append x '(0.0))) ptlist))
    )
    (mapcar '(lambda (ord)(/ ord (length ptlist) 1.0))
    (list
    (apply '+ (mapcar '(lambda (pt) (car pt)) ptlist))
    (apply '+ (mapcar '(lambda (pt) (cadr pt)) ptlist))
    (apply '+ (mapcar '(lambda (pt) (caddr pt)) ptlist))
    )
    )
    )

    Bill :)
     
    BillZ, Mar 4, 2004
    #12
  13. Huw

    Doug Broad Guest

    ;;Returns a point that represents the average
    ;;x,y, and z values of the selected points.
    ;;Hit return to finish selection. Osnap
    ;;mode may affect point placement if used
    ;;within a command.

    ;;Example: line 'mnp <pick><pick><pick><return> ....

    (defun c:mnp ( / pl p pll)
    ;;D. C. Broad, Jr. Demonstration 3/5/04
    (while (setq p (getpoint))
    (setq pl (cons p pl)))
    (setq pll (length pl))
    (mapcar '(lambda (x)(/ x pll))
    (apply 'mapcar (append '(+) pl))))



    I use a custom button:

    _non;'cal;(cur+cur)/2;

    to pick a point midway between two cursor points. I know that I can change it to, for example:

    _non;'cal;(cur+cur+cur)/3;
    _non;'cal;(cur+cur+cur+cur)/4;

    etc.

    Is there an easy way to have one button that would work for any number of cursor points?
     
    Doug Broad, Mar 4, 2004
    #13
  14. Huw

    zeha Guest

    see the first reply function middle
    is similar to c:mnp
     
    zeha, Mar 4, 2004
    #14
  15. Huw

    Joe Burke Guest

    Hi Doug,

    A related MP gem, which I'm sure you know. Maybe add filter out accidental duplicate
    side-by-side points picked?

    ;; by Michael Puckett
    ;; with rubber band between points
    (defun getpoints ( / p i pts)
    (cond
    ( (setq p (getpoint "\nPick first point: "))
    (setq pts (list p) i -1)
    (while (setq p (getpoint p "\nPick next point / [Enter] to end: "))
    (grdraw p (cadr (setq pts (cons p pts))) -1 1)
    )
    (repeat (1- (length pts))
    (grdraw (nth (setq i (1+ i)) pts) (nth (1+ i) pts) -1 1)
    )
    (reverse pts)
    )
    )
    ) ;end

    Maybe I'm blind, but I still don't see much value in a function which averages a
    point list more than two.

    Joe Burke
     
    Joe Burke, Mar 4, 2004
    #15
  16. Huw

    Doug Broad Guest

    Hi Joe and Zeha.

    Zeha,
    Your function looked good. Just thought I'd show
    another approach with mapcar. HUW seemed
    to have a problem with yours (but I couldn't see
    anything wrong).

    Joe,
    Who knows why? Perhaps HUW will chime in.
    It would certainly be easier to find the middle of a regular
    polygon by drawing a 3p circle. I'm not sure I like
    the effect of drawing vectors between the picked points
    but if I did, I would probably prefer Zeha's method.

    Interesting to note that if mine is used within a
    command (like line) and the person hits enter instead
    of picking a point, the line command continues, but
    if the function returned nil (due to error checking)
    the line command would end (which would be an
    unlikely user intent within this function).

    Small changes:

    ;;Returns a point that represents the average
    ;;x,y, and z values of the selected points.
    ;;Hit return to finish selection. Osnap
    ;;mode may affect point placement if used
    ;;within a command.

    ;;Example: line 'mnp <pick><pick><pick><return> ....

    (defun c:mnp ( / pl p pll)
    ;;D. C. Broad, Jr. Demonstration 3/4/04
    (while (setq p (getpoint "Pick point[Enter]:"))
    (setq pl (cons p pl)))
    (setq pll (length pl))
    (mapcar '(lambda (x)(/ x pll))
    (apply 'mapcar (cons '+ pl))))


     
    Doug Broad, Mar 4, 2004
    #16
  17. Huw

    CAB2k Guest

    Will this do you any good??

    Found it.. :)

    ;; ******************************************************************************
    ;; Determine centroid of a polygon
    ;;
    ;; Algorithm:
    ;; 1. Form trapezoids by dropping lines from each segment to a basey axis.
    ;; 2. Calculate the area and CG of the triangle and rectangle in each trapezoid
    ;; 3. Sums up weighted moments against given axes in X and Y direction
    ;; (may use x and y axes if number is small)
    ;; 4. Derived CG by dividing weighted sum by total area.
    ;; ******************************************************************************

    (defun GE_centroid(vlist / segno n ttl_area basex basey p1 p2 x1 x2 y1 y2
    t_x t_y t_area t_xm t_ym r_x r_y r_area r_xm r_ym Mx My)
    (setq
    vlist (append vlist (list (car vlist)))
    segno (1- (length vlist)) ; no of segments
    n 0
    Ttl_Area 0.0 ; total area
    Mx 0.0 ; Sum of moment to basex line
    My 0.0 ; Sum of moment to basey line
    basex (car (nth 0 vlist)) ; arbitrary axes (will reduce error for large numbers)
    basey (cadr (nth 0 vlist))
    )

    (repeat segno
    (setq
    p1 (nth n vlist) ; process current segment
    p2 (nth (1+ n) vlist)
    x1 (car p1)
    y1 (cadr p1)
    x2 (car p2)
    y2 (cadr p2)

    ; For the triangle
    t_x (- (* (+ x2 x2 x1) 0.333333) basex) ; cg of trianlge
    t_y (- (* (+ y1 y1 y2) 0.333333) basey)
    t_area (* (- y2 y1) (- x2 x1) 0.5) ; area of triangle
    t_xm (* t_area t_x) ; moment to Basex
    t_ym (* t_area t_y) ; moment to basey

    ; For the rectangle
    r_x (- (/ (+ x1 x2) 2) basex) ; CG of rectangle
    r_y (- (/ (+ basey y1) 2) basey)
    r_area (* (- x2 x1) (- y1 basey)) ; area of rectangle
    r_xm (* r_area r_x) ; moment to basex
    r_ym (* r_area r_y) ; moment to basey

    Ttl_Area (+ Ttl_Area t_area r_area)
    Mx (+ Mx t_xm r_xm) ; adds up moments to basex
    My (+ My t_ym r_ym) ; adds up moments to basey
    n (1+ n)
    )
    )
    (list (+ (/ Mx Ttl_Area) basex) (+ (/ My Ttl_Area) basey))
    )
     
    CAB2k, Mar 4, 2004
    #17
  18. Huw

    Joe Burke Guest

    Doug,

    Regarding rubber band, while picking many points you might lose track of which ones
    were already picked. I liked Michael's function because it doesn't rely on
    "lastpoint" to avoid an error. In this case lastpoint may have nothing to do with the
    operation.

    Right, who knows why. :)

    And I agree, Zeha's function answers the question as asked. I'm the one off on a
    tangent.

    Thanks for the mapcar example. I was trying to do something similar a few weeks ago.
    Never did figure it out. Took the long way around, similar to Zeha's code.

    Joe Burke

     
    Joe Burke, Mar 5, 2004
    #18
  19. Huw

    Doug Broad Guest

    Hi Joe,
    No problem with asking questions or being off-tangent.
    That's what a discussion group should allow and encourage.
    Otherwise there's no *discussion*. ;-)

    Thanks for posting Michael'sfunction. I like blipmode for its
    capability of communicating point picks where those points
    will never be joined by vectors. Blipmode shows me all the points
    I've picked. That's why I personally would never use what I'
    last posted in the Blipmode thread. I posted that one because
    I was curious about how to handle those kinds of events in
    VBA.

    Regards,
    Doug
     
    Doug Broad, Mar 5, 2004
    #19
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.