Jump to content

Recommended Posts

Posted (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 by petkovski
Posted

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

Posted

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

Posted

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.

Posted

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.

Posted

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

Posted

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

  • 1 year later...
Posted

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

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