Тема: LISP. Для генпланистов: построение линии с уклоном

Даная функция строит линию с заданным в промиллях вертикальным! уклоном. Заданый уклон сохраняется в глобальной переменной *RUNA_DDLSLOPE*, если задаете уклон с + то следущая точка будет выше предыдущей. Линия будет трехмерной.

;;;Построение линии по начальной точке и уклону заданому в промилях
(defun c:ddl (/ END_ELEV END_POINT SLOPE ST_ELEV ST_POINT)
;|
; Global variables: (*RUNA_DDLSLOPE*)
|;
  (if (not *runa_ddlslope*) (setq *runa_ddlslope* 5))
 (setq slope (GETREAL
           (STRCAT "Specify slope in promille or <"
               (rtos *runa_ddlslope* 2) " ?>: ")))
  (if (null slope)
    (setq slope *runa_ddlslope*)
    (setq *runa_ddlslope* slope))
  (setq st_point (getpoint "DDL Specify first point: "))
  (if (null st_point)
    (setq st_point (GETVAR "LASTPOINT")))
  (setq st_elev (last st_point))
  (setq st_elev (GETREAL
           (STRCAT "\nStart elevation <"
               (rtos st_elev 2) ">: ")))
  (if (null st_elev)
    (setq st_elev (last st_point)))
  (setq end_point (getpoint st_point "Specify end point of line: "))
  (if (null end_point)
    (princ "Cannot build a zero length line.")
    (progn
      (setq end_elev
         (+ st_elev
        (* slope 0.001
        (setq dist_in_plane
        (distance
        (cdr (reverse st_point))
        (cdr (reverse end_point)))))))
      (command "_.line"
           ".xy"
           "none"
           st_point
           st_elev
           ".xy"
           "none"
           end_point
           end_elev
           "")
      (princ (STRCAT "\nEnd elevation: "
             (rtos end_elev 2)
             "   Distance in plane: "
             (rtos dist_in_plane 2)))
      );progn
    );if
  (princ)
); end defun

А вот и функция для подсчета уклонов и расстояний на генплане:
Возвращает в командную строку типа:

Distance = 4.6924 , Slope = 0.000 ?, Delta Z = 0.0000 .
Dist by z: 4.6924 , L(M 1:500)= 9.3848 , L(M 1:200)= 23.4619

Где Distance = 4.6924 - расстояние в плане
Slope = 0.000 ? - уклон в промиллях если с + то вторая точка была выше
Delta Z = 0.0000 превышение
Dist by z: 4.6924 расстояние с учетом Z - координат
L(M 1:500)= 9.3848 - расстояние в мм в 500 масштабе
L(M 1:200)= 23.4619  - тоже но для 200.
только не пугайтесь:)

(defun c:rdd ( / runa01 runa02 runa03 runa04 runa05)
  (setq runa01 (GETPOINT "\nSpecify first point: "))
  (if (null runa01) (setq runa01 (getvar "LASTPOINT")))
  (setq runa02 (GETPOINT runa01 "  Specify second point: "))
  (if (null runa02) (princ "\nCannot computer distance.")
    (PROGN
      (setq runa03 (- (last runa02) (last runa01))
        runa05 (distance runa01 runa02))
      (setq runa01 (list (car runa01) (cadr runa01))
        runa02 (list (car runa02) (cadr runa02)))
      (setq runa04 (distance runa01 runa02))
      (princ (STRCAT "\nDistance = " (RTOS runa04 2)
             " м, Slope = "
             (rtos (* (/ runa03 runa04) 1000) 2 3)
             " ?, Delta Z = " (rtos runa03 2) " м."))
      (princ (STRCAT "\nDist by z: "
             (rtos runa05 2) " м, L(M 1:500)= "
             (rtos (/ runa04 0.5) 2) " мм, "
    "L(M 1:200)= " (rtos (/ runa04 0.2) 2) " мм"))
      );PROGN
    );if
  (princ)
  );end defun

Имена команд DDL RDD
Макросы
^C^CDDL
'RDD  - может работать в прозрачном режиме (точнее как лисп-выражение)

Re: LISP. Для генпланистов: построение линии с уклоном

> Runa
Ради дискуссии. Прошло почти 10 дней с момента опубликования и ни кто, ни чего не сказал. Говорю своё мнение. Я не черчу план автодороги в трехмерной графике  хлопотно.
1 наглядности не получится для длинного участка.
2 есть участки не только с уклоном, но и вертикальные кривые
3 в конечном счете, увязка с существующем рельефом, а он плоский.
4 есть не только осевая, но и лини верха и низа откосов, кюветы и т.п.

Re: LISP. Для генпланистов: построение линии с уклоном

> Valery Brelovsky
1 это не для наглядности делалось, наглядно не получается даже относительно коротких участков :(. Вертикалку я делаю в ЛДД а там очень удобно пользоватся этими програмами для построения трехмерной вертикалки.
2 согласен, я довольно редко сталкиваюсь с вертикальными кривыми (не дорожник я), поэтому делать того что я плохо знаю в теории на лиспе делать не буду
3 совсем не согласен, не было у меня плоских существующих рельефов (если я правильно понял). Хотя даже при спокойном рельефе возникают проблемы отвода воды.
4 с откосами совсем другие нужны программы (у меня их еще нет)
ЗЫ Мои функции не панацея, а один из инструментов работы, в конце концов можно ими пользоватся только для вычисления отметки не отрываясь от компа зная уклон и расстояние:)

Re: LISP. Для генпланистов: построение линии с уклоном

> Runa
Рельеф плоский в файле, а не в натуре.

Re: LISP. Для генпланистов: построение линии с уклоном

> Valery Brelovsky
теперь понял :)
Забыл сказать что Ваше мнение я уважаю и благодарствую за отзыв а то у меня уже было чуство что никому не было дела до того что я выложил.
В голом акаде трехмерную вертикалку делать дествительно хлопотно, а вот в ЛДД приходится изобретать инструменты именно для трехмерки.

Re: LISP. Для генпланистов: построение линии с уклоном

У меня вопросик:
Есть ли аналогичная программка для построения на плоскости отрезков (по заданным - масштабу (вертикальному и горизонтальному), нач. точке, уклону (в промиллях) и длине проекции отрезка на горизонтальную поверхность)?
Часто приходится с профилями работать, а в ручную их отстраивать достаточно муторно.
ЗЫ. Предполагаю, что прога не большая, сам бы написал, если бы знал с какой стороны к Лиспу подходить.
Спасибо.

Re: LISP. Для генпланистов: построение линии с уклоном

Здесь есть такая возможность, когда задаешь уклон и длину линии, линия прорисовывается? И возможно ли так написать? Такая возможность есть в Лэнде3

Re: LISP. Для генпланистов: построение линии с уклоном

> Vidocq
Есть что-то подобное, для себя делал поэтому и не рискнул выкладывать. На досуге выложу сюда...

> Юра
С лэндом уже давно не работаю( Да и лиспом уже почти не балуюсь(((

Re: LISP. Для генпланистов: построение линии с уклоном

> Runa
Бум ждать:)
Я правда накидал таки небольшую прожку для описанной мною цели, но только для определенного масштаба и без каких либо дополнительных излишеств.

Re: LISP. Для генпланистов: построение линии с уклоном

> Vidocq
geol-dh.ru (Комплекс KAI, DRAWGRAD, SLOPE и др.).

Re: LISP. Для генпланистов: построение линии с уклоном

Совсем забыл что обещал выложить свои заначки.

(defun +runa_make-line (s-point e-point)
;|
(+runa_make-text (getpoint) (getpoint))
|;
  (entmake
 (list
  '(0 . "LINE")
  '(100 . "AcDbEntity")
  (cons 410 (getvar "ctab"))
  (cons 8  (getvar "clayer"))
  '(100 . "AcDbLine")
  (cons 10 (trans s-point 1 0))
  (cons 11 (trans e-point 1 0))
  '(210 0.0 0.0 1.0)
  )
 )
  (setvar "lastpoint" (trans e-point 1 0))
  )
(defun +runa_scale-factor-pop (mode / gor vert po DATUM)
  (if (or mode (not *runa_scale-factor-pop*) (vl-some 'not *runa_scale-factor-pop*))
    (progn
      (if (not (progn (initget 6)
        (setq gor (getreal
               (strcat "\nGorizontal scale <"
                   (if mode (rtos (caddr *runa_scale-factor-pop*)2 0)
                     "500") ">: ")))))
    (setq gor (if mode (caddr *runa_scale-factor-pop*) 500.0)))
      (if (not (progn (initget 6)
        (setq vert (getreal
                (strcat "\nVertikal scale <"
                    (if mode (rtos (cadddr *runa_scale-factor-pop*)2 0)
                      "100") ">: ")))))
    (setq vert (if mode (cadddr *runa_scale-factor-pop*) 100.0)))
      (while (not (setq po (getpoint "\nSpecify point for datum elevation: "))))
      (while (not (setq datum (getreal "\nDatum elevation: "))))
      (setq *runa_scale-factor-pop* (list
                      (/ gor vert)
                      (strcat "\tMgor=" (rtos gor 2 0) "; Mver=" (rtos vert 2 0))
                      gor vert
                      (- (cadr po) (* datum (/ gor vert)))))
      )
    )
  *runa_scale-factor-pop*
  )
(defun +runa_ele-pop (point /)
  (/ (- (cadr point) (last *runa_scale-factor-pop*)) (car *runa_scale-factor-pop*))
  )
(defun +runa_check-pop-set (/ word)
;|
(+runa_check-pop-set)
|;
    (cond
    ((= 1 (getvar "worlducs")))
    ((or
     (not (progn (initget "Yes No") (setq word (getkword "\nUcs not world. Change ucs to world [Yes/No] <Yes>: "))))
     (= "Yes" word))
     (setvar "ucsfollow" 0) (vl-cmdf "ucs" ""))
    (t (princ "\nCannot continue program!") (exit))
    )
  (if (+runa_scale-factor-pop nil) (princ (cadr *runa_scale-factor-pop*)) (exit))
  )
(defun c:ddl-p (/ EN_POINT heigth SLOPE ST_POINT last-ent nabor word)
  (+runa_check-pop-set)
  (setq last-ent (entlast))
  (setq st_point (getpoint "\nStart point <Lastpoint>: "))
  (if (not st_point) (setq st_point (getvar "lastpoint")))
  (while
    (and
    (progn (initget "None Border Change") (setq slope (getreal "\nSlope or [None/Border/Changescalefactor/20/10/0/-10/-20]: ")))
    (cond
      ((eq slope "Border") (setq heigth (getreal "\nHeigth border [20/15/10/5] <15>: "))
       (setq en_point (getpoint st_point "\nNext point: ")))
      ((eq slope "Change") )
      (t (setq en_point (getpoint st_point "\nNext point: ")))
      )
    ); and
    (cond
      ((eq slope "Change") (+runa_scale-factor-pop t))
      ((eq slope "None") (+runa_make-line st_point en_point))
      ((eq slope "Border")
       (if
     (not
         heigth)
     (setq heigth 15)
     )
       (if (< (cadr st_point) (cadr en_point))
     (+runa_make-line st_point (mapcar '+ st_point (list 0.0 (* (car *runa_scale-factor-pop*) heigth 0.01) 0.0)))
     (+runa_make-line st_point (mapcar '- st_point (list 0.0 (* (car *runa_scale-factor-pop*) heigth 0.01) 0.0)))
     ))
      (slope (+runa_make-line st_point
                  (list
                (car en_point)
                (+ (cadr st_point) (* (car *runa_scale-factor-pop*) 0.001 slope (abs (- (car en_point) (car st_point)))))
                (last en_point)
                )))
      )
    (if (not (eq slope "Change")) (setq st_point (getvar "lastpoint")))
    ); while
  (princ)
  )
(defun c:ele (/ po word)
  (+runa_check-pop-set)
  (while (progn (initget "Change") (setq po (getpoint "\nSpecify point for elevation [Changescalefactor]: ")))
    (if (eq po "Change")
      (+runa_scale-factor-pop t)
    (princ (strcat "\nElevation: " (rtos (+runa_ele-pop po) 2))))
    )
  (princ)
  )
(defun c:ele-line (/ END END-EL STA-EL START)
  (+runa_check-pop-set)
(initget "Change")
(setq start (getpoint "\nStart point for elevation [Changescalefactor]: "))
  (if (eq start "Change")
      (progn (+runa_scale-factor-pop t)
    (setq start (getpoint "\nStart point for elevation: ")))
      )
(if
  (and start
(setq sta-el (getreal "\nElevation: ")))
(progn
  (setq start (list (car start) (+ (* sta-el (car *runa_scale-factor-pop*)) (last *runa_scale-factor-pop*))))
  (while
    (cond
      ((not (setq end (getpoint start "\nNext point: "))) nil)
      ((not (setq end-el (getreal "\nElevation: "))) nil)
      (t (+runa_make-line
       start
       (list (car end) (+ (* end-el (car *runa_scale-factor-pop*)) (last *runa_scale-factor-pop*)) 0.0)
       ))
      )
    (setq start (getvar "lastpoint"))
    )))
  (princ)
  )
(defun c:elp (/ END END-EL STA-EL START)
  (+runa_check-pop-set)
  (while
    (cond
      ((not (progn (initget "Change")
          (setq start (getpoint "\nPoint for elevation [Changescalefactor]: ")))) nil)
      ((eq start "Change") (+runa_scale-factor-pop t))
      ((not (setq sta-el (getreal "\nElevation: "))) nil)
      (t (vl-cmdf "_.point" "_none"
       (list (car start) (+ (* sta-el (car *runa_scale-factor-pop*)) (last *runa_scale-factor-pop*)) 0.0)
       ))
      )
    )
  (princ)
  )
(defun c:uk (/ PO1 PO2 word TMP1 TMP2 TMP3 TMP4 TMP5)
  (+runa_check-pop-set)
  (while
  (cond
    ((not (progn (initget "Change") (setq po1 (getpoint "\nStart point [Changescalefactor]: ")))) nil)
    ((eq po1 "Change") (+runa_scale-factor-pop t))
    ((not (setq po2 (getpoint po1 "\nEnd point: "))) nil)
    (t (princ (strcat
        (if (zerop (- (car po2) (car po1)))
          "\nUklon = vertikal ‰"
          (strcat
        "\nUklon = "
        (setq tmp1 (rtos (/ (- (cadr po2) (cadr po1)) 0.001 (- (car po2) (car po1)) (car *runa_scale-factor-pop*)) 2))
        " ‰")
          )
        "\tDelta X = "
        (setq tmp2 (rtos (abs (- (car po2) (car po1))) 2))
        " m\tDelta Y = "
        (setq tmp3 (rtos (abs (/ (- (cadr po2) (cadr po1)) (car *runa_scale-factor-pop*))) 2))
        " m\nStart elevation = "
        (setq tmp4 (rtos (+runa_ele-pop po1) 2))
        " m\tEnd elevation = "
        (setq tmp5 (rtos (+runa_ele-pop po2) 2))
        " m"
              )) (setq *temp-value-pop* (list tmp1 tmp2 tmp3 tmp4 tmp5)))
    ))
  (princ)
  )

Итого имеем в этом беспорядке комманды:
ddl-p - используется для построения профиля по уклонам
ele - в коммандной строке показывает отметку профиля
ele-line - строит линию по указаным точкам и отметкам
elp - ставит точку по указаному Х и заданной отметке
uk - показывает в коммандной строке уклон и еще что-то там по указаным точкам.
При первом вызове любой (вроде) комманды будет запрос на вертикальный и горизонтальный масштаб профиля, базовой точки профиля и отметки этой базовой точки.
Извиняюсь за сумбур и редкие комментарии - давно делал а сейчас некогда приводить в "вид".

(изменено: Valery Brelovsky, 7 января 2012г. 08:10:36)

Re: LISP. Для генпланистов: построение линии с уклоном

Наверное Стоит попробовать. При наличии сегодня мощных программ всё равно приходится доводить чертёж в ручную.