petkovski Posted July 15, 2010 Posted July 15, 2010 (edited) Hi everybody! In my work,many times i need to find angle between two planes which are in diferent UCS.Mathematicly,i am able to calculate, but i"m looking for any function that can measure direcly from drawings. Here is my idea of procedure if somebody can help.Thanks. Command: _3DAngle (measure an angle between two planes in degree) inputs : pt1,pt2,pt3,pt4,pt5,pt6,pt7,pt8,pt9 prompt: Select 3 points of first plane : select first point and assign like (pt1) select second point and assign like (pt2) select third point and assign like (pt3) set UCS to already selected 3 points **silence command,working in backround command _line : where the start point will be (pt4) and end point will be (pt5) first point (pt4) = mid point of (pt1) and (pt2) end point (pt5) with coordinates X=0,Y=0,Z=100(or any dim,not limited) (where Z is end point) prompt: Select 3 points of second plane : select first point and assign like (pt6) select second point and assign like (pt7) select third point and assign like (pt8) set UCS to already selected 3 points **silence command,working in backround command _line : where the start point will be (pt4)and end point will be (pt9) first point (pt4) = mid point of (pt1) and (pt2) (already assign in first plane) end point (pt9) with coordinates X=0,Y=0,Z=100(or any dim,not limited) (where Z is end point) ** silence command working in backround command _ucs points of thirtd plane ( where we will measure the angle) : first point is (pt4) second point is (pt5) third point is (pt9) set UCS to those 3 points ** silence command,working in backround _dimangular select first vector,line, which is between points (pt4 - pt5) select secod vector,line,which is between points (pt4 - pt9) get result in degree substract (180 - result) =angle get the angle text and insert in drawing with an insertion point. Return ucs to "world" status I understand how to get the result , but i am new in writing lisps. I will appreciate any help in writing this code or any other option. Thx Edited July 19, 2010 by petkovski Quote
CALCAD Posted July 19, 2010 Posted July 19, 2010 petkovski, Here is a program that follows your method. It's very rough and the code is ugly, but it works. (Real programmers are chuckling all over the world). It needs error trapping, output formatting and other cleanup. I hope you can use it. I will keep working on this as time permits. Thanks for the procedure. I have wanted something like this for some time and just needed the method, which you provided. (defun c:apl (/ osave p1 p2 p3 p4 p5 p6 px py pz pperp p2perp) (setq osave (getvar "OSMODE")) (command ".UCS" "") (setq p1 (getpoint "\n Get first point on first plane")) (setq p2 (getpoint "\n Get second point")) (setq p3 (getpoint "\n Get third point")) (setq p4 (getpoint "\n Get first point on second plane")) (setq p5 (getpoint "\n Get second point")) (setq p6 (getpoint "\n Get third point")) (setvar "CMDECHO" 0) (setvar "OSMODE" 0) (setq p1w p1) (command ".UCS" 3 p1 p2 p3) (setq p1 (trans p1 0 1)) (command ".UCS" "O" p1) (setq px (car p1)) (setq py (cadr p1)) (setq pz (caddr p1)) (setq pperp (list px py (+ pz 1.0))) (command "line" (list 0 0 0) pperp "") (setq fline (entlast)) (command ".UCS" "") (command ".UCS" 3 p4 p5 p6) (setq p4 (trans p4 0 1)) (command ".UCS" "O" p4) (setq px (car p4)) (setq py (cadr p4)) (setq pz (caddr p4)) (setq p2perp (list px py (+ pz 1.0))) (command "line" (list 0 0 0) p2perp "") (setq p1w (trans p1w 0 1)) (command ".MOVE" (entlast) "" (list 0 0 0) p1w) (setq fn (entget fline)) (setq f1 (cdr (assoc 10 fn))) (setq f2 (cdr (assoc 11 fn))) (setq ln (entget (entlast))) (setq f4 (cdr (assoc 11 ln))) (command ".UCS" "") (command ".UCS" 3 f1 f2 f4) (setq f1 (trans f1 0 1)) (setq f2 (trans f2 0 1)) (setq f4 (trans f4 0 1)) (setq ang1 (angle f1 f2)) (setq ang2 (angle f1 f4)) (princ "\nang1 = ")(princ ang1) (princ "\nang2 = ")(princ ang2) (setvar "OSMODE" osave) (setvar "CMDECHO" 1) (princ) ) Quote
gile Posted July 19, 2010 Posted July 19, 2010 Hi, Assuming the angle between two planes is equal to the 3d angle between the normal vectors of these planes, I thaught this should be an easier way to deal with this. Here're some geometric routines (maybe usefull) used by the 'AnglePlanePlane' routine which requires the single unit normal vector of each plane as arguments. ;; AnglePlanePlane ;; Returns the angle (radians) between two planes (using Al Kashi theorem) ;; the returned angle is always between 0 and pi radians ;; ;; Arguments: the single unit normal vectors of the planes (defun AnglePlanePlane (nor1 nor2) ((lambda (d) (acos (/ (- 2 (* d d)) 2)) ) (distance nor1 nor2) ) ) ;;; Acos ;;; Returns the Arc Cosine of number ;;; ;;; Argument: a number between -1 and 1 (defun acos (num) (cond ((equal num 1 1e-9) 0.0) ((equal num -1 1e-9) pi) ((< -1 num 1) (atan (sqrt (- 1 (expt num 2))) num) ) ) ) ;; CrossProduct ;; Returns the cross product (vector) of two vectors ;; ;; Arguments: two vectors (defun CrossProduct (v1 v2) (list (- (* (cadr v1) (caddr v2)) (* (caddr v1) (cadr v2))) (- (* (caddr v1) (car v2)) (* (car v1) (caddr v2))) (- (* (car v1) (cadr v2)) (* (cadr v1) (car v2))) ) ) ;; Normalize ;; Returns the single unit vector of a vector ;; ;; Argument : un vecteur (defun Normalize (v) ((lambda (l) (if (/= 0 l) (mapcar (function (lambda (x) (/ x l))) v) ) ) (distance '(0 0 0) v) ) ) ;; Norm_3Points ;; Returns the single unit normal vector of a plane definedby 3 points ;; ;; Arguments: three points (defun norm_3pts (p0 p1 p2) (Normalize (CrossProduct (mapcar '- p1 p0) (mapcar '- p2 p0))) ) Here's a test command which prompt the user to specify 3 points on each plane and returns the result on command line in current angle units. (defun c:test (/ a) (if (vl-catch-all-error-p (setq a (vl-catch-all-apply '(lambda (/ p1 p2 p3 p4 p5 p6) (setq p1 (getpoint "\nFirst point on first plane: ") p2 (getpoint p1 "\nSecond point on first plane: ") p3 (getpoint p1 "\nThird point on first plane: ") p4 (getpoint "\nFirst point on second plane: ") p5 (getpoint p4 "\nSecond point on second plane: ") p6 (getpoint p4 "\nThird point on second plane: ") ) (princ (strcat "\nAngle beween planes = " (angtos (AnglePlanePlane (norm_3pts p1 p2 p3) (norm_3pts p4 p5 p6)) ) ) ) ) ) ) ) (princ (strcat "\nerror: " (vl-catch-all-error-message a))) ) (princ) ) Quote
petkovski Posted July 19, 2010 Author Posted July 19, 2010 Thanks to both replays. Yes.angle between the normals of each plane is actualy angle between planes,and that i was try to explain in procedure. I will test now the both code. Quote
petkovski Posted July 20, 2010 Author Posted July 20, 2010 Calcad, code is working,and as you say need some cleanups. In my explenation,with expression "silence command" or "working in backround" ,i was mean to don't draw the normals in windows(drawing),that process to be hiden,and that happening with this code. Output is in radians,steady degree. UCS is "freeze" on last chosen plane ,need to return to the "world status" after the command finish. Second code,thanks to Gile, work as i expect. Just minor comment: in both code what missing is command to insert the result like text in drawing with an insertion point. Anyway,i am satisfy and thanks to both for your effort. Quote
petkovski Posted July 22, 2010 Author Posted July 22, 2010 Hi, i will be free and ask the author or someone else to add a command in second code to insert the result in drawing like text with an insertion point. Thx in advance Quote
gile Posted July 22, 2010 Posted July 22, 2010 Hi, Replace: (princ (strcat "\nAngle beween planes = " (angtos (AnglePlanePlane (norm_3pts p1 p2 p3) (norm_3pts p4 p5 p6)) ) ) ) with (command "_.text" pause "" "" (angtos (AnglePlanePlane (norm_3pts p1 p2 p3) (norm_3pts p4 p5 p6) ) ) ) The text is created at specified point on the current UCS plane with the current settings (size, style, ...). Quote
petkovski Posted January 8, 2012 Author Posted January 8, 2012 Hi, I will ask for help,mybe answer from author of code is best solution. When i exchange part of code to insert text in drawing i am getting an error. Executting command text: "Command: _.3DAngle First point on first plane: Second point on first plane: Third point on first plane: First point on second plane: Second point on second plane: Third point on second plane: _.text Current text style: "STANDARD" Text height: 250.00 Specify start point of text or [Justify/Style]: Specify rotation angle of text : Enter text: Command: 179.79 Unknown command "179.79". Press F1 for help." Maybe i am doing something wrong? Another question: Did enywhere in code controll decimal precision? Thank you in advance for any replay. 3dangle.lsp Quote
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.