;exercício de programação realizado por Camila Oliveira 20130244 | Elia Bombardini 20158194 | João Lopes 20130119 | Manuel Caldeira 20130195
;Modelação e visualização Tridimensional em Arquitectura | Prof. Luís Romão | MIARQ 3DD
;A ser implantada no Parque de estacionamento Sul da Faculdade de Arquitectura, esta macro realiza diversas formas, todas baseadas nas mesmas premissas mas com valores diferentes, logo com aspectos bastante diferentes
;Cada membro do grupo selecionou uma forma diferente gerada por este ficheiro

;nesta secção definimos os valores aleatórios que farão com que a macro gere formas sempre diferente

(defun valor (num)
;(fix (* num (rnd)))
(* num (rnd))
)
(defun rnd (/ modulus multiplier increment random)
  (if (not seed)
    (setq seed (getvar "DATE"))
  )
  (setq modulus    65536
        multiplier 25173
        increment  13849
        seed  (rem (+ (* multiplier seed) increment) modulus)
        random     (/ seed modulus)
  )
)


;sendo que a forma terá de ser implantada num terreno da faculdade, percebemos através de um referencial implantado no terreno, que a posição do primeiro circulo teria de ser igual para todos para garantir um afastamento da empena necessario.
;neste ponto definimos então a posição do centro do círculo e o seu raio. este circulo irá marcar as entradas individuais de cada forma
 
(defun circulo ()
	(command "UCS" "Y" "90")
	(command "circle" (list 0 7.5 -3) 7)
	(set (read (strcat "entidade0")) (entlast))
	(command "UCS" "WORLD")
)

;neste ponto definimos como serão desenhados os vários círculos que iram compor a forma. não só definimos que valores estes devem assumir (aleatórios), como também em que plano devem ser desenhados, alterando o UCS e dizendo que estes devem ter uma pequena rotação entre eles (esta também aleatória)
;nesta função defini-se também que cada círculo deve ter o nome "entidade", seguido de um número que depende da ordem em que este foi desenhado

(defun desenhar ()
(command "UCS" "Y" "90")
	(dados)
	(command "circle" (list x y z) r)
	(set (read (strcat "entidade" (rtos nu))) (entlast))
	(command "UCS" "World")
	(command "rotate" (entlast) "" "0,0,0" a)
)

;nesta função é definida a forma como o sólido deve ser feito, ou seja, com o comando loft vamos unir todos os círculos que foram desenhados (numero de repetições é definido posteriormente) para formar uma única forma

	(defun solido ()
	(command "loft" entidade0
					entidade1 
					entidade2
					entidade3
					entidade4	
					entidade5
					entidade6			
					"" ""
	)
)

;finalmente juntamos todas as funções que pré-definimos anteriormente num só comando que vai realizar todas as acções no autocad
;com as linhas inicias fazemos uma limpeza geral à área de trabalho para termos o ecrã vazio
;começamos por desenhar uma caixa que tem as medidas, em largura, comprimento e altura do nosso terreno
;mandamos realizar a função que definimos anteriormente que ia desenhar o primeiro círculo
;e agora definimos que a função desenhar, que faz os círculos que compõem a forma, deve-se repetir 6 vezes, onde de seguida realizamos a função loft
;para gerarmos a forma final, o comando intersect faz com que a caixa corte o sólido para garantir que esta encaixa apenas dentro da área que queremos

(defun c:lombriga ()
	(command "erase" "all" "")
	(setq pontos2d (getvar "osmode"))
	(setq pontos3d (getvar "3dosmode"))
	(setvar "osmode" 0)
	(setvar "3dosmode" 0)
	(setq nu 0)
	(setq eixo (/ pi 2))
	(setq z 0)

	(command "box" (list 0 0) (list 45 13.5 20))
	(set (read (strcat "caixa")) (entlast))
	(setq nu (+ 1 nu))
	(circulo)
	
	(repeat 6
		(desenhar)
		(setq nu (+ 1 nu))
	)
	
	(solido)
	(command "INTERSECT" (entlast) entidade0 caixa "")
		(setq 	entidade0 nil
				entidade1 nil
				entidade2 nil
				entidade3 nil
				entidade4 nil
				entidade5 nil
				entidade6 nil
				x nil
				y nil
				z nil
				r nil)
	(setvar "osmode" pontos2d)
	(setvar "3dosmode" pontos3d)	
)

;nesta secção definos alguns valores limites tanto para o x y z dos centros do círculo, como para o raio destes e para o angulo

(defun dados ()
	(setq x (valor (- 15.0)))
	(setq y (valor 15.0))
	(setq z (+ (valor 12.0) z 2.0))
	(setq r (+ (valor 1.5) 3.5))
	(setq a (valor 18.0))

)