Skip to content

Commit

Permalink
1 fuente luminosa, 3 sections. cambiados parámetros de refleccion de …
Browse files Browse the repository at this point in the history
…cuerpos
  • Loading branch information
camilovergara committed Jun 15, 2010
1 parent 184220f commit 46c5b4d
Show file tree
Hide file tree
Showing 6 changed files with 770 additions and 443 deletions.
576 changes: 347 additions & 229 deletions cuerpos.py

Large diffs are not rendered by default.

230 changes: 180 additions & 50 deletions functions.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
from numpy import *
from patch import *
from punto import *
from variables import *

# global patchesList

global patchesList
counter = 0
# recibe 2 parches i y j, retorna el F_ij (al parecer, F_ij != F_ji)
def formfactor(p_i,p_j,visib):
def formfactor(i,j,visib):
if(i==j):
return 0.0
p_i = patchesList[i]
p_j = patchesList[j]
# patchesList = PL
# segun http://www.gamedev.net/reference/articles/article653.asp
# http://wiki.cgsociety.org/index.php/Radiosity#Form_Factor_Determination
Expand All @@ -15,64 +20,189 @@ def formfactor(p_i,p_j,visib):
c_j = p_j.center
n_i = p_i.normal
n_j = p_j.normal
d_ij = Punto(c_i.x-c_j.x, c_i.y-c_j.y, c_i.z-c_j.z)
d_ij = c_i.resta(c_j, 1)

r = math.sqrt(math.pow(c_i.x-c_j.x,2)+math.pow(c_i.y-c_j.y,2)+math.pow(c_i.z-c_j.z,2)) #centro p_i, p_j
if r==0:
return 0
r = math.sqrt( (c_i.x-c_j.x)**2 + (c_i.y-c_j.y)**2 + (c_i.z-c_j.z)**2) #centro p_i, p_j
if (r==0):
return 0.0

dAj = p_j.area
H_ij = visib # en este caso, todos los parches son visibles para todos (no hay obstaculos)
H_ij = visib

#cosenos segun http://www.geoan.com/vectores/angulo.html
costi = (d_ij.x*n_i.x + d_ij.y*n_i.y + d_ij.z*n_i.z)/((math.sqrt(d_ij.x*d_ij.x + d_ij.y*d_ij.y + d_ij.z*d_ij.z))*(math.sqrt(n_i.x*n_i.x+n_i.y*n_i.y+n_i.z*n_i.z)))
costj = (d_ij.x*n_j.x + d_ij.y*n_j.y + d_ij.z*n_j.z)/((math.sqrt(d_ij.x*d_ij.x + d_ij.y*d_ij.y + d_ij.z*d_ij.z))*(math.sqrt(n_j.x*n_j.x+n_j.y*n_j.y+n_j.z*n_j.z)))
costi = (d_ij.x*n_i.x + d_ij.y*n_i.y + d_ij.z*n_i.z)/((math.sqrt(d_ij.x**2 + d_ij.y**2 + d_ij.z**2))*(math.sqrt(n_i.x**2 + n_i.y**2 + n_i.z**2 )))
costj = (d_ij.x*n_j.x + d_ij.y*n_j.y + d_ij.z*n_j.z)/((math.sqrt(d_ij.x**2 + d_ij.y**2 + d_ij.z**2))*(math.sqrt(n_j.x**2 + n_j.y**2 + n_j.z**2 )))

signo = 1.0
# if( costi>0 and costj>0):
# signo = 1.0

# F_ij =
return ((costi*costj)/(math.pi*math.pow(r,2)))*H_ij*dAj
ff = signo * 1.0 * ((costi*costj)/(math.pi*(r**2)))*H_ij*dAj
# print "ff = ",ff
if(ff > 1):
print "ff>1"
return 1.0
if(ff < 0):
return 0.0

return ff

def sistema(a,b):
x = linalg.solve(a, b)
return x

def visibility(i,j) :
p_i = patchesList[i]
p_j = patchesList[j]

# recibe dos parches, y determina el factor de visibilidad entre los centros de ambos (valor 0 o 1)
def visibility(p_i,p_j,PL):
global patchesList
rvalue = 1
patchesList = PL
# global counter
# centros de p_, p_j
ci = p_i.center
cj = p_j.center
# counter = counter + 1
# print "vis ",counter
# PARA CADA PARCHE P EN LA ESCENA
for p in patchesList:
x1 = p_i.center.x
y1 = p_i.center.y
z1 = p_i.center.z

x2 = p_j.center.x
y2 = p_j.center.y
z2 = p_j.center.z

i = (x2-x1)
j = (y2-y1)
k = (z2-z1)

for x, p in enumerate(patchesList):
if(x == i or x == j):
continue
cp = p.center
# CALCULAR ANGULO THETA ENTRE VECTORES PI,PJ Y PI,CP
v = cp.resta(ci,1)
w = cj.resta(ci,1)
if( v.modulo() == 0 or w.modulo() == 0):
return 1
theta = v.anguloEntre(w)
# CALCULAR DISTANCIA COMO (CP-PI)SEN THETA
d = math.sin(theta) * v.modulo()
# CALCULAR MAYOR DISTANCIA ENTRE UN VERTICE DE P Y EL CENTRO DE P (DIS_MAX = DM)
dm = p.pradio
dmm = p.pmradio
# CALCULAR ANGULO ENTRE NORMAL DE P Y R, ANGULO = TH
alpha = p.normal.anguloEntre(w)
# CALCULAR DD = DM*COS(TH) -> 'CUANTO SE ACERCA P A R'
dd = dm*math.cos(alpha)
ddm = dmm*math.cos(alpha)
# SI D < DD => RECTA ATRAVIESA PARCHE
# RETURN 0
if( d < ddm ):
return 0
elif(d < dd):
rvalue = 0.5
# FIN DEL LOOP

# RETURN 1
return rvalue

l = cp.x
m = cp.y
n = cp.z
r = p.pradio

a = i**2 + j**2 + k**2
b = 2*i*(x1 - l) + 2*j*(y1 - m) + 2*k*(z1 - n)
c = l**2 + m**2 + n**2 + x1**2 + y1**2 + z1**2 + 2*(-l*x1 -m*y1 -n*z1) - r**2

det = b**2 - 4*a*c
if(det <= 0):
return 1.0
return 0.0

def visibility2(i,j) :
p_i = patchesList[i]
p_j = patchesList[j]
dist = (p_i.center.resta(p_j.center,1)).modulo()
if( dist == 0):
return 1.0

x1 = p_i.center.x
y1 = p_i.center.y
z1 = p_i.center.z

x2 = p_j.center.x
y2 = p_j.center.y
z2 = p_j.center.z

i = (x2-x1)
j = (y2-y1)
k = (z2-z1)

for x, p in enumerate(patchesList):
if(x == i or x == j):
continue

dist = (p_i.center.resta(p.center,1)).modulo()
if( dist == 0):
continue
dist = (p_j.center.resta(p.center,1)).modulo()
if( dist == 0):
continue

n = p.normal

a = n.x
b = n.y
c = n.z

np = -1.0*n.producto(p.p1)

den = a*i + b*j + c*k
if(den == 0):
# print "den = 0"
continue
num = -1.0*( a*x1 + b*y1 + c*z1 + np)

t = num/den

int_x = x1 + i*t
int_y = y1 + j*t
int_z = z1 + k*t

# print "interseccion ",int_x,"--",int_y,"--",int_z,"--"

inter = Punto(int_x, int_y, int_z)

v1 = p.p1.resta(inter,1)
v2 = p.p2.resta(inter,1)
v3 = p.p3.resta(inter,1)
v4 = p.p4.resta(inter,1)

if( v1.modulo() == 0 or v2.modulo() == 0 or v3.modulo() == 0 or v4.modulo() == 0):
continue

# print v1.imprimir("v1")
# print v2.imprimir("v2")
# print v3.imprimir("v3")
# print v4.imprimir("v4")

ang1 = v1.anguloEntre(v2)
ang2 = v2.anguloEntre(v3)
ang3 = v3.anguloEntre(v4)
ang4 = v4.anguloEntre(v1)
total = ang1 + ang2 + ang3 + ang4

if( total >= 350 ):
return 0.0

return 1.0

# recibe dos parches, y determina el factor de visibilidad entre los centros de ambos (valor 0 o 1)
# def visibility(i,j):
# if(i==j):
# return 1

# p_i = patchesList[i]
# p_j = patchesList[j]
# rvalue = 1
# ci = p_i.center
# cj = p_j.center

# # PARA CADA PARCHE P EN LA ESCENA
# for p in patchesList:
# cp = p.center
# # CALCULAR ANGULO THETA ENTRE VECTORES PI,PJ Y PI,CP
# v = cp.resta(ci,1)
# w = cj.resta(ci,1)
# if( v.modulo() == 0 or w.modulo() == 0):
# return 1
# theta = v.anguloEntre(w)
# # CALCULAR DISTANCIA COMO (CP-PI)SEN THETA
# d = math.sin(theta) * v.modulo()
# # CALCULAR MAYOR DISTANCIA ENTRE UN VERTICE DE P Y EL CENTRO DE P (DIS_MAX = DM)
# dm = p.pradio
# dmm = p.pmradio
# # CALCULAR ANGULO ENTRE NORMAL DE P Y R, ANGULO = TH
# alpha = p.normal.anguloEntre(w)
# # CALCULAR DD = DM*COS(TH) -> 'CUANTO SE ACERCA P A R'
# dd = dm*math.cos(alpha)
# ddm = dmm*math.cos(alpha)
# # SI D < DD => RECTA ATRAVIESA PARCHE
# # RETURN 0
# if( d < ddm ):
# return 0
# # elif(d < dd):
# # rvalue = 0.5
# # FIN DEL LOOP

# # RETURN 1
# return rvalue

77 changes: 41 additions & 36 deletions patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,86 +4,91 @@
#implementado como triangulo
class Patch:

reflectance_red = 0 # reflectividad roja
reflectance_green = 0 # reflectividad verde
reflectance_blue = 0 # reflectividad azul
reflectance_red = 0.0 # reflectividad roja
reflectance_green = 0.0 # reflectividad verde
reflectance_blue = 0.0 # reflectividad azul

emmision_red = 0 # emisividad roja
emmision_green = 0 # emisividad verde
emmision_blue = 0 # emisividad azul
emmision_red = 0.0 # emisividad roja
emmision_green = 0.0 # emisividad verde
emmision_blue = 0.0 # emisividad azul

excident_red = 0 # color (luz excedente) roja
excident_green = 0 # color (luz excedente) verde
excident_blue = 0 # color (luz excedente) azul
excident_red = 0.0 # color (luz excedente) roja
excident_green = 0.0 # color (luz excedente) verde
excident_blue = 0.0 # color (luz excedente) azul

incident_red = 0 # luz incidente roja
incident_green = 0 # luz incidente verde
incident_blue = 0 # luz incidente azul
incident_red = 0.0 # luz incidente roja
incident_green = 0.0 # luz incidente verde
incident_blue = 0.0 # luz incidente azul

def __init__(self,p1,p2,p3):
#los puntos del parche deben especificarse en orden (antihorario=>normal +).
#en teoria debieran ser coplanares
def __init__(self,p1,p2,p3,p4):
self.p1 = p1
self.p2 = p2
self.p3 = p3
self.p4 = p4
self.normal = self._normal()
self.center = self._center()
self.area = self._area()
self.pradio = self._pradio()
self.pmradio = self._pmradio()

#retorna el baricentro del parche
def _center(self):
#x = (self.p1.x + self.p2.x + self.p3.x) / 3
#y = (self.p1.y + self.p2.y + self.p3.y) / 3
#z = (self.p1.z + self.p2.z + self.p3.z) / 3

#return Punto(x, y, z)
return self.p1.suma(self.p2.suma(self.p3,1),3) # == (p1 + ((p2 + p3) / 1)) / 3
return self.p1.suma(self.p3,2) # punto medio entre vertices opuestos

#no es necesario normalizar, basta la direccion
def _normal(self):
b_menos_a = self.p2.resta(self.p1, 1) # == (p2 - p1) / 1
c_menos_a = self.p3.resta(self.p1, 1) # == (p3 - p1) / 1
if(b_menos_a.modulo() == 0 or c_menos_a.modulo()==0):
print " normal es cero"
cruz = b_menos_a.cruz(c_menos_a)
mod = math.sqrt(cruz.x*cruz.x + cruz.y*cruz.y + cruz.z*cruz.z)
cruz.x = cruz.x/mod
cruz.y = cruz.y/mod
cruz.z = cruz.z/mod

return cruz
return cruz.normalizar()
# return cruz

def _area(self):
p1 = self.p1
p2 = self.p2
p3 = self.p3
p4 = self.p4

lado1 = math.sqrt(math.pow(p1.x-p2.x,2)+math.pow(p1.y-p2.y,2)+math.pow(p1.z-p2.z,2)) #p1, p2
lado2 = math.sqrt(math.pow(p3.x-p2.x,2)+math.pow(p3.y-p2.y,2)+math.pow(p3.z-p2.z,2)) #p2, p3
lado3 = math.sqrt(math.pow(p1.x-p3.x,2)+math.pow(p1.y-p3.y,2)+math.pow(p1.z-p3.z,2)) #p3, p1
s = 0.5*(lado1 + lado2 + lado3)
lado2 = math.sqrt(math.pow(p3.x-p2.x,2)+math.pow(p3.y-p2.y,2)+math.pow(p3.z-p2.z,2)) # p2, p3
# lado3 = math.sqrt(math.pow(p1.x-p3.x,2)+math.pow(p1.y-p3.y,2)+math.pow(p1.z-p3.z,2)) #p1, p3
# lado4 = math.sqrt(math.pow(p3.x-p4.x,2)+math.pow(p3.y-p4.y,2)+math.pow(p3.z-p4.z,2)) # p3, p4
# lado5 = math.sqrt(math.pow(p1.x-p4.x,2)+math.pow(p1.y-p4.y,2)+math.pow(p1.z-p4.z,2)) #p1, p4

# s1 = 0.5*(lado1 + lado2 + lado3)
# s2 = 0.5*(lado4 + lado5 + lado3)

return math.sqrt(s*(s-lado1)*(s-lado2)*(s-lado3))
# return math.sqrt(s1*(s1-lado1)*(s1-lado2)*(s1-lado3)) + math.sqrt(s2*(s2-lado4)*(s2-lado5)*(s2-lado3))
return lado1*lado2

#atajo para dibujar cada patch
def draw(self):
p1 = self.p1
p2 = self.p2
p3 = self.p3
p4 = self.p4
glVertex3f(p1.x, p1.y, p1.z)
glVertex3f(p2.x, p2.y, p2.z)
glVertex3f(p3.x, p3.y, p3.z)
glVertex3f(p4.x, p4.y, p4.z)

# retorna el radio de la circunferencia circunscrita
def _pradio(self):
d1 = self.center.resta(self.p1,1).modulo()
d2 = self.center.resta(self.p2,1).modulo()
d3 = self.center.resta(self.p3,1).modulo()
return max(d1,d2,d3)
d4 = self.center.resta(self.p4,1).modulo()
return max(d1,d2,d3,d4)

# retorna el radio de la circunferencia inscrita
def _pmradio(self):
d1 = self.p2.resta(self.p1,1).modulo()
d2 = self.p3.resta(self.p2,1).modulo()
d3 = self.p1.resta(self.p3,1).modulo()
s = ( d1 + d2 + d3)/2
return math.sqrt(((s-d1)*(s-d2)*(s-d3))/(s))
d1 = self.center.resta(self.p1,1).modulo()
d2 = self.center.resta(self.p2,1).modulo()
d3 = self.center.resta(self.p3,1).modulo()
d4 = self.center.resta(self.p4,1).modulo()
return min(d1,d2,d3,d4)


Loading

0 comments on commit 46c5b4d

Please sign in to comment.