;;; Okrąg wpisany w trójkąt
;;; zwcad.pl
;;; Polecenie do uruchomienia skryptu LISP: trojkat
;;; Opis: https://www.zwcad.pl/materialy-edukacyjne/kurs-lisp/przyklady-lisp/289-okrag-wpisany-w-trojkat.html

; W tym przykładzie chciałbym zaprezentować kilka funkcji matematycznych w LISP.
; Standardowe funkcje ZWCADA pozwalają na narysowanie okręgu stycznego do trzech obiektów. 
; Wykorzystanie ich w LISP jest nieco skomplikowane, dodatkowo jeśli chcemy narysować okrąg
; styczny do linii 'wirtualnych' np zdefiniowanych w bloku konieczne jest opracowanie własnej
; funkcji definiującej okrąg wpisany w trójkąt. 
(vl-load-com)
(setq *ZWCAD* (vlax-get-acad-object))
(setq *Rysunek* (vla-get-activedocument *ZWCAD* ))
(setq *Model* (vla-get-Modelspace *Rysunek* ))
(defun DPL (P0 A1 A2 / A B P X H)
	(setq A (distance P0 A1))
	(setq B (distance P0 A2))
	(setq P (distance A1 A2))
	(setq X (abs (/(-(+(* P P) (* A A))(* B B)) ( * P 2))))
	(setq H (sqrt (- (* A A) (* X X))))
	H
)
(defun C:trojkat ( / )
(setq A (getpoint "Wkaż 1 narożnik trójkąta" ))
(setq B (getpoint "Wkaż 2 narożnik trójkąta" ))
(setq C (getpoint "Wkaż 3 narożnik trójkąta" ))
(setq katAB (angle A B ) )		; obliczamy kąt nachylenia linii 
(setq katAC (angle A C ) )		; względem osi OX
(setq katBA (angle B A ) )		; dla każdej pary punktów
(setq katBC (angle B C ) )
 (setq Aprim (polar A (+ katAB (/(- katAC katAB) 2.0)) (/(distance A B) 2.0)))	; obliczamy punkt na dwusiecznej kąta
 (setq midptA(vlax-invoke-method *Model* 'AddPoint (vlax-3d-point Aprim ) ))	; kontrolnie wstawiamy punkt w obliczonych współrzędnych. Nie jest to konieczne, jedynie dla zobrazowania poprawności wykonania obliczeń
 (setq Bprim (polar B (+ katBC (/(- katBA katBC) 2.0)) (/(distance B C) 2.0))); obliczamy punkt na dwusiecznej kąta
 (setq midptB(vlax-invoke-method *Model* 'AddPoint (vlax-3d-point Bprim ) ))
 (setq D(inters A Aprim B Bprim nil))		; Wyznaczamy punkt przecięcia linii zdefiniowanych przez punkty A, Aprim i B Bprim
 (setq DPt(vlax-invoke-method *Model* 'AddPoint (vlax-3d-point D ) )) ; kontrolnie wstawiamy punkt na przecięciu linii
 (setq R (DPL D A B ))	; obliczamy promień okręgu przez wyznaczenie odległości punktu środkowego okręgu od odcinka AB
 (vlax-invoke-method *Model* 'AddCircle (vlax-3d-point D ) R)	; Rysujemy okrąg.
)