Grdraw Arc passing by 3 points (UCS) with N segments

_Bilal
Advocate
Advocate

Grdraw Arc passing by 3 points (UCS) with N segments

_Bilal
Advocate
Advocate

 

 

 

; **
; * ba:3pgrarc grdraw an arc with n segments - Bilal
; * p1, p2 and p3		1st, 2nd and 3rd points (UCS)
; * n segments number
; **
;========================================================================================
(defun ba:3pgrarc ( p1 p2 p3 n / lst cen rds pc s ps va arcangle pa a ang plst ang* x y px p p0 )
;========================================================================================
	
	;Get center and radius of the arc passing by p1, p2, p3
	(if (setq lst (circleBy3Points p1 p2 p3))
		(progn
			(setq cen (car lst) rds (cadr lst) pc (mid p1 p3))
			(if (equal cen pc 1e-9)
				(setq s		(* (distance p1 p2)(cos (atan (distance p2 p3) (distance p2 p1))))
					  ps 	(mapcar '+ p1 (mapcar '(lambda (u) (* u s)) (vx1 (mapcar '- p3 p1))))
					  va 	(vx1 (mapcar '- ps p2))
					  pa 	(mapcar '+ cen (mapcar '(lambda (u) (* rds u)) va))
					  arcangle pi
				)
				(if (inters p1 p3 p2 cen)
					(progn
						(setq arcangle (* 2 (atan (distance p1 pc) (distance cen pc))))
						(setq pa (mapcar '+ cen (mapcar '(lambda (u) (* rds u)) (vx1 (mapcar '- cen pc)))))
					)
					(progn
						(setq arcangle (* 2 (atan (distance p1 pc) (- (distance cen pc)))))
						(setq pa (mapcar '+ cen (mapcar '(lambda (u) (* rds u)) (vx1 (mapcar '- pc cen)))))
					)
				)
			)
			;Initial values
			(setq a (/ arcangle n) ang 0.0 plst nil)
			(repeat n
				(setq ang	(+ ang a)
					  ang* 	(- (/ arcangle 4.0) (/ ang 2.0))
					  x 	(- (distance p1 pc) (* (distance pa pc) (/ (sin ang*) (cos ang*))))
					  y 	(/ (+ rds (* rds (cos (- (/ arcangle 2) ang)))) (cos ang*))
					  px 	(mapcar '+ p1 (mapcar '(lambda (u) (* u x)) (vx1 (mapcar '- p3 p1))))
					  p 	(mapcar '+ pa (mapcar '(lambda (u) (* u y)) (vx1 (mapcar '- px pa))))
					  plst 	(cons p plst)
				)
			)
			(setq plst (reverse plst))

			;grdraw segments
			(setq p0 p1)
			(foreach p plst (grdraw p0 (setq p0 p) 1))
		)
	)

;------------------	
);Endof//ba:3pgrarc
;------------------


;; Midpoint  -  Lee Mac
;; Returns the midpoint of two points
(defun mid ( a b )
    (mapcar (function (lambda ( a b ) (/ (+ a b) 2.0))) a b)
)

;; V^V
;; Cross product of two vectors
(defun v^v (u v)
	(list
		(- (* (cadr u) (caddr v)) (* (caddr u) (cadr v)))
		(- (* (caddr u) (car v)) (* (car u) (caddr v)))
		(- (* (car u) (cadr v)) (* (cadr u) (car v)))
	)
);V^V

; * Circle by 3 points  -  Gile
; * Returns the center (UCS) and radius of the circle defined by 3 points (UCS).
(defun circleBy3Points (p1 p2 p3 / v1 v2 norm m1 m2 cen)
	(setq 	v1   (mapcar '- p2 p1)
			v2   (mapcar '- p3 p2)
			norm (v^v v1 v2)
			m1   (mid p1 p2)
			m2   (mid p2 p3)
			cen (inters
					m1 (mapcar '+ m1 (v^v v1 norm))
					m2 (mapcar '+ m2 (v^v v2 norm))
					nil
				)
	)
	(list cen (distance cen p1))
)

;; Unit Vector  -  Lee Mac
;; Args: v - vector in R^2 or R^3

(defun vx1 ( v )
    (   (lambda ( n ) (if (equal 0.0 n 1e-10) nil (mapcar '/ v (list n n n))))
        (distance '(0.0 0.0 0.0) v)
    )
)

 

 

 

Trigonometric calculation are based on the this figure

ba-3pgrarc.jpg

0 Likes
Reply
400 Views
4 Replies
Replies (4)

hak_vz
Advisor
Advisor

Add function (vx1) to your code. You can edit your original post.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes

CADaSchtroumpf
Advisor
Advisor

This grdraw an arc, but alway in ant-clockwise

((lambda ( / p1 p2 ll pt_m px1 px2 key p3 px3 px4 pt_cen rad inc ang nm lst_pt pa1 pa2)
  (initget 9)
  (setq p1 (getpoint "\nFirst point: "))
  (initget 9)
  (setq p2 (getpoint p1 "\nNext point: "))
  (setq
    ll (list p1 p2)
    pt_m
    (mapcar
      '/
      (list
        (apply '+ (mapcar 'car ll))
        (apply '+ (mapcar 'cadr ll))
        (apply '+ (mapcar 'caddr ll))
      )
      '(2.0 2.0 2.0)
    )
    px1 (polar pt_m (+ (angle p1 p2) (* pi 0.5)) (distance p1 p2))
    px2 (polar pt_m (- (angle p1 p2) (* pi 0.5)) (distance p1 p2))
  )
  (princ "\nLast point: ")
  (while (and (setq key (grread T 4 0)) (/= (car key) 3))
    (cond
      ((eq (car key) 5)
        (redraw)
        (setq
          p3 (cadr key)
          ll (list p1 p3)
          pt_m
          (mapcar
            '/
            (list
              (apply '+ (mapcar 'car ll))
              (apply '+ (mapcar 'cadr ll))
              (apply '+ (mapcar 'caddr ll))
            )
            '(2.0 2.0 2.0)
          )
          px3 (polar pt_m (+ (angle p1 p3) (* pi 0.5)) (distance p1 p3))
          px4 (polar pt_m (- (angle p1 p3) (* pi 0.5)) (distance p1 p3))
          pt_cen (inters px1 px2 px3 px4 nil)
        )
        (cond
          (pt_cen
            (setq 
              rad (distance pt_cen p3)
              inc (angle pt_cen p1)
              ang (+ (* 2.0 pi) (angle pt_cen p3))
              nm (fix (/ (rem (- ang inc) (* 2.0 pi)) (/ (* pi 2.0) 36.0)))
              lst_pt '()
            )
            (if (zerop nm) (setq nm 1))
            (repeat nm
              (setq
                pa1 (polar pt_cen inc rad)
                inc (+ inc (/ (* pi 2.0) 36.0))
                pa2 (polar pt_cen inc rad)
                lst_pt (append lst_pt (list pa1 pa2))
              )
            )
            (setq lst_pt (append lst_pt (list pa2 p3)))
            (grvecs lst_pt)
          )
        )
      )
    )
  )
  (prin1)
))

 

0 Likes

_Bilal
Advocate
Advocate

thank you for your comment, I edit the post accordingly

0 Likes

_Bilal
Advocate
Advocate

I edited the code to fix the case when the arcangle become = pi to avoide the dividing by 0.0

0 Likes