Jump to content

Recommended Posts

Posted

I’m currently working on a function that calculates a new 3D polyline based on a given slope and an existing polyline with chatGPT. However, I’ve encountered an issue where the last vertex of the created 3D polyline is showing incorrect X and Y coordinates. Im so close but i can not fix it. Can somebody help me? 

(defun c:calculateNew3DPolylineWithSlope ( / js slope total_horizontal_length new_points pt_start pt_end inter_distance n start_z end_z ratio num_points)
  (princ "\nSelect a 3D polyline.")
  
  ;; Select the 3D polyline
  (setq js (ssget '((0 . "POLYLINE")))) ; Only polylines
  
  ;; Check if the selection is empty
  (if (not js)
    (progn
      (princ "\nEmpty or invalid polyline selection!")
      (exit)  ;; Exit the command
    )
  )
  
  ;; Get the VLA object for the selected polyline
  (setq ename (vlax-ename->vla-object (ssname js 0)))

  ;; Calculate the total horizontal length of the polyline (X, Y plane)
  (setq total_horizontal_length 0.0)
  (setq num_points (fix (vlax-curve-getEndParam ename)))  ;; Total number of vertices

  ;; Check if the polyline has vertices
  (if (<= num_points 0)
    (progn
      (princ "\nThe polyline has no valid vertices!")
      (exit)
    )
  )

  ;; Loop to calculate horizontal length
  (setq n 0)
  (while (< n num_points)
    (setq
      pt_start (vlax-curve-getPointAtParam ename (float n))   ;; Starting point at the n-th vertex
      pt_end (vlax-curve-getPointAtParam ename (float (1+ n)))  ;; Next point
      ;; Check if points are valid
      inter_distance 0.0
    )
    ;; If both points are valid
    (if (and pt_start pt_end)
      (progn
        ;; Calculate horizontal distance
        (setq inter_distance (distance (list (car pt_start) (cadr pt_start)) (list (car pt_end) (cadr pt_end)))  ;; Horizontal distance
              total_horizontal_length (+ total_horizontal_length inter_distance))  ;; Add horizontal distance
        
        ;; Print horizontal length to the current vertex
        (princ (strcat "\nHorizontal length to vertex " (itoa n) " is: " (rtos total_horizontal_length 2 2) " units."))
      )
    )
    (setq n (1+ n))
  )

  ;; Get the desired slope from the user
  (setq slope (getreal "\nEnter the desired slope in percentage: "))
  (setq slope (/ slope 100.0))  ;; Convert to decimal
  
  ;; Calculate height based on the slope (slope * total horizontal length)
  (setq start_z (getreal "\nEnter the Z coordinate of the starting point: "))
  (setq end_z (+ start_z (* slope total_horizontal_length))) ;; Z coordinate of the last point
  
  ;; Create a list for new points
  (setq new_points '())

  ;; Interpolate heights between the first and last point
  (setq n 0)
  (setq horizontal_length_so_far 0.0)  ;; Horizontal length to the current vertex

  (while (< n num_points)
    (setq pt_start (vlax-curve-getPointAtParam ename (float n))) ;; Get the n-th point
    
    ;; Check the validity of the point
    (if pt_start
      (progn
        ;; Prevent division by zero
        (if (> num_points 0)
          (setq ratio (/ horizontal_length_so_far total_horizontal_length)) ;; Calculate ratio
          (setq ratio 0.0)
        )
        
        ;; Interpolate Z coordinate considering horizontal length to vertex
        (setq interpolated_z (+ start_z (* ratio (- end_z start_z)))) ;; Interpolate Z
        ;; Add new point with new Z coordinate to the list
        (setq new_points (cons (list (car pt_start) (cadr pt_start) interpolated_z) new_points))
      )
    )
    
    ;; Add the horizontal length of the current vertex
    (if (< n (1- num_points))  ;; Ensure not to go out of bounds
      (setq next_pt_start (vlax-curve-getPointAtParam ename (float (1+ n)))  ;; Next point
            inter_distance (distance (list (car pt_start) (cadr pt_start)) (list (car next_pt_start) (cadr next_pt_start)))  ;; Horizontal distance
            horizontal_length_so_far (+ horizontal_length_so_far inter_distance)) ;; Accumulate horizontal length
    )
    
    (setq n (1+ n))
  )
)

 

Posted

Since you reported this solved, you should come back and provide the solution.

 

Not to mention, there may be better solutions.

Posted

Here is my solution.

(defun c:3Dppad ( / js pad total_horizontal_length l_pt pt_start pt_end inter_dist n start_z end_z ratio num_points)
  (princ "\nOdaberite 3D poliliniju.")
  
  ;; Selektovanje 3D polilinije
  (setq js (ssget '((0 . "POLYLINE")))) ; Samo polilinije
  
  ;; Proverava da li je izbor prazan
  (if (not js)
    (progn
      (princ "\nNeprazan ili nevalidan izbor polilinije!")
      (exit)  ;; Izlazi iz komande
    )
  )
  
  ;; Dobijanje VLA objekta za odabranu poliliniju
  (setq ename (vlax-ename->vla-object (ssname js 0)))

  ;; Računanje ukupne horizontalne dužine polilinije (X, Y ravnina)
  (setq total_horizontal_length 0.0)
  (setq num_points (fix (vlax-curve-getEndParam ename)))  ;; Ukupan broj verteksa

  ;; Provera da li polilinija ima verteksa
  (if (<= num_points 0)
    (progn
      (princ "\nPolilinija nema validne vertekse!")
      (exit)
    )
  )

  ;; Petlja za računanje horizontalne dužine
  (setq n 0)
  (while (< n num_points)
    (setq
      pt_start (vlax-curve-getPointAtParam ename (float n))   ;; Početna tačka na n-tom verteksu
      pt_end (vlax-curve-getPointAtParam ename (float (1+ n)))  ;; Sledeća tačka
      ;; Provera da li su tačke validne
      inter_dist 0.0
    )
    ;; Ako su obe tačke validne
    (if (and pt_start pt_end)
      (progn
        ;; Izračunaj horizontalnu distancu
        (setq inter_dist (distance (list (car pt_start) (cadr pt_start)) (list (car pt_end) (cadr pt_end)))  ;; Horizontalna distanca
              total_horizontal_length (+ total_horizontal_length inter_dist))  ;; Dodaj horizontalnu distancu
        
        ;; Ispis horizontalne dužine do trenutnog verteksa
        (princ (strcat "\nHorizontalna dužina do verteksa " (itoa n) " je: " (rtos total_horizontal_length 2 2) " jedinica."))
      )
    )
    (setq n (1+ n))
  )

  ;; Dobavljanje željenog nagiba od korisnika
  (setq pad (getreal "\nUnesite željeni pad (slope) u procentima: "))
  (setq pad (/ pad -100.0))  ;; Pretvaranje u decimalni oblik
  
  ;; Računanje visine na osnovu nagiba (pad * ukupna horizontalna dužina)
  (setq start_z (getreal "\nUnesite Z koordinatu početne tačke: "))
  (setq end_z (+ start_z (* pad total_horizontal_length))) ;; Z koordinata poslednje tačke
  
  ;; Kreiranje liste za nove tačke
  (setq l_pt '())

  ;; Interpolacija visina između prve i poslednje tačke
  (setq n 0)
  (setq horizontal_length_so_far 0.0)  ;; Horizontalna dužina do trenutnog verteksa

  (while (<= n num_points)
    (setq pt_start (vlax-curve-getPointAtParam ename (float n))) ;; Dohvata n-tu tačku
    
    ;; Provera validnosti tačke
    (if pt_start
      (progn
        ;; Sprečavanje deljenja sa nulom
        (if (>= num_points 0)
          (setq ratio (/ horizontal_length_so_far total_horizontal_length)) ;; Izračunaj ratio
          (setq ratio 0.0)
        )
        
        ;; Interpolacija Z koordinate uzimajući u obzir horizontalnu dužinu do verteksa
        (setq interpolated_z (+ start_z (* ratio (- end_z start_z)))) ;; Interpolacija Z
        ;; Dodaj novu tačku s novom Z koordinatom u listu
        (setq l_pt (cons (list (car pt_start) (cadr pt_start) interpolated_z) l_pt))
      )
    )
    
    ;; Dodaj horizontalnu dužinu trenutnog verteksa
    (if (<= n (1- num_points))  ;; Osigurati da ne idemo van granica
      (setq next_pt_start (vlax-curve-getPointAtParam ename (float (1+ n)))  ;; Sledeća tačka
            inter_dist (distance (list (car pt_start) (cadr pt_start)) (list (car next_pt_start) (cadr next_pt_start)))  ;; Horizontalna distanca
            horizontal_length_so_far (+ horizontal_length_so_far inter_dist)) ;; Akumuliraj horizontalnu dužinu
    )
    
    (setq n (1+ n))
  )

  ;; Kreiranje nove 3D polilinije sa zadatim nagibom
  (vla-put-Layer (vlax-invoke (vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object))) 'Add3DPoly (apply 'append (reverse l_pt))) (vla-get-Layer (ssname js 0)))

  (princ "\nNova 3D polilinija je uspešno kreirana sa zadatim nagibom.")
  (princ)  ;; Završavanje funkcije bez greške
)

 

  • Like 1
  • Thanks 1
Posted

Thanks for coming back with the solution.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...