Drawing an line that changes colour depending on angle.

Drawing an line that changes colour depending on angle.

JanTol82
Enthusiast Enthusiast
1,557 Views
13 Replies
Message 1 of 14

Drawing an line that changes colour depending on angle.

JanTol82
Enthusiast
Enthusiast

Hello everyone,

 

I have a question. At my job we make drawings to put in reports to clearify declines in facades. We draw the lines manually and change the colors afterward (green for low decline and then from  yellow, orange to red too big decline). Is it possible in Autocad too program a function to draw polylines that change color too the angle they are drawn in?

 

We preferable look for an command in which we can click on the x coordinates by mouse and then add the negative Y coordinates that draws the lines from left too right and change the color depending on the angle.

 

If anyone can help we would really appreciate it.

 

Kind regards

 

Jan

0 Likes
Accepted solutions (1)
1,558 Views
13 Replies
Replies (13)
Message 2 of 14

DannyNL
Advisor
Advisor

Something like this?

 

Line will only be drawn if start and end point are selected from left to right and the decline point indicates an angle between or equal to 0 and -90 degrees.

 

(defun c:Test (/ T_Point1 T_Point2 T_Decline T_Angle T_Color)
   (if
      (and
         (setq T_Point1  (getpoint          "\nSelect start point  : "))
         (setq T_Point2  (getpoint T_Point1 "\nSelect end position : "))
         (setq T_Decline (getpoint T_Point2 "\nSelect decline point: "))
         (or
            (= (setq T_Angle (angle T_Point1 T_Decline)) 0.0)
            (and
                (>= T_Angle (* 1.5 pi))
                (<  T_Angle (* 2   pi))
            )
         )
      )
      (progn
         (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
         (setvar "CMDECHO" 0)
         (command "_PLINE" T_Point1 (setq T_EndPoint (list (car T_Point2) (cadr T_Decline))) "")
         (setq T_Color
            (cond
               (
                  (= T_Angle 0.0)               ; horizontal line
                  1                             ; red
               )
               (
                  (and
                     (< T_Angle (* 2    pi))    ; line between 0
                     (> T_Angle (* 1.75 pi))    ; and -45 degrees
                  ) 
                  2                             ; yellow
               )
               (
                  (= T_Angle (* 1.75 pi))       ; line at -45 degrees
                  4                             ; cyan
               )               
               (
                  (and
                     (< T_Angle (* 1.75 pi))    ; line between -45
                     (> T_Angle (* 1.5  pi))    ; and -90 degrees
                  )
                  6                             ; magenta
               )               
               (
                  (= T_Angle (* 1.5 pi))        ; vertical line
                  3                             ; green
               )
            )
         )
         (command "_CHPROP" "L" "" "C" T_Color "")
         (setvar "CMDECHO" 0)
         (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
      )
   )
   (princ)
)
Message 3 of 14

JanTol82
Enthusiast
Enthusiast

Maybe I'm doing something wrong, but it doesn't work at my workstation.

It asks for 4 points and doesn't seem to draw anything.

Command response with input 1,2,3,4 below.

 

 

Command: (defun c:Test (/ T_Point1 T_Point2 T_Decline T_Angle T_Color) (_> (if ((_> (and (((_> (setq T_Point1 (getpoint "1 ((((("_> nSelect start point : ")) (((_> (setq T_Point2 (getpoint T_Point1 "2 ((((("_> nSelect end position : ")) (((_> (setq T_Decline (getpoint T_Point2 "3 ((((("_> nSelect decline point: ")) (((_> (or ((((_> (= (setq T_Angle (angle T_Point1 T_Decline)) 0.0) ((((_> (and (((((_> (>= T_Angle (* 1.5 pi)) (((((_> (< T_Angle (* 2 pi)) (((((_> ) ((((_> ) (((_> ) ((_> (progn (((_> (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object))) (((_> (setvar "CMDECHO" 0) (((_> (command "_PLINE" T_Point1 (setq T_EndPoint (list (car T_Point2) (cadr T_Decline))) "") (((_> (setq T_Color ((((_> (cond (((((_> ( ((((((_> (= T_Angle 0.0) ((((((_> horizontal line ((((((_> 1 ((((((_> red ((((((_> ) (((((_> ( ((((((_> (and (((((((_> (< T_Angle (* 2 pi)) (((((((_> line between 0 (((((((_> (> T_Angle (* 1.75 pi)) (((((((_> and -45 degrees (((((((_> ) ((((((_> 2 ((((((_> yellow ((((((_> ) (((((_> ( ((((((_> (= T_Angle (* 1.75 pi)) ((((((_> line at -45 degrees ((((((_> 4 ((((((_> cyan ((((((_> ) (((((_> ( ((((((_> (and (((((((_> (< T_Angle (* 1.75 pi)) (((((((_> line between -45 (((((((_> (> T_Angle (* 1.5 pi)) (((((((_> and -90 degrees (((((((_> ) ((((((_> 6 ((((((_> magenta ((((((_> ) (((((_> ( ((((((_> (= T_Angle (* 1.5 pi)) ((((((_> vertical line ((((((_> 3 ((((((_> green ((((((_> ) (((((_> ) ((((_> ) (((_> (command "_CHPROP" "L" "" "C" T_Color "") (((_> (setvar "CMDECHO" 0) (((_> (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object))) (((_> ) ((_> ) (_> (princ) (_> ) 4 4
0 Likes
Message 4 of 14

DannyNL
Advisor
Advisor

You've pasted the whole code to your command line, but that doesn't run it. Type the command TEST en press enter.

 

You can also copy the code in a new notepad document and save it to a name with FileNameYouWant.lsp.

Drag 'n drop this LSP file into your drawing and type TEST on the command line to start the routine.

 

If you know what the VL Editor is (command VLIDE in AutoCAD), you can also paste the code in a new document and load in directly into your drawing.

0 Likes
Message 5 of 14

JanTol82
Enthusiast
Enthusiast

Thank you for help. I'm out of office the rest of the day but I'm gonna try it first thing Monday morning. 

0 Likes
Message 6 of 14

Kent1Cooper
Consultant
Consultant

When you say "lines," does that mean you draw these in some kind of multiples  in series, such as this kind of thing, as in a time-line graph of some kind?

 

Capture.PNG

 

Or is it only one at a time?

 

I made them Polylines here for width for visual clarity, but you mention both  Polylines and Lines -- which would it be?

 

If they would be Polylines, and if they would be in series like the image above, they would have to be separate  Polylines -- a single one with multiple segments can't have the segments in different colors.

Kent Cooper, AIA
0 Likes
Message 7 of 14

JanTol82
Enthusiast
Enthusiast

It doesn't matter if the're lines or seperate polylines. Both would be fine for the purpose.

0 Likes
Message 8 of 14

JanTol82
Enthusiast
Enthusiast

Thank you for your help Danny but this is not what I meant.

0 Likes
Message 9 of 14

DannyNL
Advisor
Advisor

Can you post an example drawing or picture of what you do mean?

A picture tells more then a thousand words and then we have an idea what the end result should look like.

0 Likes
Message 10 of 14

Kent1Cooper
Consultant
Consultant

Something like this, perhaps [minimally tested]?

 

(defun C:SLC (/ p1 p2 drop p3 dropang); = Sloped Lines Color-coded
  (setq
    p1 (getpoint "\nStart/left end of Line: ")
    p2 (getpoint p1 "\nPoint with X coordinate of right end of Line: ")
    drop (getdist p2 "\nDrop distance from left to right: ")
    p3 (list (car p2) (- (cadr p1) drop))
    dropang (angle p1 p3)
  ); setq
  (command
    "_.line" p1 p3 ""
    "_.chprop" "_last" "" "_color"
      (cond
        ((> dropang (* pi 1.95)) 90); green ;;; EDIT multipliers & color numbers as desired
        ((> dropang (* pi 1.9)) 50); yellow
        ((> dropang (* pi 1.8)) 40); orange
        (10); red [anything steeper]
      ); cond
    ""
  ); command
  (princ)
); defun

 

It asks for the start and X-position-of-end for one  Line, but could be made to repeatedly ask for the next X-of-end pick in a series such as in my earlier image, if that's what you need.  That is, as written, to do that kind of series, you have to pick on the right end of the previous Line for the left start of the next one, but it could be made to use that previous-Line right end for the next-Line left end automatically.

 

And note that though it uses rubber-banding for the 'p2' and 'drop' settings, it does not  just use the picked points, but operates as I think your description indicates -- it uses only the X coordinate of the 'p2' pick location, and it takes the 'drop' distance, however specified [picked relative to p2, or typed in] off the Y coordinate of 'p1' , not off p2 that it's rubber-banding from.  If that's confusing, the rubber-banding can be eliminated.

 

It also does not check for other things that it could, for example that the second point is actually to the right of the first one, but such things could be added easily enough.  Consider other optional approaches, such as putting the Lines on different Layers  with those colors, depending on their slopes, rather than forcing a color override on them.

Kent Cooper, AIA
Message 11 of 14

JanTol82
Enthusiast
Enthusiast

Thank you, that's what we mean and need, is it also possible to make it so that he picks the last point for the next line and make it an active command in which you can insert multiple points?

0 Likes
Message 12 of 14

Kent1Cooper
Consultant
Consultant

@JanTol82 wrote:

... is it also possible to make it so that he picks the last point for the next line and make it an active command in which you can insert multiple points?


Try this variation:

(defun C:SLC (/ p1 p2 drop p3 dropang); = Sloped Lines Color-coded
  (setq p1 (getpoint "\nStart/left end of Line: "))
  (while (setq p2 (getpoint p1 "\nPoint with X coordinate of right end of Line <exit>: "))
    (setq
      drop (getdist p2 "\nDrop distance from left to right: ")
      p3 (list (car p2) (- (cadr p1) drop))
      dropang (angle p1 p3)
    ); setq
    (command
      "_.line" p1 p3 ""
      "_.chprop" "_last" "" "_color"
        (cond
          ((> dropang (* pi 1.95)) 90); green ;;; EDIT multipliers & color numbers as desired
          ((> dropang (* pi 1.9)) 50); yellow
          ((> dropang (* pi 1.8)) 40); orange
          (10); red [anything steeper]
        ); cond
      ""
    ); command
    (setq p1 p3); set end as beginning of next Line
  ); while
  (princ)
); defun
Kent Cooper, AIA
Message 13 of 14

JanTol82
Enthusiast
Enthusiast

Thank you Kent, that is what we want. Is it also possible to make it that works in two direction with the angel? 
I've attached a drawing wiht an example of the line we sometimes get.

Thank you very much.

0 Likes
Message 14 of 14

Kent1Cooper
Consultant
Consultant
Accepted solution

@JanTol82 wrote:

Thank you Kent, that is what we want. Is it also possible to make it that works in two direction with the angel? ....
.


This seems to do that [in very limited testing].  I changed it to ask for the Difference  rather than the Drop, and added that to the Y component rather than subtract it, because if left in "drop" terms, you would have had to enter a negative value to go up, which seemed counterintuitive.  So enter a negative value for a drop, positive for a rise.

 

(defun C:SLC (/ p1 p2 diff p3 diffang); = Sloped Lines Color-coded
  (setq p1 (getpoint "\nStart/left end of Line: "))
  (while (setq p2 (getpoint p1 "\nPoint with X coordinate of right end of Line <exit>: "))
    (setq
      diff (getdist p2 "\nDifference from left to right: ")
      p3 (list (car p2) (+ (cadr p1) diff))
      diffang (angle p1 p3)
    ); setq
    (command
      "_.line" p1 p3 ""
      "_.chprop" "_last" "" "_color"
        (cond
          ((or (< diffang (* pi 0.05)) (> diffang (* pi 1.95))) 90); green ;;; EDIT multipliers & color numbers as desired
          ((or (< diffang (* pi 0.1)) (> diffang (* pi 1.9))) 50); yellow
          ((or (< diffang (* pi 0.2)) (> diffang (* pi 1.8))) 40); orange
          (10); red [anything steeper]
        ); cond
      ""
    ); command
    (setq p1 p3); set end as beginning of next Line
  ); while
  (princ)
); defun
Kent Cooper, AIA