Warning: this is an htmlized version! The original is across this link, and the conversion rules are here.
```;; Calculadora para Geometria Analítica
;; 2004jun24

(defun nn_ponto (x_ y_ &optional nome)
(let ((p_ (list 'ponto x_ y_ nome)))
(if (and nome (symbolp nome))
(set nome p_))
p_))

(defun nn_vetor (dx_ dy_ &optional nome)
(let ((v_ (list 'vetor dx_ dy_ nome)))
(if (and nome (symbolp nome))
(set nome v_))
v_))

(defun nnnn_segmento (x1_ y1_ x2_ y2_ &optional nome)
(let ((s_ (list 'segmento x1_ y1_ x2_ y2_ nome)))
(if (and nome (symbolp nome))
(set nome s_))
s_))

(defun nnn_reta (a_ b_ c_ &optional nome)
(let ((r_ (list 'reta a_ b_ c_ nome)))
(if (and nome (symbolp nome))
(set nome r_))
r_))

(defun @x  (p) (nth 1 p))
(defun @y  (p) (nth 2 p))
(defun @dx (v) (nth 1 v))
(defun @dy (v) (nth 2 v))
(defun @x1 (s) (nth 1 s))
(defun @y1 (s) (nth 2 s))
(defun @x2 (s) (nth 3 s))
(defun @y2 (s) (nth 4 s))
(defun @a  (r) (nth 1 r))
(defun @b  (r) (nth 2 r))
(defun @c  (r) (nth 3 r))

(defun vv_+ (v_ w_ &optional nome)
(nn_vetor (+ (@dx v_) (@dx w_)) (+ (@dy v_) (@dy w_)) nome))
(defun pv_+ (p_ v_ &optional nome)
(nn_ponto (+ (@x p_) (@dx v_)) (+ (@y p_) (@dy v_)) nome))
(defun vn_* (v_ n_ &optional nome)
(nn_vetor (* (@dx v_) n_) (* (@dy v_) n_) nome))
(defun pp_segmento (p1_ p2_ &optional nome)
(nnnn_segmento (@x p1_) (@y p1_) (@x p2_) (@y p2_) nome))
(defun s_vetor (s_ &optional nome)
(nn_vetor (- (@x2 s_) (@x1 s_)) (- (@y2 s_) (@y1 s_)) nome))
(defun pp_-> (orig_ extr_ &optional nome)
(nn_vetor (- (@x extr_) (@x orig_)) (- (@y extr_) (@y orig_)) nome))
(defun v_comprimento (v)
(sqrt (+ (* (@dx v) (@dx v)) (* (@dy v) (@dy v)))))
(defun pp_distancia (p1 p2)
(v_comprimento (pp_-> p1 p2)))
(defun v_versor (v_ &optional nome)
(vn_* v_ (/ 1.0 (v_comprimento v_)) nome))

(defun s_reta (s_ &optional nome)
(let* ((x1_ (@x1 s_))
(y1_ (@y1 s_))
(x2_ (@x2 s_))
(y2_ (@y2 s_))
(a_ (- y1_ y2_))
(b_ (- x2_ x1_))
(c_ (- (* x2_ y1_) (* x1_ y2_))))
(nnn_reta a_ b_ c_ nome)))

;; Pra calcular o ponto onde duas retas se cruzam a gente inverte uma
;; matriz 2x2...
;;
;; (a1 b1) (x)   (c1)
;; (     ) ( ) = (  )
;; (a2 b2) (y)   (c2)
;;
;;         (x)      1      ( b2 -b1) (c1)
;;   ==>   ( ) = --------- (       ) (  )
;;         (y)   a1b2-a2b1 (-a2  a1) (c2)
;;
(defun rr_cruzamento (r1_ r2_ &optional nome)
(let* ((a1_ (@a r1_))
(b1_ (@b r1_))
(c1_ (@c r1_))
(a2_ (@a r2_))
(b2_ (@b r2_))
(c2_ (@c r2_))
(det_ (- (* a1_ b2_) (* a2_ b1_))) ; determinante
(b2c1-b1c2_ (- (* b2_ c1_) (* b1_ c2_))) ; numerador do x
(-a2c1+a1c2_ (- (* a1_ c2_) (* a2_ c1_)))) ; numerador do y
(nn_ponto (/  b2c1-b1c2_ det_)
(/ -a2c1+a1c2_ det_)
nome)))

(defun pp_reta (A_ B_ &optional nome)
(s_reta (pp_segmento A_ B_) nome))

;; Testes
;;
(defun eqreduzida (r)
(let ((a (@a r)) (b (@b r)) (c (@c r)))
(list 'y '= (/ a -1.0 b) 'x '+ (/ c 1.0 b))))
(defun eqgeral (r)
(let ((a (@a r)) (b (@b r)) (c (@c r)))
(list a 'x '+ b 'y '= c)))

(defun testa_reta (x1_ y1_ x2_ y2_)
(let (A B AB)
(nn_ponto x1_ y1_ 'A)
(nn_ponto x2_ y2_ 'B)
(s_reta (pp_segmento A B) 'AB)
(list A B AB (eqgeral AB) (eqreduzida AB))))

(defun testa_cruzamento (x1_ y1_ x2_ y2_ x3_ y3_)
(let (A B C AB AC D=A)
(nn_ponto x1_ y1_ 'A)
(nn_ponto x2_ y2_ 'B)
(nn_ponto x3_ y3_ 'C)
(s_reta (pp_segmento A B) 'AB)
(s_reta (pp_segmento A C) 'AC)
(rr_cruzamento AB AC 'D=A)
(list A B C AB AC D=A)))

;; (testa_reta 1 2 4 1)
;; (testa_cruzamento 1 2  4 1  2 0)
```