Jump to content

Recommended Posts

Posted

Hello friends

i want to find the maximum slope in a 3d face (this 3d face) consist of 3 points with different z value

is this possible 

thanks

Posted (edited)

The slope of of the plan defined by 3 distinct, non collinear points.

(defun 3dface_slope (p1 p2 p3 / n)
  (setq n (v*v
            (v-v p1 p2)
            (v-v p1 p3)
          )
  )
  (atan
    (distance '(0 0) n)
    (abs (caddr n))
  )
)

 ;Vectors and matrices function
 ;Stefan M. 17.11.2013
 (defun v-v (u v) (mapcar '- u v))                    ;subtract 2 vectors
 (defun v*v (a b)                                     ;cross product
    (list
      (- (* (cadr  a) (caddr b)) (* (caddr a) (cadr  b)))
      (- (* (caddr a) (car   b)) (* (car   a) (caddr b)))
      (- (* (car   a) (cadr  b)) (* (cadr  a) (car   b)))
    )
  )

 

Edited by Stefan BMR
small simplification
Posted

Do you have CIV3D its a surface style option, it displays a arrow on each Triangle. 

 

For me Slope Arrows & Catchments

Posted

Here's my primitive attempt.

(defun c:FaceSlope (/)
  (princ "\nPlease select 3DFACE and press ENTER.")
  (setq	ss    (ssget)
	en    (ssname ss 0)
	edata (entget en)
  )
  (if (= (cdr (assoc 0 edata)) "3DFACE")
    (progn
      (setq p1 (cdr (assoc 10 edata))	;set p1, p2, p3 to the three vertices of the 3DFACE
	    p2 (cdr (assoc 11 edata))
	    p3 (cdr (assoc 12 edata))
      )
      (setq normal (cross (mapcar '- p2 p1) (mapcar '- p3 p1)))
      (setq v1 (cross '(0.0 0.0 1.0) normal))
      (setq sv (cross v1 normal))
      (setq a (expt (+ (expt (car sv) 2) (expt (cadr sv) 2)) 0.5))
      ;; check if a = 0
      (if (< (abs a) 0.00001 )
	(setq slope "Vertical")
	(setq slope (/ (caddr sv) a))
      )
      (princ "\nThe slope is: ")
      (princ slope)
    )					;end true if
  )					; end if
  (princ)
)

;;; Compute the cross product of 2 vectors a and b
(defun cross (a b / crs)
  (setq	crs (list
	      (- (* (nth 1 a) (nth 2 b))
		 (* (nth 1 b) (nth 2 a))
	      )
	      (- (* (nth 0 b) (nth 2 a))
		 (* (nth 0 a) (nth 2 b))
	      )
	      (- (* (nth 0 a) (nth 1 b))
		 (* (nth 0 b) (nth 1 a))
	      )
	    )				;end list
  )					;end setq c
)					;end cross
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 

Posted (edited)

The other way is to take P1 and get closestpoint P4 to P2-P3 then get slope of P1-P4.

 

Repeat for P2 & P3 keeping answer compare a abs of slope. This way if -ve is ok.

 

As its faces will need a line or ray to be calculated.

 

Cal(p1,p2,p3) maybe ? 

 

>> Expression: nor(p1,p2,p3)
0.707106781,-0.707106781,0
 

Edited by BIGAL
  • 2 weeks later...
Posted

Hello  friends 

sorry for delaying 

thank you for replying 

i did't get what i want exactly 

Mr Irm

can you add a vector in the direction of maximum slope on the 3dface

because you calculate the value but in unknown place

thanks

 

Posted

Here's a revised version of the program. It outputs a unit vector of the maximum slope and draws a line from the center of the face in the direction of the maximum slope.  The length of the line is the average length of the sides of the face.

 

;; Determine the maximum slope of a 3dface.
;; 7/11/2020
(defun c:FaceSlope (/ ss en edata p1 p2 p3 v1 sv a slope midpt s endpt)
  (setq oldsnap (getvar "osmode"))
  (setvar "osmode" 0)

  (princ "\nPlease select 3DFACE and press ENTER.")
  (setq	ss    (ssget)
	en    (ssname ss 0)
	edata (entget en)
  )
  (setvar "cmdecho" 0)
  (if (= (cdr (assoc 0 edata)) "3DFACE")
    (progn
      (setq p1 (cdr (assoc 10 edata))	;set p1, p2, p3 to the three vertices of the 3DFACE
	    p2 (cdr (assoc 11 edata))
	    p3 (cdr (assoc 12 edata))
      )
      (setq normal (cross (mapcar '- p2 p1) (mapcar '- p3 p1)))
      (setq v1 (cross '(0.0 0.0 1.0) normal))
      (setq sv (cross v1 normal))
      (setq a (distance '(0 0 0) sv))
      (setq sv (mapcar '/ sv (list a a a)))
      (setq a (expt (+ (expt (car sv) 2) (expt (cadr sv) 2)) 0.5))
      ;; check if a = 0
      (if (< (abs a) 0.00001)
	(setq slope "Vertical")
	(setq slope (/ (caddr sv) a))
      )
      (princ "\nThe slope is: ")
      (princ slope)
      (princ "\nThe slope vector is: ")
      (princ sv)

      (setq midpt (mapcar '/ (mapcar '+ p1 p2 p3) '(3.0 3.0 3.0)))
      (setq s (+ (distance p1 p2) (distance p2 p3) (distance p1 p3)))
      (setq endpt (mapcar '+ midpt (mapcar '* sv (list s s s))))
      (command "_line" midpt endpt "")  ;; draw line showing maximum slope
    )					;end true if
    (princ "\nSelected object must be a face.")
  )					; end if
  (setvar "osmode" oldsnap)
  (setvar "cmdecho" 1)
  (princ)
)
;;; Compute the cross product of 2 vectors a and b
(defun cross (a b / crs)
  (setq	crs (list
	      (- (* (nth 1 a) (nth 2 b))
		 (* (nth 1 b) (nth 2 a))
	      )
	      (- (* (nth 0 b) (nth 2 a))
		 (* (nth 0 a) (nth 2 b))
	      )
	      (- (* (nth 0 a) (nth 1 b))
		 (* (nth 0 b) (nth 1 a))
	      )
	    )				;end list
  )					;end setq c
)					;end cross
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 

Posted

Thank you Mr Irm for your routine 

it is excellent but if you print slop value on the line that indicates the direction

 

Posted

@motee-z

You are welcome.

Are you asking for text to be added to the drawing that contains the numerical value of the slope or do you want the unit vector values? Should the text align with the slope line or the XY world plane or something else?  The more specific you are in specifying what you want the more likely the results will meet your needs.

 

Posted (edited)

i want the numerical  value text of the slope to be aligned with the slope line drawn by the lisp.

thanks

 

Edited by motee-z
Posted (edited)

lrm, a 3dface has always 4 points, even if it looks like a  triangle. In this case, 2 points are coincidental and the 4th point is not necessary one of them. So the points you need are not always dxf 10, 11 and 12.

Try it on this object:

(entmakex
  '((0 . "3DFACE")
    (10 0.0 0.0 0.0)
    (11 2.0 0.0 0.0)
    (12 2.0 0.0 0.0)
    (13 1.0 2.0 2.0)
   )
)

 

Edited by Stefan BMR
Posted

@Stefan BMR yes, I realize that a face has 4 points.  It is likely, but not guaranteed,  that the first three are the ones that are being used to define the flat plane of interest to the user. I did not idiot proof the code (not a good idea) and assumed the first three points are the ones to use.  My main goal was to find the maximum slope and simplify the coding with some basic assumptions.  Feel free to edit my code to handle invalid faces.

Posted

@motee-z

"i want the numerical  value of the slope to be aligned with the slope line drawn by the lisp."

 

That reduces the orientation to an infinity of choices as the text could be rotated about the slope line and still be aligned with it!  Should I assume you do not care which one is used?

Posted
24 minutes ago, lrm said:

.... Feel free to edit my code to handle invalid faces.

No, thanks, I don't need it.. I just wanted to point out that you will get an error eventually.

It's your decision, and your time, if you want to add it to your code or not.

Posted

Whilst civ3d has slope arrow I dont think you can add a slope text as a surface style. But it is useful to test against a series of 3dfaces can compare result lisp versus arrow. I still think the nor (p1,p2,p3) is useful just not sure how to interpret the x y z compared to (0 0 0)  

 ang1=nor(p1,p2,p3)

(angle '(0. 0. 0.) ang1)

 

Posted

@motee-z

 

Here's a revised version that adds text to the face with the slope value.  It also checks that the firsts 3 vertices of the face are not duplicates.  It does not check to see if they are collinear.

 

;; Determine the maximum slope of a 3dface.
;; 7/13/2020
(defun c:FaceSlope (/ ss en edata p1 p2 p3 v1 sv a slope midpt s endpt)
  (setq oldsnap (getvar "osmode"))
  (setvar "osmode" 0)
  (princ "\nPlease select 3DFACE and press ENTER.")
  (setq	ss    (ssget)
	en    (ssname ss 0)
	edata (entget en)
  )
  (setvar "cmdecho" 0)
  (if (= (cdr (assoc 0 edata)) "3DFACE")
    (progn
      (setq p1 (cdr (assoc 10 edata))	;set p1, p2, p3 to the three vertices of the 3DFACE
	    p2 (cdr (assoc 11 edata))
	    p3 (cdr (assoc 12 edata))
      )
      (if (or (equal p1 p2 0.0001)
	      (equal p1 p3 0.0001)
	      (equal p3 p2 0.0001)
	  )
	(princ "\nThe first 3 vertices of the face are not unique.")
	(progn
	  (setq normal (cross (mapcar '- p2 p1) (mapcar '- p3 p1)))
	  (setq v1 (cross '(0.0 0.0 1.0) normal))
	  (setq sv (cross v1 normal))
	  (setq a (distance '(0 0 0) sv))
	  (setq sv (mapcar '/ sv (list a a a)))
	  (setq a (expt (+ (expt (car sv) 2) (expt (cadr sv) 2)) 0.5))
	  ;; check if a = 0
	  (if (< (abs a) 0.00001)
	    (setq slope "Vertical")
	    (setq slope (/ (caddr sv) a))
	  )
	  (princ "\nThe slope is: ")
	  (princ slope)
	  (princ "\nThe slope vector is: ")
	  (princ sv)

	  (setq midpt (mapcar '/ (mapcar '+ p1 p2 p3) '(3.0 3.0 3.0)))
	  (setq
	    s (/ (+ (distance p1 p2) (distance p2 p3) (distance p1 p3)) 3.0)
	  )
	  (setq endpt (mapcar '+ midpt (mapcar '* sv (list s s s))))
	  (command "_line" midpt endpt "")
	  ;; draw line showing maximum slope

	  (setq slope (LM:roundto slope 3))
	  (command "text" midpt "" "" slope "")
	)				; end if false, no duplicates
      )					;end true, is face 
    )					; end if duplicate
       (princ "\nSelected object must be a face.")
 )					; end if face
  (setvar "osmode" oldsnap)
  (setvar "cmdecho" 1)
  (princ)
)
;;; Compute the cross product of 2 vectors a and b
(defun cross (a b / crs)
  (setq	crs (list
	      (- (* (nth 1 a) (nth 2 b))
		 (* (nth 1 b) (nth 2 a))
	      )
	      (- (* (nth 0 b) (nth 2 a))
		 (* (nth 0 a) (nth 2 b))
	      )
	      (- (* (nth 0 a) (nth 1 b))
		 (* (nth 0 b) (nth 1 a))
	      )
	    )				;end list
  )					;end setq c
)					;end cross
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Round Multiple  -  Lee Mac
;; Rounds 'n' to the nearest multiple of 'm'
(defun LM:roundm (n m)
  (* m (atoi (rtos (/ n (float m)) 2 0)))
)
;; Round To  -  Lee Mac
;; Rounds 'n' to 'p' decimal places
(defun LM:roundto (n p)
  (LM:roundm n (expt 10.0 (- p)))
)

 

  • Thanks 1
Posted

Thank you Mr Irm

the text of the slope is not aligned with line can you repair it

Posted

You didn't respond to my question about the orientation so I placed it parallel to the XY world plane..  

Posted

Had a look in CIV3d the display slope and your code look like they match, well done. The slope in CIV3d has a rainbow as its variation in slope.

Posted

Thanks for All especially for Mr Irm

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...