motee-z Posted June 26, 2020 Share Posted June 26, 2020 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 Quote Link to comment Share on other sites More sharing options...
Stefan BMR Posted June 26, 2020 Share Posted June 26, 2020 (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 June 27, 2020 by Stefan BMR small simplification Quote Link to comment Share on other sites More sharing options...
BIGAL Posted June 26, 2020 Share Posted June 26, 2020 Do you have CIV3D its a surface style option, it displays a arrow on each Triangle. For me Slope Arrows & Catchments Quote Link to comment Share on other sites More sharing options...
lrm Posted June 27, 2020 Share Posted June 27, 2020 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Quote Link to comment Share on other sites More sharing options...
BIGAL Posted June 27, 2020 Share Posted June 27, 2020 (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 June 27, 2020 by BIGAL Quote Link to comment Share on other sites More sharing options...
motee-z Posted July 11, 2020 Author Share Posted July 11, 2020 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 Quote Link to comment Share on other sites More sharing options...
lrm Posted July 12, 2020 Share Posted July 12, 2020 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Quote Link to comment Share on other sites More sharing options...
motee-z Posted July 12, 2020 Author Share Posted July 12, 2020 Thank you Mr Irm for your routine it is excellent but if you print slop value on the line that indicates the direction Quote Link to comment Share on other sites More sharing options...
lrm Posted July 12, 2020 Share Posted July 12, 2020 @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. Quote Link to comment Share on other sites More sharing options...
motee-z Posted July 12, 2020 Author Share Posted July 12, 2020 (edited) i want the numerical value text of the slope to be aligned with the slope line drawn by the lisp. thanks Edited July 12, 2020 by motee-z Quote Link to comment Share on other sites More sharing options...
Stefan BMR Posted July 12, 2020 Share Posted July 12, 2020 (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 July 12, 2020 by Stefan BMR Quote Link to comment Share on other sites More sharing options...
lrm Posted July 12, 2020 Share Posted July 12, 2020 @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. Quote Link to comment Share on other sites More sharing options...
lrm Posted July 12, 2020 Share Posted July 12, 2020 @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? Quote Link to comment Share on other sites More sharing options...
Stefan BMR Posted July 12, 2020 Share Posted July 12, 2020 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. Quote Link to comment Share on other sites More sharing options...
BIGAL Posted July 13, 2020 Share Posted July 13, 2020 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) Quote Link to comment Share on other sites More sharing options...
lrm Posted July 13, 2020 Share Posted July 13, 2020 @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))) ) 1 Quote Link to comment Share on other sites More sharing options...
motee-z Posted July 13, 2020 Author Share Posted July 13, 2020 Thank you Mr Irm the text of the slope is not aligned with line can you repair it Quote Link to comment Share on other sites More sharing options...
lrm Posted July 14, 2020 Share Posted July 14, 2020 You didn't respond to my question about the orientation so I placed it parallel to the XY world plane.. Quote Link to comment Share on other sites More sharing options...
BIGAL Posted July 14, 2020 Share Posted July 14, 2020 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. Quote Link to comment Share on other sites More sharing options...
motee-z Posted July 15, 2020 Author Share Posted July 15, 2020 Thanks for All especially for Mr Irm Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.