<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pt-BR">
	<id>http://fiscomp.if.ufrgs.br/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Brunoztemp</id>
	<title>Física Computacional - Contribuições do usuário [pt-br]</title>
	<link rel="self" type="application/atom+xml" href="http://fiscomp.if.ufrgs.br/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Brunoztemp"/>
	<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php/Especial:Contribui%C3%A7%C3%B5es/Brunoztemp"/>
	<updated>2026-04-10T05:13:43Z</updated>
	<subtitle>Contribuições do usuário</subtitle>
	<generator>MediaWiki 1.39.4</generator>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=5230</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=5230"/>
		<updated>2021-05-26T03:27:49Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos buscando a criação de estruturas similares com micélios reais. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de diferentes modelos de crescimento. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|'''Figura 1''': Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|'''Figura 2''': Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' ('''figura 1''').&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na '''figura 2'''.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado para a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a um deslocamento do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|'''Figura 3''': O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na '''figura 3'''. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório que varia com a espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
&lt;br /&gt;
O código base que chama as funções é o seguinte:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
flag = True&lt;br /&gt;
                   # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&lt;br /&gt;
for i in range (0,repeticao): &lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    if not eventos[i][4]:&lt;br /&gt;
      continue&lt;br /&gt;
  except IndexError or Exception:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  c = check_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE)&lt;br /&gt;
  &lt;br /&gt;
  if (random.random() &amp;gt; 0.6857-0.2857*c and c&amp;gt;=0.3):   #faz divisão&lt;br /&gt;
    &lt;br /&gt;
    custo = 0.3&lt;br /&gt;
    &lt;br /&gt;
    c1x,c1y,c2x,c2y= divisao(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    c1x,c1y,flag_1 = check_anastomose(eventos, c1x,c1y, eventos[i][2],eventos[i][3])&lt;br /&gt;
    c2x,c2y,flag_2 = check_anastomose(eventos,c2x,c2y, eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    novo1 = np.array( [eventos[i][2], eventos[i][3], c1x, c1y, flag_1])&lt;br /&gt;
    novo2 = np.array( [eventos[i][2], eventos[i][3], c2x, c2y, flag_2] )&lt;br /&gt;
                      #xf-&amp;gt;xi          yf-&amp;gt;yi       xf   yf    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    eventos = np.append( eventos, [novo1], axis=0)&lt;br /&gt;
    eventos = np.append( eventos, [novo2], axis=0)&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
  &lt;br /&gt;
  elif (c &amp;gt;= 0.01): #faz crescimento&lt;br /&gt;
      &lt;br /&gt;
    custo = 0.01&lt;br /&gt;
    &lt;br /&gt;
    newx,newy = crecimento(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
    &lt;br /&gt;
    newx,newy,flag = check_anastomose(eventos,newx,newy,eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    novo = np.array( [eventos[i][2], eventos[i][3], newx, newy, flag] )&lt;br /&gt;
    &lt;br /&gt;
    eventos = np.append( eventos, [novo], axis=0 )&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os principais mecanismos são: ''eventos'' que armazena os segmentos de retas com ''xi yi xf yf  flag''; ''flag'' representa se ocorreu o processo de anastomose, caso ''flag'' armazene ''False'' o primeiro ''try'' faz o segmento parar de crescer; Dentro do ''for'' principal há um ''if'' e ''else'' que junto da condição ''random.random() &amp;gt; 0.6857-0.2857*c'' faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois ''random.random()'' é um valor entre [0,1].&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente '''(Figura 4)''' é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|'''Figura 4''': Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;\sin(\sqrt{(A^2+B^2)})^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado - com os mesmos números horizontal e verticalmente - e produz o mapa mostrado na '''Figura 9'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 13'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Condições Iniciais===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:CondiIni.png|250px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
As condições iniciais em formato de estrela são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] ) # xi yi xf yf  flag&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
&lt;br /&gt;
Como discutido anteriormente o mapa de nutrientes utilizado nas simulações de crescimento das hifas interfere diretamente no resultado final referente ao formato do micélio gerado. Para exemplificar essa diferença executamos 3 simulações utilizando cada um dos três estilos de mapas mostrados já citados, o Mapa Nâo Homogêneo, o Homogêneo e o Mapa por Imagem utilizando os códigos listados na seção anterior. Abaixo está representado o crescimento de real de um fungo. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:Rhizomorhic-mycelium.jpg|250px|thumb|right|'''Figura 8''': Crescimento real de um micélio &amp;lt;ref name='REYNDERS'&amp;gt;B. REYNDERS. Grow mushroom cultures from spore, 2018.(https://funguys.co.za/mushroom-cultivation-tips/growing-mushrooms/grow-mushroom-cultures-from-spore/) &amp;lt;/ref&amp;gt;]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Mapa Heterogêneo===&lt;br /&gt;
&lt;br /&gt;
O mapa heterogêneo tem como característica principal a presença de diferentes concentrações nutricionais ao longo se sua extensão ('''figura 9''') &lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri1.jpeg|250px|thumb|left|'''Figura 9''': mapa de nutrientes utilizado para obtenção da simulação 1.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice1.jpeg|250px|thumb|right|'''Figura 10''': simulação do crescimento das hifas de um fungo após 3000 iterações.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É possível perceber através dessa imagem a nítida semelhança entre a simulação realizada utilizando o mapa não homogêneo e a a fotografia real do crescimento de um fungo mostrada anteriormente ('''figura 8''').&lt;br /&gt;
&lt;br /&gt;
===Mapa Homogêneo===&lt;br /&gt;
&lt;br /&gt;
Inicialmente o mapa de nutrientes homogêneo se encontra completo por nutrientes ('''figura 10'''), conforme o fungo vai crescendo parte desses nutrientes é consumida e é representada pelas partes mais claras da '''figura 11''', enquanto o fungo completamente desenvolvido está mostrado na '''figura 12'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutrii.jpeg|250px|thumb|center|'''Figura 10''': mapa de nutrientes inicial - e homogêneo - utilizado para obtenção da simulação 2.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri2.jpeg|250px|thumb|center|'''Figura 11''': mapa de nutrientes após a obtenção da simulação 2.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice2.jpeg|250px|thumb|center|'''Figura 12''': simulação do crescimento das hifas de um fungo após 90000 iterações.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Evolução Temporal====&lt;br /&gt;
&lt;br /&gt;
Abaixo está representada a evolução temporal do crescimento de um micélio utilizando um mapa de nutrientes homogêneo como base para desenvolvimento das hifas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice3.jpeg|1000px|thumb|center|'''Figura 13''': 5 etapas da simulação usando o mapa homogêneo de crescimento das hifas de um fungo.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora a mesma evolução representada com a utilização do mapa de nutrientes gerado tendo como base uma imagem.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:angulogrande.jpeg|1000px|thumb|center|'''Figura 14''': Evolução temporal do crescimento de hifas utilizando o mapa de imagem da '''figura 6'''.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante ressaltar que para cada simulação diferente, os parâmetros utilizados, para crescimento e divisão, devem ser adaptados, na figura acima, por exemplo, foi utilizado um grande desvio padrão na distribuição normal dos ângulos e por isso a figura não se formou por completo pois as hifas se interceptaram excessivamente e isso fez com que o mapa de nutrientes não fosse completamente aproveitado.&lt;br /&gt;
&lt;br /&gt;
===Mapa por imagem===&lt;br /&gt;
&lt;br /&gt;
A possibilidade de utilizar uma imagem para realizar esse tipo de simulação é de grande importância, pois nos permite analisar um grande número de situações e formatos diversos que apresentariam grande dificuldade de serem modeladas matemáticamente como foi feita na primeira implementação. Abaixo está representada a mesma imagem da seção anterior, mas dessa vez foi diminuido o tamanho do segmento de reta do crescimento após a divisão das hifas, o que aumentou o número de divisões realizadas e consequentemente a legibilidade da frase. &lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|'''Figura 15''': simulação do crescimento do fungo utilizando o mapa de nutrientes da '''Figura 6''' (a imagem precisou ser invertida, pois os mapas advindos de imagens são invertidos).]]&lt;br /&gt;
&lt;br /&gt;
== Melhorias a serem realizadas ==&lt;br /&gt;
&lt;br /&gt;
Através do trabalho realizado foi possível simular o crescimento de fungos de uma forma muito satisfatória, mas para um estudo mais aprofundado poderiam ser feitas algumas otimizações na implementação do algorítmo para deixar a simulação mais próxima da realidade, tais como:&lt;br /&gt;
&lt;br /&gt;
* Considerar o translocação de nutrientes realizada pelas hifas do fungo até as extremidades onde há uma escassez desses insumos;&lt;br /&gt;
&lt;br /&gt;
* Levar em conta a divisão lateral e não só a dicotômica;&lt;br /&gt;
&lt;br /&gt;
* Uma melhoria no algoritmo de detecção de intersecções entre as hifas;&lt;br /&gt;
&lt;br /&gt;
* Sistema de mortalidade das hifas levando em conta seu tempo de vida;&lt;br /&gt;
&lt;br /&gt;
* Utilizar um mapa de nutrientes contínuo e não discreto;&lt;br /&gt;
&lt;br /&gt;
* Permitir o movimento do fungo para que ele conseguisse &amp;quot;desviar&amp;quot; de possíveis substâncias tóxicas presentes no ambiente;&lt;br /&gt;
&lt;br /&gt;
* Determinar um custo nutricional para manutenção do fungo.&lt;br /&gt;
&lt;br /&gt;
== Código Completo ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
import matplotlib.pyplot as plt &lt;br /&gt;
import matplotlib.animation as animation &lt;br /&gt;
import numpy as np &lt;br /&gt;
import math &lt;br /&gt;
import random&lt;br /&gt;
from array import *&lt;br /&gt;
import seaborn as sb&lt;br /&gt;
&lt;br /&gt;
global r &lt;br /&gt;
r = 1 # tamanho de passo&lt;br /&gt;
repeticao= 1000 # número de hifas que serão calculadas&lt;br /&gt;
tamanho_mapa=100 # quantas divisões(quadrados) ocorrem no mapa de nutri&lt;br /&gt;
&lt;br /&gt;
# MAPA NUTRIENTE&lt;br /&gt;
&lt;br /&gt;
COORDENADA_MAPA= np.linspace(-30,30,tamanho_mapa) &lt;br /&gt;
&lt;br /&gt;
def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) * 1/2&lt;br /&gt;
  addy1 = r * math.sin(angulo1) * 1/2&lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) * 1/2&lt;br /&gt;
  addy2= r * math.sin(angulo2) * 1/2&lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      #print(&amp;quot;Intersection!&amp;quot;)&lt;br /&gt;
      #print(&amp;quot;X1:&amp;quot;,xi,&amp;quot; Y1:&amp;quot;,yi, &amp;quot; X2:&amp;quot;,xf,&amp;quot; Y2:&amp;quot;,yf)&lt;br /&gt;
      #print(&amp;quot;X3:&amp;quot;,evento[0],&amp;quot; Y3:&amp;quot;,evento[1],&amp;quot; X4:&amp;quot;,evento[2],&amp;quot; Y4:&amp;quot;,evento[3])&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
yCOORDENADA_MAPA,xCOORDENADA_MAPA = COORDENADA_MAPA,COORDENADA_MAPA&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&lt;br /&gt;
# MAPA_NUTRIENTE = mapa_unitario_nutri(COORDENADA_MAPA) &lt;br /&gt;
MAPA_NUTRIENTE = mapa_nutri_Nhomogenea(COORDENADA_MAPA)&lt;br /&gt;
print(MAPA_NUTRIENTE)&lt;br /&gt;
# CONDIÇÕES INICIAIS&lt;br /&gt;
flag = True&lt;br /&gt;
                   # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&lt;br /&gt;
for i in range (0,repeticao): &lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    if not eventos[i][4]:&lt;br /&gt;
      continue&lt;br /&gt;
  except IndexError or Exception:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  c = check_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE)&lt;br /&gt;
  &lt;br /&gt;
  if (random.random() &amp;gt; 0.6857-0.2857*c and c&amp;gt;=0.3):   #faz divisão&lt;br /&gt;
    &lt;br /&gt;
    custo = 0.3&lt;br /&gt;
    &lt;br /&gt;
    c1x,c1y,c2x,c2y= divisao(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    c1x,c1y,flag_1 = check_anastomose(eventos, c1x,c1y, eventos[i][2],eventos[i][3])&lt;br /&gt;
    c2x,c2y,flag_2 = check_anastomose(eventos,c2x,c2y, eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    novo1 = np.array( [eventos[i][2], eventos[i][3], c1x, c1y, flag_1])&lt;br /&gt;
    novo2 = np.array( [eventos[i][2], eventos[i][3], c2x, c2y, flag_2] )&lt;br /&gt;
                      #xf-&amp;gt;xi          yf-&amp;gt;yi       xf   yf    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    eventos = np.append( eventos, [novo1], axis=0)&lt;br /&gt;
    eventos = np.append( eventos, [novo2], axis=0)&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
  &lt;br /&gt;
  elif (c &amp;gt;= 0.01): #faz crescimento&lt;br /&gt;
      &lt;br /&gt;
    custo = 0.01&lt;br /&gt;
    &lt;br /&gt;
    newx,newy = crecimento(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
    &lt;br /&gt;
    newx,newy,flag = check_anastomose(eventos,newx,newy,eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    novo = np.array( [eventos[i][2], eventos[i][3], newx, newy, flag] )&lt;br /&gt;
    &lt;br /&gt;
    eventos = np.append( eventos, [novo], axis=0 )&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
plt.figure(figsize=(10,10))&lt;br /&gt;
plt.axes().set_facecolor(&amp;quot;black&amp;quot;)&lt;br /&gt;
plt.title('Fungo com repeticoes: {}'.format(repeticao))&lt;br /&gt;
&lt;br /&gt;
for j in range (0,repeticao):&lt;br /&gt;
    vet=[[eventos[j][0],eventos[j][2]],[eventos[j][1],eventos[j][3]]]&lt;br /&gt;
    &lt;br /&gt;
    plt.plot(vet[0],vet[1],color='green')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Plot ao longo do tempo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# plot ao longo do tempo&lt;br /&gt;
&lt;br /&gt;
numero_plot=5&lt;br /&gt;
size=3&lt;br /&gt;
fig, axs = plt.subplots(1, numero_plot, figsize=(numero_plot*size*1.5,1*size))&lt;br /&gt;
&lt;br /&gt;
repeticao=len(eventos)&lt;br /&gt;
for j in range (0,repeticao):&lt;br /&gt;
    vet=[[eventos[j][0],eventos[j][2]],[eventos[j][1],eventos[j][3]]]&lt;br /&gt;
    axs[4].plot(vet[0],vet[1],color='green')&lt;br /&gt;
    if (j&amp;lt;repeticao/10):&lt;br /&gt;
      axs[0].plot(vet[0],vet[1],color='green')&lt;br /&gt;
    if (j&amp;lt;repeticao/4):&lt;br /&gt;
      axs[1].plot(vet[0],vet[1],color='green')&lt;br /&gt;
    if (j&amp;lt;repeticao/2):&lt;br /&gt;
      axs[2].plot(vet[0],vet[1],color='green')&lt;br /&gt;
    if (j&amp;lt;3*repeticao/4):&lt;br /&gt;
      axs[3].plot(vet[0],vet[1],color='green')&lt;br /&gt;
&lt;br /&gt;
axs[0].set_title(&amp;quot;{}&amp;quot;.format(int(repeticao/10)))&lt;br /&gt;
axs[1].set_title(&amp;quot;{}&amp;quot;.format(int(repeticao/4)))&lt;br /&gt;
axs[2].set_title(&amp;quot;{}&amp;quot;.format(int(repeticao/2)))&lt;br /&gt;
axs[3].set_title(&amp;quot;{}&amp;quot;.format(int(3*repeticao/4)))&lt;br /&gt;
axs[4].set_title(&amp;quot;{}&amp;quot;.format(int(repeticao)))      &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
axis=80&lt;br /&gt;
&lt;br /&gt;
for b in range (0,numero_plot):&lt;br /&gt;
  axs[b].set_xlim(-45,70) &lt;br /&gt;
  axs[b].set_ylim(-45,80) &lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
fig.suptitle('Fungo com repeticoes: {}\n'.format(repeticao))&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=5205</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=5205"/>
		<updated>2021-05-25T23:57:13Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos buscando a criação de estruturas similares com micélios reais. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de diferentes modelos de crescimento. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|'''Figura 1''': Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|'''Figura 2''': Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' ('''figura 1''').&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na '''figura 2'''.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado para a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a um deslocamento do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|'''Figura 3''': O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na '''figura 3'''. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório que varia com a espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
&lt;br /&gt;
O código base que chama as funções é o seguinte:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
flag = True&lt;br /&gt;
                   # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&lt;br /&gt;
for i in range (0,repeticao): &lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    if not eventos[i][4]:&lt;br /&gt;
      continue&lt;br /&gt;
  except IndexError or Exception:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  c = check_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE)&lt;br /&gt;
  &lt;br /&gt;
  if (random.random() &amp;gt; 0.6857-0.2857*c and c&amp;gt;=0.3):   #faz divisão&lt;br /&gt;
    &lt;br /&gt;
    custo = 0.3&lt;br /&gt;
    &lt;br /&gt;
    c1x,c1y,c2x,c2y= divisao(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    c1x,c1y,flag_1 = check_anastomose(eventos, c1x,c1y, eventos[i][2],eventos[i][3])&lt;br /&gt;
    c2x,c2y,flag_2 = check_anastomose(eventos,c2x,c2y, eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    novo1 = np.array( [eventos[i][2], eventos[i][3], c1x, c1y, flag_1])&lt;br /&gt;
    novo2 = np.array( [eventos[i][2], eventos[i][3], c2x, c2y, flag_2] )&lt;br /&gt;
                      #xf-&amp;gt;xi          yf-&amp;gt;yi       xf   yf    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    eventos = np.append( eventos, [novo1], axis=0)&lt;br /&gt;
    eventos = np.append( eventos, [novo2], axis=0)&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
  &lt;br /&gt;
  elif (c &amp;gt;= 0.01): #faz crescimento&lt;br /&gt;
      &lt;br /&gt;
    custo = 0.01&lt;br /&gt;
    &lt;br /&gt;
    newx,newy = crecimento(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
    &lt;br /&gt;
    newx,newy,flag = check_anastomose(eventos,newx,newy,eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    novo = np.array( [eventos[i][2], eventos[i][3], newx, newy, flag] )&lt;br /&gt;
    &lt;br /&gt;
    eventos = np.append( eventos, [novo], axis=0 )&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os principais mecanismos são: ''eventos'' que armazena os segmentos de retas com ''xi yi xf yf  flag''; ''flag'' representa se ocorreu o processo de anastomose, caso ''flag'' armazene ''False'' o primeiro ''try'' faz o segmento parar de crescer; Dentro do ''for'' principal há um ''if'' e ''else'' que junto da condição ''random.random() &amp;gt; 0.6857-0.2857*c'' faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois ''random.random()'' é um valor entre [0,1].&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente '''(Figura 4)''' é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|'''Figura 4''': Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;\sin(\sqrt{(A^2+B^2)})^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado - com os mesmos números horizontal e verticalmente - e produz o mapa mostrado na '''Figura 9'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 13'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Condições Iniciais===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:CondiIni.png|250px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
As condições iniciais em formato de estrela são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] ) # xi yi xf yf  flag&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
&lt;br /&gt;
Como discutido anteriormente o mapa de nutrientes utilizado nas simulações de crescimento das hifas interfere diretamente no resultado final referente ao formato do micélio gerado. Para exemplificar essa diferença executamos 3 simulações utilizando cada um dos três estilos de mapas mostrados já citados, o Mapa Nâo Homogêneo, o Homogêneo e o Mapa por Imagem utilizando os códigos listados na seção anterior. Abaixo está representado o crescimento de real de um fungo. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:Rhizomorhic-mycelium.jpg|250px|thumb|right|'''Figura 8''': Crescimento real de um micélio ]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ref name='REYNDERS'&amp;gt;B. REYNDERS. Grow mushroom cultures from spore, 2018.(https://funguys.co.za/mushroom-cultivation-tips/growing-mushrooms/grow-mushroom-cultures-from-spore/) &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Mapa Heterogêneo===&lt;br /&gt;
&lt;br /&gt;
O mapa heterogêneo tem como característica principal a presença de diferentes concentrações nutricionais ao longo se sua extensão ('''figura 9''') &lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri1.jpeg|250px|thumb|left|'''Figura 9''': mapa de nutrientes utilizado para obtenção da simulação 1.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice1.jpeg|250px|thumb|right|'''Figura 10''': simulação do crescimento das hifas de um fungo após 3000 iterações.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É possível perceber através dessa imagem a nítida semelhança entre a simulação realizada utilizando o mapa não homogêneo e a a fotografia real do crescimento de um fungo mostrada anteriormente ('''figura 8''').&lt;br /&gt;
&lt;br /&gt;
===Mapa Homogêneo===&lt;br /&gt;
&lt;br /&gt;
Inicialmente o mapa de nutrientes homogêneo se encontra completo por nutrientes ('''figura 10'''), conforme o fungo vai crescendo parte desses nutrientes é consumida e é representada pelas partes mais claras da '''figura 11''', enquanto o fungo completamente desenvolvido está mostrado na '''figura 12'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutrii.jpeg|250px|thumb|center|'''Figura 10''': mapa de nutrientes inicial - e homogêneo - utilizado para obtenção da simulação 2.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri2.jpeg|250px|thumb|center|'''Figura 11''': mapa de nutrientes após a obtenção da simulação 2.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice2.jpeg|250px|thumb|center|'''Figura 12''': simulação do crescimento das hifas de um fungo após 90000 iterações.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Evolução Temporal====&lt;br /&gt;
&lt;br /&gt;
Abaixo está representada a evolução temporal do crescimento de um micélio utilizando um mapa de nutrientes homogêneo como base para desenvolvimento das hifas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice3.jpeg|1000px|thumb|center|'''Figura 13''': 5 etapas da simulação usando o mapa homogêneo de crescimento das hifas de um fungo.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora a mesma evolução representada com a utilização do mapa de nutrientes gerado tendo como base uma imagem.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:angulogrande.jpeg|1000px|thumb|center|'''Figura 14''': Evolução temporal do crescimento de hifas utilizando o mapa de imagem da '''figura 6'''.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante ressaltar que para cada simulação diferente, os parâmetros utilizados, para crescimento e divisão, devem ser adaptados, na figura acima, por exemplo, foi utilizado um grande desvio padrão na distribuição normal dos ângulos e por isso a figura não se formou por completo pois as hifas se interceptaram excessivamente e isso fez com que o mapa de nutrientes não fosse completamente aproveitado.&lt;br /&gt;
&lt;br /&gt;
===Mapa por imagem===&lt;br /&gt;
&lt;br /&gt;
A possibilidade de utilizar uma imagem para realizar esse tipo de simulação é de grande importância, pois nos permite analisar um grande número de situações e formatos diversos que apresentariam grande dificuldade de serem modeladas matemáticamente como foi feita na primeira implementação. Abaixo está representada a mesma imagem da seção anterior, mas dessa vez foi diminuido o tamanho do segmento de reta do crescimento após a divisão das hifas, o que aumentou o número de divisões realizadas e consequentemente a legibilidade da frase. &lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|'''Figura 15''': simulação do crescimento do fungo utilizando o mapa de nutrientes da '''Figura 6''' (a imagem precisou ser invertida, pois os mapas advindos de imagens são invertidos).]]&lt;br /&gt;
&lt;br /&gt;
== Melhorias a serem realizadas ==&lt;br /&gt;
&lt;br /&gt;
Através do trabalho realizado foi possível simular o crescimento de fungos de uma forma muito satisfatória, mas para um estudo mais aprofundado poderiam ser feitas algumas otimizações na implementação do algorítmo para deixar a simulação mais próxima da realidade, tais como:&lt;br /&gt;
&lt;br /&gt;
* Considerar o translocação de nutrientes realizada pelas hifas do fungo até as extremidades onde há uma escassez desses insumos;&lt;br /&gt;
&lt;br /&gt;
* Levar em conta a divisão lateral e não só a dicotômica;&lt;br /&gt;
&lt;br /&gt;
* Uma melhoria no algoritmo de detecção de intersecções entre as hifas;&lt;br /&gt;
&lt;br /&gt;
* Sistema de mortalidade das hifas levando em conta seu tempo de vida;&lt;br /&gt;
&lt;br /&gt;
* Utilizar um mapa de nutrientes contínuo e não discreto;&lt;br /&gt;
&lt;br /&gt;
* Permitir o movimento do fungo para que ele conseguisse &amp;quot;desviar&amp;quot; de possíveis substâncias tóxicas presentes no ambiente;&lt;br /&gt;
&lt;br /&gt;
* Determinar um custo nutricional para manutenção do fungo.&lt;br /&gt;
&lt;br /&gt;
== Código Completo ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
import matplotlib.pyplot as plt &lt;br /&gt;
import matplotlib.animation as animation &lt;br /&gt;
import numpy as np &lt;br /&gt;
import math &lt;br /&gt;
import random&lt;br /&gt;
from array import *&lt;br /&gt;
import seaborn as sb&lt;br /&gt;
&lt;br /&gt;
global r &lt;br /&gt;
r = 1 # tamanho de passo&lt;br /&gt;
repeticao= 1000 # número de hifas que serão calculadas&lt;br /&gt;
tamanho_mapa=100 # quantas divisões(quadrados) ocorrem no mapa de nutri&lt;br /&gt;
&lt;br /&gt;
# MAPA NUTRIENTE&lt;br /&gt;
&lt;br /&gt;
COORDENADA_MAPA= np.linspace(-30,30,tamanho_mapa) &lt;br /&gt;
&lt;br /&gt;
def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) * 1/2&lt;br /&gt;
  addy1 = r * math.sin(angulo1) * 1/2&lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) * 1/2&lt;br /&gt;
  addy2= r * math.sin(angulo2) * 1/2&lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      #print(&amp;quot;Intersection!&amp;quot;)&lt;br /&gt;
      #print(&amp;quot;X1:&amp;quot;,xi,&amp;quot; Y1:&amp;quot;,yi, &amp;quot; X2:&amp;quot;,xf,&amp;quot; Y2:&amp;quot;,yf)&lt;br /&gt;
      #print(&amp;quot;X3:&amp;quot;,evento[0],&amp;quot; Y3:&amp;quot;,evento[1],&amp;quot; X4:&amp;quot;,evento[2],&amp;quot; Y4:&amp;quot;,evento[3])&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
yCOORDENADA_MAPA,xCOORDENADA_MAPA = COORDENADA_MAPA,COORDENADA_MAPA&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&lt;br /&gt;
# MAPA_NUTRIENTE = mapa_unitario_nutri(COORDENADA_MAPA) &lt;br /&gt;
MAPA_NUTRIENTE = mapa_nutri_Nhomogenea(COORDENADA_MAPA)&lt;br /&gt;
print(MAPA_NUTRIENTE)&lt;br /&gt;
# CONDIÇÕES INICIAIS&lt;br /&gt;
flag = True&lt;br /&gt;
                   # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&lt;br /&gt;
for i in range (0,repeticao): &lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    if not eventos[i][4]:&lt;br /&gt;
      continue&lt;br /&gt;
  except IndexError or Exception:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  c = check_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE)&lt;br /&gt;
  &lt;br /&gt;
  if (random.random() &amp;gt; 0.6857-0.2857*c and c&amp;gt;=0.3):   #faz divisão&lt;br /&gt;
    &lt;br /&gt;
    custo = 0.3&lt;br /&gt;
    &lt;br /&gt;
    c1x,c1y,c2x,c2y= divisao(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    c1x,c1y,flag_1 = check_anastomose(eventos, c1x,c1y, eventos[i][2],eventos[i][3])&lt;br /&gt;
    c2x,c2y,flag_2 = check_anastomose(eventos,c2x,c2y, eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    novo1 = np.array( [eventos[i][2], eventos[i][3], c1x, c1y, flag_1])&lt;br /&gt;
    novo2 = np.array( [eventos[i][2], eventos[i][3], c2x, c2y, flag_2] )&lt;br /&gt;
                      #xf-&amp;gt;xi          yf-&amp;gt;yi       xf   yf    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    eventos = np.append( eventos, [novo1], axis=0)&lt;br /&gt;
    eventos = np.append( eventos, [novo2], axis=0)&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
  &lt;br /&gt;
  elif (c &amp;gt;= 0.01): #faz crescimento&lt;br /&gt;
      &lt;br /&gt;
    custo = 0.01&lt;br /&gt;
    &lt;br /&gt;
    newx,newy = crecimento(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
    &lt;br /&gt;
    newx,newy,flag = check_anastomose(eventos,newx,newy,eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    novo = np.array( [eventos[i][2], eventos[i][3], newx, newy, flag] )&lt;br /&gt;
    &lt;br /&gt;
    eventos = np.append( eventos, [novo], axis=0 )&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
plt.figure(figsize=(10,10))&lt;br /&gt;
plt.axes().set_facecolor(&amp;quot;black&amp;quot;)&lt;br /&gt;
plt.title('Fungo com repeticoes: {}'.format(repeticao))&lt;br /&gt;
&lt;br /&gt;
for j in range (0,repeticao):&lt;br /&gt;
    vet=[[eventos[j][0],eventos[j][2]],[eventos[j][1],eventos[j][3]]]&lt;br /&gt;
    &lt;br /&gt;
    plt.plot(vet[0],vet[1],color='green')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Plot ao longo do tempo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# plot ao longo do tempo&lt;br /&gt;
&lt;br /&gt;
numero_plot=5&lt;br /&gt;
size=3&lt;br /&gt;
fig, axs = plt.subplots(1, numero_plot, figsize=(numero_plot*size*1.5,1*size))&lt;br /&gt;
&lt;br /&gt;
repeticao=len(eventos)&lt;br /&gt;
for j in range (0,repeticao):&lt;br /&gt;
    vet=[[eventos[j][0],eventos[j][2]],[eventos[j][1],eventos[j][3]]]&lt;br /&gt;
    axs[4].plot(vet[0],vet[1],color='green')&lt;br /&gt;
    if (j&amp;lt;repeticao/10):&lt;br /&gt;
      axs[0].plot(vet[0],vet[1],color='green')&lt;br /&gt;
    if (j&amp;lt;repeticao/4):&lt;br /&gt;
      axs[1].plot(vet[0],vet[1],color='green')&lt;br /&gt;
    if (j&amp;lt;repeticao/2):&lt;br /&gt;
      axs[2].plot(vet[0],vet[1],color='green')&lt;br /&gt;
    if (j&amp;lt;3*repeticao/4):&lt;br /&gt;
      axs[3].plot(vet[0],vet[1],color='green')&lt;br /&gt;
&lt;br /&gt;
axs[0].set_title(&amp;quot;{}&amp;quot;.format(int(repeticao/10)))&lt;br /&gt;
axs[1].set_title(&amp;quot;{}&amp;quot;.format(int(repeticao/4)))&lt;br /&gt;
axs[2].set_title(&amp;quot;{}&amp;quot;.format(int(repeticao/2)))&lt;br /&gt;
axs[3].set_title(&amp;quot;{}&amp;quot;.format(int(3*repeticao/4)))&lt;br /&gt;
axs[4].set_title(&amp;quot;{}&amp;quot;.format(int(repeticao)))      &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
axis=80&lt;br /&gt;
&lt;br /&gt;
for b in range (0,numero_plot):&lt;br /&gt;
  axs[b].set_xlim(-45,70) &lt;br /&gt;
  axs[b].set_ylim(-45,80) &lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
fig.suptitle('Fungo com repeticoes: {}\n'.format(repeticao))&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=5076</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=5076"/>
		<updated>2021-05-24T22:50:27Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Código Completo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de diferentes modelos de crescimento. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|'''Figura 1''': Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|'''Figura 2''': Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' ('''figura 1''').&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na '''figura 2'''.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado para a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a um deslocamento do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|'''Figura 3''': O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na '''figura 3'''. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório que varia com a espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
&lt;br /&gt;
O código base que chama as funções é o seguinte:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
flag = True&lt;br /&gt;
                   # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&lt;br /&gt;
for i in range (0,repeticao): &lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    if not eventos[i][4]:&lt;br /&gt;
      continue&lt;br /&gt;
  except IndexError or Exception:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  c = check_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE)&lt;br /&gt;
  &lt;br /&gt;
  if (random.random() &amp;gt; 0.6857-0.2857*c and c&amp;gt;=0.3):   #faz divisão&lt;br /&gt;
    &lt;br /&gt;
    custo = 0.3&lt;br /&gt;
    &lt;br /&gt;
    c1x,c1y,c2x,c2y= divisao(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    c1x,c1y,flag_1 = check_anastomose(eventos, c1x,c1y, eventos[i][2],eventos[i][3])&lt;br /&gt;
    c2x,c2y,flag_2 = check_anastomose(eventos,c2x,c2y, eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    novo1 = np.array( [eventos[i][2], eventos[i][3], c1x, c1y, flag_1])&lt;br /&gt;
    novo2 = np.array( [eventos[i][2], eventos[i][3], c2x, c2y, flag_2] )&lt;br /&gt;
                      #xf-&amp;gt;xi          yf-&amp;gt;yi       xf   yf    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    eventos = np.append( eventos, [novo1], axis=0)&lt;br /&gt;
    eventos = np.append( eventos, [novo2], axis=0)&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
  &lt;br /&gt;
  elif (c &amp;gt;= 0.01): #faz crescimento&lt;br /&gt;
      &lt;br /&gt;
    custo = 0.01&lt;br /&gt;
    &lt;br /&gt;
    newx,newy = crecimento(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
    &lt;br /&gt;
    newx,newy,flag = check_anastomose(eventos,newx,newy,eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    novo = np.array( [eventos[i][2], eventos[i][3], newx, newy, flag] )&lt;br /&gt;
    &lt;br /&gt;
    eventos = np.append( eventos, [novo], axis=0 )&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os principais mecanismos são: ''eventos'' que armazena os segmentos de retas com ''xi yi xf yf  flag''; ''flag'' representa se ocorreu o processo de anastomose, caso ''flag'' armazene ''False'' o primeiro ''try'' faz o segmento parar de crescer; Dentro do ''for'' principal há um ''if'' e ''else'' que junto da condição ''random.random() &amp;gt; 0.6857-0.2857*c'' faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois ''random.random()'' é um valor entre [0,1].&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente '''(Figura 4)''' é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|'''Figura 4''': Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;\sin(\sqrt{(A^2+B^2)})^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado - com os mesmos números horizontal e verticalmente - e produz o mapa mostrado na '''Figura 9'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 13'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Condições Iniciais===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:CondiIni.png|250px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
As condições iniciais em formato de estrela são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] ) # xi yi xf yf  flag&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
&lt;br /&gt;
Como discutido anteriormente o mapa de nutrientes utilizado nas simulações de crescimento das hifas interfere diretamente no resultado final referente ao formato do micélio gerado. Para exemplificar essa diferença executamos 3 simulações utilizando cada um dos três estilos de mapas mostrados anteriormente, o Mapa Nâo Homogêneo, o Homogêneo e o Mapa por Imagem utilizando os códigos listados anteriormente. Abaixo está representado o crescimento de real de um fungo. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:Rhizomorhic-mycelium.jpg|250px|thumb|right|'''Figura 8''': Crescimento real de um micélio ]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ref name='REYNDERS'&amp;gt;B. REYNDERS. Grow mushroom cultures from spore, 2018.(https://funguys.co.za/mushroom-cultivation-tips/growing-mushrooms/grow-mushroom-cultures-from-spore/) &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Mapa Heterogêneo===&lt;br /&gt;
&lt;br /&gt;
O mapa heterogêneo tem como característica principal a presença de diferentes concentrações nutricionais ao longo se sua extensão ('''figura 9''') &lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri1.jpeg|250px|thumb|left|'''Figura 9''': mapa de nutrientes utilizado para obtenção da simulação 1.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice1.jpeg|250px|thumb|right|'''Figura 10''': simulação do crescimento das hifas de um fungo após 3000 iterações.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É possível perceber através dessa imagem a nítida semelhança entre a simulação realizada utilizando o mapa não homogêneo e a a fotografia real do crescimento de um fungo mostrada anteriormente ('''figura 8''').&lt;br /&gt;
&lt;br /&gt;
===Mapa Homogêneo===&lt;br /&gt;
&lt;br /&gt;
Inicialmente o mapa de nutrientes homogênio se encontra completo por nutrientes ('''figura 10'''), conforme o fungo vai crescendo parte desses nutrientes é consumida e é representada pelas partes mais claras da '''figura 11''', enquanto o fungo completamente desenvolvido está mostrado na '''figura 12'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutrii.jpeg|250px|thumb|center|'''Figura 10''': mapa de nutrientes inicial - e homogêneo - utilizado para obtenção da simulação 2.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri2.jpeg|250px|thumb|center|'''Figura 11''': mapa de nutrientes após a obtenção da simulação 2.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice2.jpeg|250px|thumb|center|'''Figura 12''': simulação do crescimento das hifas de um fungo após 90000 iterações.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Evolução Temporal====&lt;br /&gt;
&lt;br /&gt;
Abaixo está representada a evolução temporal do crescimento de um micélio utilizando um mapa de nutrientes homogêneo como base para desenvolvimento das hifas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice3.jpeg|1000px|thumb|center|'''Figura 13''': 5 etapas da simulação usando o mapa homogêneo de crescimento das hifas de um fungo.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora a mesma evolução representada com a utilização do mapa de nutrientes gerado tendo como base uma imagem.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:angulogrande.jpeg|1000px|thumb|center|'''Figura 14''': Evolução temporal do crescimento de hifas utilizando o mapa de imagem da '''figura 6'''.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante ressaltar que para cada simulação diferente, os parâmetros utilizados, para crescimento e divisão, devem ser adaptados, na figura acima, por exemplo, foi utilizado um grande desvio padrão na distribuição normal dos ângulos e por isso a figura não se formou por completo pois as hifas se interceptaram excessivamente e isso fez com que o mapa de nutrientes não fosse completamente aproveitado.&lt;br /&gt;
&lt;br /&gt;
===Mapa por imagem===&lt;br /&gt;
&lt;br /&gt;
A possibilidade de utilizar uma imagem para realizar esse tipo de simulação é de grande importância, pois nos permite analisar um grande número de situações e formatos diversos que apresentariam grande dificuldade de serem modeladas matemáticamente como foi feita na primeira implementação. Abaixo está representada a mesma imagem da seção anterior, mas dessa vez foi diminuido o tamanho do segmento de reta da divisão das hifas, o que aumentou o número de divisões realizadas e consequentemente a legibilidade da frase. &lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|'''Figura 15''': simulação do crescimento do fungo utilizando o mapa de nutrientes da '''Figura 6''' (a imagem precisou ser invertida, pois os mapas advindos de imagens são invertidos).]]&lt;br /&gt;
&lt;br /&gt;
== Melhorias a serem realizadas ==&lt;br /&gt;
&lt;br /&gt;
Através do trabalho realizado foi possível simular o crescimente de fungos de uma forma muito satisfatória, mas para um estudo mais aprofundado poderiam ser feitas algumas otimizações na implementação do algorítmo para deixar a simulação mais próxima da realidade, tais como:&lt;br /&gt;
&lt;br /&gt;
* Considerar o translocação de nutrientes realizada pelas hifas do fungo até as extremidades onde há uma escassez desses insumos;&lt;br /&gt;
&lt;br /&gt;
* Levar em conta a divisão lateral e não só a dicotômica;&lt;br /&gt;
&lt;br /&gt;
* Uma melhoria no algoritmo de deteção de intersecções entre as hifas;&lt;br /&gt;
&lt;br /&gt;
* Sistema de mortalidade das hifas levando em conta seu tempo de vida;&lt;br /&gt;
&lt;br /&gt;
* Utilizar um mapa de nutrientes contínuo e não discreto;&lt;br /&gt;
&lt;br /&gt;
* Permitir o movimento do fungo para que ele conseguisse &amp;quot;desviar&amp;quot; de possíveis substâncias tóxicas presentes no ambiente;&lt;br /&gt;
&lt;br /&gt;
* Determinar um custo nutricional para manutenção do fungo.&lt;br /&gt;
&lt;br /&gt;
== Código Completo ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
import matplotlib.pyplot as plt &lt;br /&gt;
import matplotlib.animation as animation &lt;br /&gt;
import numpy as np &lt;br /&gt;
import math &lt;br /&gt;
import random&lt;br /&gt;
from array import *&lt;br /&gt;
import seaborn as sb&lt;br /&gt;
&lt;br /&gt;
global r &lt;br /&gt;
r = 1 # tamanho de passo&lt;br /&gt;
repeticao= 1000 # número de hifas que serão calculadas&lt;br /&gt;
tamanho_mapa=100 # quantas divisões(quadrados) ocorrem no mapa de nutri&lt;br /&gt;
&lt;br /&gt;
# MAPA NUTRIENTE&lt;br /&gt;
&lt;br /&gt;
COORDENADA_MAPA= np.linspace(-30,30,tamanho_mapa) &lt;br /&gt;
&lt;br /&gt;
def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) * 1/2&lt;br /&gt;
  addy1 = r * math.sin(angulo1) * 1/2&lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) * 1/2&lt;br /&gt;
  addy2= r * math.sin(angulo2) * 1/2&lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      #print(&amp;quot;Intersection!&amp;quot;)&lt;br /&gt;
      #print(&amp;quot;X1:&amp;quot;,xi,&amp;quot; Y1:&amp;quot;,yi, &amp;quot; X2:&amp;quot;,xf,&amp;quot; Y2:&amp;quot;,yf)&lt;br /&gt;
      #print(&amp;quot;X3:&amp;quot;,evento[0],&amp;quot; Y3:&amp;quot;,evento[1],&amp;quot; X4:&amp;quot;,evento[2],&amp;quot; Y4:&amp;quot;,evento[3])&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
yCOORDENADA_MAPA,xCOORDENADA_MAPA = COORDENADA_MAPA,COORDENADA_MAPA&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&lt;br /&gt;
# MAPA_NUTRIENTE = mapa_unitario_nutri(COORDENADA_MAPA) &lt;br /&gt;
MAPA_NUTRIENTE = mapa_nutri_Nhomogenea(COORDENADA_MAPA)&lt;br /&gt;
print(MAPA_NUTRIENTE)&lt;br /&gt;
# CONDIÇÕES INICIAIS&lt;br /&gt;
flag = True&lt;br /&gt;
                   # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&lt;br /&gt;
for i in range (0,repeticao): &lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    if not eventos[i][4]:&lt;br /&gt;
      continue&lt;br /&gt;
  except IndexError or Exception:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  c = check_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE)&lt;br /&gt;
  &lt;br /&gt;
  if (random.random() &amp;gt; 0.6857-0.2857*c and c&amp;gt;=0.3):   #faz divisão&lt;br /&gt;
    &lt;br /&gt;
    custo = 0.3&lt;br /&gt;
    &lt;br /&gt;
    c1x,c1y,c2x,c2y= divisao(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    c1x,c1y,flag_1 = check_anastomose(eventos, c1x,c1y, eventos[i][2],eventos[i][3])&lt;br /&gt;
    c2x,c2y,flag_2 = check_anastomose(eventos,c2x,c2y, eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    novo1 = np.array( [eventos[i][2], eventos[i][3], c1x, c1y, flag_1])&lt;br /&gt;
    novo2 = np.array( [eventos[i][2], eventos[i][3], c2x, c2y, flag_2] )&lt;br /&gt;
                      #xf-&amp;gt;xi          yf-&amp;gt;yi       xf   yf    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    eventos = np.append( eventos, [novo1], axis=0)&lt;br /&gt;
    eventos = np.append( eventos, [novo2], axis=0)&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
  &lt;br /&gt;
  elif (c &amp;gt;= 0.01): #faz crescimento&lt;br /&gt;
      &lt;br /&gt;
    custo = 0.01&lt;br /&gt;
    &lt;br /&gt;
    newx,newy = crecimento(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
    &lt;br /&gt;
    newx,newy,flag = check_anastomose(eventos,newx,newy,eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    novo = np.array( [eventos[i][2], eventos[i][3], newx, newy, flag] )&lt;br /&gt;
    &lt;br /&gt;
    eventos = np.append( eventos, [novo], axis=0 )&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
plt.figure(figsize=(10,10))&lt;br /&gt;
plt.axes().set_facecolor(&amp;quot;black&amp;quot;)&lt;br /&gt;
plt.title('Fungo com repeticoes: {}'.format(repeticao))&lt;br /&gt;
&lt;br /&gt;
for j in range (0,repeticao):&lt;br /&gt;
    vet=[[eventos[j][0],eventos[j][2]],[eventos[j][1],eventos[j][3]]]&lt;br /&gt;
    &lt;br /&gt;
    plt.plot(vet[0],vet[1],color='green')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Plot ao longo do tempo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# plot ao longo do tempo&lt;br /&gt;
&lt;br /&gt;
numero_plot=5&lt;br /&gt;
size=3&lt;br /&gt;
fig, axs = plt.subplots(1, numero_plot, figsize=(numero_plot*size*1.5,1*size))&lt;br /&gt;
&lt;br /&gt;
repeticao=len(eventos)&lt;br /&gt;
for j in range (0,repeticao):&lt;br /&gt;
    vet=[[eventos[j][0],eventos[j][2]],[eventos[j][1],eventos[j][3]]]&lt;br /&gt;
    axs[4].plot(vet[0],vet[1],color='green')&lt;br /&gt;
    if (j&amp;lt;repeticao/10):&lt;br /&gt;
      axs[0].plot(vet[0],vet[1],color='green')&lt;br /&gt;
    if (j&amp;lt;repeticao/4):&lt;br /&gt;
      axs[1].plot(vet[0],vet[1],color='green')&lt;br /&gt;
    if (j&amp;lt;repeticao/2):&lt;br /&gt;
      axs[2].plot(vet[0],vet[1],color='green')&lt;br /&gt;
    if (j&amp;lt;3*repeticao/4):&lt;br /&gt;
      axs[3].plot(vet[0],vet[1],color='green')&lt;br /&gt;
&lt;br /&gt;
axs[0].set_title(&amp;quot;{}&amp;quot;.format(int(repeticao/10)))&lt;br /&gt;
axs[1].set_title(&amp;quot;{}&amp;quot;.format(int(repeticao/4)))&lt;br /&gt;
axs[2].set_title(&amp;quot;{}&amp;quot;.format(int(repeticao/2)))&lt;br /&gt;
axs[3].set_title(&amp;quot;{}&amp;quot;.format(int(3*repeticao/4)))&lt;br /&gt;
axs[4].set_title(&amp;quot;{}&amp;quot;.format(int(repeticao)))      &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
axis=80&lt;br /&gt;
&lt;br /&gt;
for b in range (0,numero_plot):&lt;br /&gt;
  axs[b].set_xlim(-45,70) &lt;br /&gt;
  axs[b].set_ylim(-45,80) &lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
fig.suptitle('Fungo com repeticoes: {}\n'.format(repeticao))&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=5044</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=5044"/>
		<updated>2021-05-24T22:33:45Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Condições Iniciais */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de diferentes modelos de crescimento. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado para a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a um deslocamento do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório que varia com a espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
&lt;br /&gt;
O código base que chama as funções é o seguinte:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
flag = True&lt;br /&gt;
                   # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&lt;br /&gt;
for i in range (0,repeticao): &lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    if not eventos[i][4]:&lt;br /&gt;
      continue&lt;br /&gt;
  except IndexError or Exception:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  c = check_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE)&lt;br /&gt;
  &lt;br /&gt;
  if (random.random() &amp;gt; 0.6857-0.2857*c and c&amp;gt;=0.3):   #faz divisão&lt;br /&gt;
    &lt;br /&gt;
    custo = 0.3&lt;br /&gt;
    &lt;br /&gt;
    c1x,c1y,c2x,c2y= divisao(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    c1x,c1y,flag_1 = check_anastomose(eventos, c1x,c1y, eventos[i][2],eventos[i][3])&lt;br /&gt;
    c2x,c2y,flag_2 = check_anastomose(eventos,c2x,c2y, eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    novo1 = np.array( [eventos[i][2], eventos[i][3], c1x, c1y, flag_1])&lt;br /&gt;
    novo2 = np.array( [eventos[i][2], eventos[i][3], c2x, c2y, flag_2] )&lt;br /&gt;
                      #xf-&amp;gt;xi          yf-&amp;gt;yi       xf   yf    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    eventos = np.append( eventos, [novo1], axis=0)&lt;br /&gt;
    eventos = np.append( eventos, [novo2], axis=0)&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
  &lt;br /&gt;
  elif (c &amp;gt;= 0.01): #faz crescimento&lt;br /&gt;
      &lt;br /&gt;
    custo = 0.01&lt;br /&gt;
    &lt;br /&gt;
    newx,newy = crecimento(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
    &lt;br /&gt;
    newx,newy,flag = check_anastomose(eventos,newx,newy,eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    novo = np.array( [eventos[i][2], eventos[i][3], newx, newy, flag] )&lt;br /&gt;
    &lt;br /&gt;
    eventos = np.append( eventos, [novo], axis=0 )&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os principais mecanismos são: ''eventos'' que armazena os segmentos de retas com ''xi yi xf yf  flag''; ''flag'' representa se ocorreu o processo de anastomose, caso ''flag'' armazene ''False'' o primeiro ''try'' faz o segmento parar de crescer; Dentro do ''for'' principal há um ''if'' e ''else'' que junto da condição ''random.random() &amp;gt; 0.6857-0.2857*c'' faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois ''random.random()'' é um valor entre [0,1].&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente '''(Figura 4)''' é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;\sin(\sqrt{(A^2+B^2)})^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado - com os mesmos números horizontal e verticalmente - e produz o mapa mostrado na '''Figura 9'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 13'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Condições Iniciais===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:CondiIni.png|250px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
As condições iniciais em formato de estrela são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] ) # xi yi xf yf  flag&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
&lt;br /&gt;
Como discutido anteriormente o mapa de nutrientes utilizado nas simulações de crescimento das hifas interfere diretamente no resultado final referente ao formato do micélio gerado. Para exemplificar essa diferença executamos 3 simulações utilizando cada um dos três estilos de mapas mostrados anteriormente, o Mapa Nâo Homogêneo, o Homogêneo e o Mapa por Imagem utilizando os códigos listados anteriormente. Abaixo está representado o crescimento de real de um fungo. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:Rhizomorhic-mycelium.jpg|250px|thumb|right|Figura 14: Crescimento real de um micélio ]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ref name='REYNDERS'&amp;gt;B. REYNDERS. Grow mushroom cultures from spore, 2018.(https://funguys.co.za/mushroom-cultivation-tips/growing-mushrooms/grow-mushroom-cultures-from-spore/) &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Mapa Heterogêneo===&lt;br /&gt;
&lt;br /&gt;
O mapa heterogêneo tem como característica principal a presença de diferentes concentrações nutricionais ao longo se sua extensão ('''figura 9''') &lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri1.jpeg|250px|thumb|left|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 1.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice1.jpeg|250px|thumb|right|Figura 8: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É possível perceber através dessa imagem a nítida semelhança entre a simulação realizada utilizando o mapa não homogêneo e a a fotografia real do crescimento de um fungo mostrada anteriormente ('''figura 14''').&lt;br /&gt;
&lt;br /&gt;
===Mapa Homogêneo===&lt;br /&gt;
&lt;br /&gt;
Inicialmente o mapa de nutrientes homogênio se encontra completo por nutrientes ('''figura 13'''), conforme o fungo vai crescendo parte desses nutrientes é consumida e é representada pelas partees mais claras da '''figura 11''', enquanto o fungo completamente desenvolvido está mostrado na '''figura 10'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutrii.jpeg|250px|thumb|center|Figura 13: mapa de nutrientes inicial - e homogêneo - utilizado para obtenção da simulação 2.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 11: mapa de nutrientes após a obtenção da simulação 2.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 10: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Evolução Temporal====&lt;br /&gt;
&lt;br /&gt;
Abaixo está representada a evolução temporal do crescimento de um micélio utilizando um mapa de nutrientes homogêneo como base para desenvolvimento das hifas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 12: 5 etapas da simulação usando o mapa homogêneo de crescimento das hifas de um fungo.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora a mesma evolução representada com a utilização do mapa de nutrientes gerado tendo como base uma imagem.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:angulogrande.jpeg|1000px|thumb|center|Figura 16: Evolução temporal do crescimento de hifas utilizando o mapa de imagem da figura 5.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante ressaltar que para cada simulação diferente, os parâmetros utilizados, para crescimento e divisão, devem ser adaptados, na figura acima, por exemplo, foi utilizado um grande desvio padrão na distribuição normal dos ângulos e por isso a figura não se formou por completo pois as hifas se interceptaram excessivamente e isso fez com que o mapa de nutrientes não fosse completamente aproveitado.&lt;br /&gt;
&lt;br /&gt;
===Mapa por imagem===&lt;br /&gt;
&lt;br /&gt;
A possibilidade de utilizar uma imagem para realizar esse tipo de simulação é de grande importância ois nos permite analisar um grande número de situações e formatos diversos que apresentariam grande dificuldade de serem modeladas matemáticamente como foi feita na primeira implementação. Abaixo está representada a mesma imagem da seção anterior, mas dessa vez utilizando um menor desvio padrão para a distribuição normal. &lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|'''Figura 14''': simulação do crescimento do fungo utilizando o mapa de nutrientes da '''Figura 6'''.]]&lt;br /&gt;
&lt;br /&gt;
== Melhorias a serem realizadas ==&lt;br /&gt;
&lt;br /&gt;
Através do trabalho realizado foi possível simular o crescimente de fungos de uma forma muito satisfatória, mas para um estudo mais aprofundado poderiam ser feitas algumas otimizações na implementação do algorítmo para deixar a simulação mais próxima da realidade, tais como:&lt;br /&gt;
&lt;br /&gt;
* Considerar o translocação de nutrientes realizada pelas hifas do fungo até as extremidades onde há uma escassez desses insumos;&lt;br /&gt;
&lt;br /&gt;
* Levar em conta a divisão lateral e não só a dicotômica;&lt;br /&gt;
&lt;br /&gt;
* Uma melhoria no algoritmo de deteção de intersecções entre as hifas;&lt;br /&gt;
&lt;br /&gt;
* Sistema de mortalidade das hifas levando em conta seu tempo de vida;&lt;br /&gt;
&lt;br /&gt;
* Utilizar um mapa de nutrientes contínuo e não discreto;&lt;br /&gt;
&lt;br /&gt;
* Permitir o movimento do fungo para que ele conseguisse &amp;quot;desviar&amp;quot; de possíveis substâncias tóxicas presentes no ambiente;&lt;br /&gt;
&lt;br /&gt;
* Determinar um custo nutricional para manutenção do fungo.&lt;br /&gt;
&lt;br /&gt;
== Código Completo ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
import matplotlib.pyplot as plt &lt;br /&gt;
import matplotlib.animation as animation &lt;br /&gt;
import numpy as np &lt;br /&gt;
import math &lt;br /&gt;
import random&lt;br /&gt;
from array import *&lt;br /&gt;
import seaborn as sb&lt;br /&gt;
&lt;br /&gt;
global r &lt;br /&gt;
r = 1 # tamanho de passo&lt;br /&gt;
repeticao= 1000 # número de hifas que serão calculadas&lt;br /&gt;
tamanho_mapa=100 # quantas divisões(quadrados) ocorrem no mapa de nutri&lt;br /&gt;
&lt;br /&gt;
# MAPA NUTRIENTE&lt;br /&gt;
&lt;br /&gt;
COORDENADA_MAPA= np.linspace(-30,30,tamanho_mapa) &lt;br /&gt;
&lt;br /&gt;
def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) * 1/2&lt;br /&gt;
  addy1 = r * math.sin(angulo1) * 1/2&lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) * 1/2&lt;br /&gt;
  addy2= r * math.sin(angulo2) * 1/2&lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      #print(&amp;quot;Intersection!&amp;quot;)&lt;br /&gt;
      #print(&amp;quot;X1:&amp;quot;,xi,&amp;quot; Y1:&amp;quot;,yi, &amp;quot; X2:&amp;quot;,xf,&amp;quot; Y2:&amp;quot;,yf)&lt;br /&gt;
      #print(&amp;quot;X3:&amp;quot;,evento[0],&amp;quot; Y3:&amp;quot;,evento[1],&amp;quot; X4:&amp;quot;,evento[2],&amp;quot; Y4:&amp;quot;,evento[3])&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
yCOORDENADA_MAPA,xCOORDENADA_MAPA = COORDENADA_MAPA,COORDENADA_MAPA&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&lt;br /&gt;
# MAPA_NUTRIENTE = mapa_unitario_nutri(COORDENADA_MAPA) &lt;br /&gt;
MAPA_NUTRIENTE = mapa_nutri_Nhomogenea(COORDENADA_MAPA)&lt;br /&gt;
print(MAPA_NUTRIENTE)&lt;br /&gt;
# CONDIÇÕES INICIAIS&lt;br /&gt;
flag = True&lt;br /&gt;
                   # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&lt;br /&gt;
for i in range (0,repeticao): &lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    if not eventos[i][4]:&lt;br /&gt;
      continue&lt;br /&gt;
  except IndexError or Exception:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  c = check_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE)&lt;br /&gt;
  &lt;br /&gt;
  if (random.random() &amp;gt; 0.6857-0.2857*c and c&amp;gt;=0.3):   #faz divisão&lt;br /&gt;
    &lt;br /&gt;
    custo = 0.3&lt;br /&gt;
    &lt;br /&gt;
    c1x,c1y,c2x,c2y= divisao(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    c1x,c1y,flag_1 = check_anastomose(eventos, c1x,c1y, eventos[i][2],eventos[i][3])&lt;br /&gt;
    c2x,c2y,flag_2 = check_anastomose(eventos,c2x,c2y, eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    novo1 = np.array( [eventos[i][2], eventos[i][3], c1x, c1y, flag_1])&lt;br /&gt;
    novo2 = np.array( [eventos[i][2], eventos[i][3], c2x, c2y, flag_2] )&lt;br /&gt;
                      #xf-&amp;gt;xi          yf-&amp;gt;yi       xf   yf    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    eventos = np.append( eventos, [novo1], axis=0)&lt;br /&gt;
    eventos = np.append( eventos, [novo2], axis=0)&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
  &lt;br /&gt;
  elif (c &amp;gt;= 0.01): #faz crescimento&lt;br /&gt;
      &lt;br /&gt;
    custo = 0.01&lt;br /&gt;
    &lt;br /&gt;
    newx,newy = crecimento(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
    &lt;br /&gt;
    newx,newy,flag = check_anastomose(eventos,newx,newy,eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    novo = np.array( [eventos[i][2], eventos[i][3], newx, newy, flag] )&lt;br /&gt;
    &lt;br /&gt;
    eventos = np.append( eventos, [novo], axis=0 )&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
plt.figure(figsize=(10,10))&lt;br /&gt;
plt.axes().set_facecolor(&amp;quot;black&amp;quot;)&lt;br /&gt;
plt.title('Fungo com repeticoes: {}'.format(repeticao))&lt;br /&gt;
&lt;br /&gt;
for j in range (0,repeticao):&lt;br /&gt;
    vet=[[eventos[j][0],eventos[j][2]],[eventos[j][1],eventos[j][3]]]&lt;br /&gt;
    &lt;br /&gt;
    plt.plot(vet[0],vet[1],color='green')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=5039</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=5039"/>
		<updated>2021-05-24T22:31:54Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Condições Iniciais */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de diferentes modelos de crescimento. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado para a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a um deslocamento do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório que varia com a espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
&lt;br /&gt;
O código base que chama as funções é o seguinte:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
flag = True&lt;br /&gt;
                   # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&lt;br /&gt;
for i in range (0,repeticao): &lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    if not eventos[i][4]:&lt;br /&gt;
      continue&lt;br /&gt;
  except IndexError or Exception:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  c = check_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE)&lt;br /&gt;
  &lt;br /&gt;
  if (random.random() &amp;gt; 0.6857-0.2857*c and c&amp;gt;=0.3):   #faz divisão&lt;br /&gt;
    &lt;br /&gt;
    custo = 0.3&lt;br /&gt;
    &lt;br /&gt;
    c1x,c1y,c2x,c2y= divisao(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    c1x,c1y,flag_1 = check_anastomose(eventos, c1x,c1y, eventos[i][2],eventos[i][3])&lt;br /&gt;
    c2x,c2y,flag_2 = check_anastomose(eventos,c2x,c2y, eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    novo1 = np.array( [eventos[i][2], eventos[i][3], c1x, c1y, flag_1])&lt;br /&gt;
    novo2 = np.array( [eventos[i][2], eventos[i][3], c2x, c2y, flag_2] )&lt;br /&gt;
                      #xf-&amp;gt;xi          yf-&amp;gt;yi       xf   yf    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    eventos = np.append( eventos, [novo1], axis=0)&lt;br /&gt;
    eventos = np.append( eventos, [novo2], axis=0)&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
  &lt;br /&gt;
  elif (c &amp;gt;= 0.01): #faz crescimento&lt;br /&gt;
      &lt;br /&gt;
    custo = 0.01&lt;br /&gt;
    &lt;br /&gt;
    newx,newy = crecimento(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
    &lt;br /&gt;
    newx,newy,flag = check_anastomose(eventos,newx,newy,eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    novo = np.array( [eventos[i][2], eventos[i][3], newx, newy, flag] )&lt;br /&gt;
    &lt;br /&gt;
    eventos = np.append( eventos, [novo], axis=0 )&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os principais mecanismos são: ''eventos'' que armazena os segmentos de retas com ''xi yi xf yf  flag''; ''flag'' representa se ocorreu o processo de anastomose, caso ''flag'' armazene ''False'' o primeiro ''try'' faz o segmento parar de crescer; Dentro do ''for'' principal há um ''if'' e ''else'' que junto da condição ''random.random() &amp;gt; 0.6857-0.2857*c'' faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois ''random.random()'' é um valor entre [0,1].&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente '''(Figura 4)''' é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;\sin(\sqrt{(A^2+B^2)})^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado - com os mesmos números horizontal e verticalmente - e produz o mapa mostrado na '''Figura 9'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 13'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Condições Iniciais===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:CondiIni.png|250px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
As condições iniciais são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] ) # xi yi xf yf  flag&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
&lt;br /&gt;
Como discutido anteriormente o mapa de nutrientes utilizado nas simulações de crescimento das hifas interfere diretamente no resultado final referente ao formato do micélio gerado. Para exemplificar essa diferença executamos 3 simulações utilizando cada um dos três estilos de mapas mostrados anteriormente, o Mapa Nâo Homogêneo, o Homogêneo e o Mapa por Imagem utilizando os códigos listados anteriormente. Abaixo está representado o crescimento de real de um fungo. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:Rhizomorhic-mycelium.jpg|250px|thumb|right|Figura 14: Crescimento real de um micélio ]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ref name='REYNDERS'&amp;gt;B. REYNDERS. Grow mushroom cultures from spore, 2018.(https://funguys.co.za/mushroom-cultivation-tips/growing-mushrooms/grow-mushroom-cultures-from-spore/) &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Mapa Heterogêneo===&lt;br /&gt;
&lt;br /&gt;
O mapa heterogêneo tem como característica principal a presença de diferentes concentrações nutricionais ao longo se sua extensão (figura 9) &lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri1.jpeg|250px|thumb|left|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 1.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice1.jpeg|250px|thumb|right|Figura 8: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É possível perceber através dessa imagem a nítida semelhança entre a simulação realizada utilizando o mapa não homogêneo e a a fotografia real do crescimento de um fungo mostrada anteriormente (figura 14).&lt;br /&gt;
&lt;br /&gt;
===Mapa Homogêneo===&lt;br /&gt;
&lt;br /&gt;
Inicialmente o mapa de nutrientes homogênio se encontra completo por nutrientes (figura 13), conforme o fungo vai crescendo parte desses nutrientes é consumida e é representada pelas partees mais claras da figura 11, enquanto o fungo completamente desenvolvido está mostrado na figura 10.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutrii.jpeg|250px|thumb|center|Figura 13: mapa de nutrientes inicial - e homogêneo - utilizado para obtenção da simulação 2.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 11: mapa de nutrientes após a obtenção da simulação 2.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 10: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Evolução Temporal====&lt;br /&gt;
&lt;br /&gt;
Abaixo está representada a evolução temporal do crescimento de um micélio utilizando um mapa de nutrientes homogêneo como base para desenvolvimento das hifas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 12: 5 etapas da simulação usando o mapa homogêneo de crescimento das hifas de um fungo.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora a mesma evolução representada com a utilização do mapa de nutrientes gerado tendo como base uma imagem.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:angulogrande.jpeg|1000px|thumb|center|Figura 16: Evolução temporal do crescimento de hifas utilizando o mapa de imagem da figura 5.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante ressaltar que para cada simulação diferente, os parâmetros utilizados, para crescimento e divisão, devem ser adaptados, na figura acima, por exemplo, foi utilizado um grande desvio padrão na distribuição normal dos ângulos e por isso a figura não se formou por completo pois as hifas se interceptaram excessivamente e isso fez com que o mapa de nutrientes não fosse completamente aproveitado.&lt;br /&gt;
&lt;br /&gt;
===Mapa por imagem===&lt;br /&gt;
&lt;br /&gt;
A possibilidade de utilizar uma imagem para realizar esse tipo de simulação é de grande importância ois nos permite analisar um grande número de situações e formatos diversos que apresentariam grande dificuldade de serem modeladas matemáticamente como foi feita na primeira implementação. Abaixo está representada a mesma imagem da seção anterior, mas dessa vez utilizando um menor desvio padrão para a distribuição normal. &lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|'''Figura 14''': simulação do crescimento do fungo utilizando o mapa de nutrientes da '''Figura 6'''.]]&lt;br /&gt;
&lt;br /&gt;
== Melhorias a serem realizadas ==&lt;br /&gt;
&lt;br /&gt;
Através do trabalho realizado foi possível simular o crescimente de fungos de uma forma muito satisfatória, mas para um estudo mais aprofundado poderiam ser feitas algumas otimizações na implementação do algorítmo para deixar a simulação mais próxima da realidade, tais como:&lt;br /&gt;
&lt;br /&gt;
* Considerar o translocação de nutrientes realizada pelas hifas do fungo até as extremidades onde há uma escassez desses insumos;&lt;br /&gt;
&lt;br /&gt;
* Levar em conta a divisão lateral e não só a dicotômica;&lt;br /&gt;
&lt;br /&gt;
* Uma melhoria no algoritmo de deteção de intersecções entre as hifas;&lt;br /&gt;
&lt;br /&gt;
* Sistema de mortalidade das hifas levando em conta seu tempo de vida;&lt;br /&gt;
&lt;br /&gt;
* Utilizar um mapa de nutrientes contínuo e não discreto;&lt;br /&gt;
&lt;br /&gt;
* Permitir o movimento do fungo para que ele conseguisse &amp;quot;desviar&amp;quot; de possíveis substâncias tóxicas presentes no ambiente;&lt;br /&gt;
&lt;br /&gt;
* Determinar um custo nutricional para manutenção do fungo.&lt;br /&gt;
&lt;br /&gt;
== Código Completo ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
import matplotlib.pyplot as plt &lt;br /&gt;
import matplotlib.animation as animation &lt;br /&gt;
import numpy as np &lt;br /&gt;
import math &lt;br /&gt;
import random&lt;br /&gt;
from array import *&lt;br /&gt;
import seaborn as sb&lt;br /&gt;
&lt;br /&gt;
global r &lt;br /&gt;
r = 1 # tamanho de passo&lt;br /&gt;
repeticao= 1000 # número de hifas que serão calculadas&lt;br /&gt;
tamanho_mapa=100 # quantas divisões(quadrados) ocorrem no mapa de nutri&lt;br /&gt;
&lt;br /&gt;
# MAPA NUTRIENTE&lt;br /&gt;
&lt;br /&gt;
COORDENADA_MAPA= np.linspace(-30,30,tamanho_mapa) &lt;br /&gt;
&lt;br /&gt;
def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) * 1/2&lt;br /&gt;
  addy1 = r * math.sin(angulo1) * 1/2&lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) * 1/2&lt;br /&gt;
  addy2= r * math.sin(angulo2) * 1/2&lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      #print(&amp;quot;Intersection!&amp;quot;)&lt;br /&gt;
      #print(&amp;quot;X1:&amp;quot;,xi,&amp;quot; Y1:&amp;quot;,yi, &amp;quot; X2:&amp;quot;,xf,&amp;quot; Y2:&amp;quot;,yf)&lt;br /&gt;
      #print(&amp;quot;X3:&amp;quot;,evento[0],&amp;quot; Y3:&amp;quot;,evento[1],&amp;quot; X4:&amp;quot;,evento[2],&amp;quot; Y4:&amp;quot;,evento[3])&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
yCOORDENADA_MAPA,xCOORDENADA_MAPA = COORDENADA_MAPA,COORDENADA_MAPA&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&lt;br /&gt;
# MAPA_NUTRIENTE = mapa_unitario_nutri(COORDENADA_MAPA) &lt;br /&gt;
MAPA_NUTRIENTE = mapa_nutri_Nhomogenea(COORDENADA_MAPA)&lt;br /&gt;
print(MAPA_NUTRIENTE)&lt;br /&gt;
# CONDIÇÕES INICIAIS&lt;br /&gt;
flag = True&lt;br /&gt;
                   # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&lt;br /&gt;
for i in range (0,repeticao): &lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    if not eventos[i][4]:&lt;br /&gt;
      continue&lt;br /&gt;
  except IndexError or Exception:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  c = check_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE)&lt;br /&gt;
  &lt;br /&gt;
  if (random.random() &amp;gt; 0.6857-0.2857*c and c&amp;gt;=0.3):   #faz divisão&lt;br /&gt;
    &lt;br /&gt;
    custo = 0.3&lt;br /&gt;
    &lt;br /&gt;
    c1x,c1y,c2x,c2y= divisao(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    c1x,c1y,flag_1 = check_anastomose(eventos, c1x,c1y, eventos[i][2],eventos[i][3])&lt;br /&gt;
    c2x,c2y,flag_2 = check_anastomose(eventos,c2x,c2y, eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    novo1 = np.array( [eventos[i][2], eventos[i][3], c1x, c1y, flag_1])&lt;br /&gt;
    novo2 = np.array( [eventos[i][2], eventos[i][3], c2x, c2y, flag_2] )&lt;br /&gt;
                      #xf-&amp;gt;xi          yf-&amp;gt;yi       xf   yf    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    eventos = np.append( eventos, [novo1], axis=0)&lt;br /&gt;
    eventos = np.append( eventos, [novo2], axis=0)&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
  &lt;br /&gt;
  elif (c &amp;gt;= 0.01): #faz crescimento&lt;br /&gt;
      &lt;br /&gt;
    custo = 0.01&lt;br /&gt;
    &lt;br /&gt;
    newx,newy = crecimento(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
    &lt;br /&gt;
    newx,newy,flag = check_anastomose(eventos,newx,newy,eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    novo = np.array( [eventos[i][2], eventos[i][3], newx, newy, flag] )&lt;br /&gt;
    &lt;br /&gt;
    eventos = np.append( eventos, [novo], axis=0 )&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
plt.figure(figsize=(10,10))&lt;br /&gt;
plt.axes().set_facecolor(&amp;quot;black&amp;quot;)&lt;br /&gt;
plt.title('Fungo com repeticoes: {}'.format(repeticao))&lt;br /&gt;
&lt;br /&gt;
for j in range (0,repeticao):&lt;br /&gt;
    vet=[[eventos[j][0],eventos[j][2]],[eventos[j][1],eventos[j][3]]]&lt;br /&gt;
    &lt;br /&gt;
    plt.plot(vet[0],vet[1],color='green')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=5023</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=5023"/>
		<updated>2021-05-24T22:08:24Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Mapa de Nutrientes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de diferentes modelos de crescimento. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado para a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a um deslocamento do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório que varia com a espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
&lt;br /&gt;
O código base que chama as funções é o seguinte:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
flag = True&lt;br /&gt;
                   # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&lt;br /&gt;
for i in range (0,repeticao): &lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    if not eventos[i][4]:&lt;br /&gt;
      continue&lt;br /&gt;
  except IndexError or Exception:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  c = check_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE)&lt;br /&gt;
  &lt;br /&gt;
  if (random.random() &amp;gt; 0.6857-0.2857*c and c&amp;gt;=0.3):   #faz divisão&lt;br /&gt;
    &lt;br /&gt;
    custo = 0.3&lt;br /&gt;
    &lt;br /&gt;
    c1x,c1y,c2x,c2y= divisao(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    c1x,c1y,flag_1 = check_anastomose(eventos, c1x,c1y, eventos[i][2],eventos[i][3])&lt;br /&gt;
    c2x,c2y,flag_2 = check_anastomose(eventos,c2x,c2y, eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    novo1 = np.array( [eventos[i][2], eventos[i][3], c1x, c1y, flag_1])&lt;br /&gt;
    novo2 = np.array( [eventos[i][2], eventos[i][3], c2x, c2y, flag_2] )&lt;br /&gt;
                      #xf-&amp;gt;xi          yf-&amp;gt;yi       xf   yf    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    eventos = np.append( eventos, [novo1], axis=0)&lt;br /&gt;
    eventos = np.append( eventos, [novo2], axis=0)&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
  &lt;br /&gt;
  elif (c &amp;gt;= 0.01): #faz crescimento&lt;br /&gt;
      &lt;br /&gt;
    custo = 0.01&lt;br /&gt;
    &lt;br /&gt;
    newx,newy = crecimento(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
    &lt;br /&gt;
    newx,newy,flag = check_anastomose(eventos,newx,newy,eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    novo = np.array( [eventos[i][2], eventos[i][3], newx, newy, flag] )&lt;br /&gt;
    &lt;br /&gt;
    eventos = np.append( eventos, [novo], axis=0 )&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os principais mecanismos são: ''eventos'' que armazena os segmentos de retas com ''xi yi xf yf  flag''; ''flag'' representa se ocorreu o processo de anastomose, caso ''flag'' armazene ''False'' o primeiro ''try'' faz o segmento parar de crescer; Dentro do ''for'' principal há um ''if'' e ''else'' que junto da condição ''random.random() &amp;gt; 0.6857-0.2857*c'' faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois ''random.random()'' é um valor entre [0,1].&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;\sin(\sqrt{(A^2+B^2)})^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado - com os mesmos números horizontal e verticalmente - e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Condições Iniciais===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:CondiIni.png|200px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
As condições iniciais são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] ) # xi yi xf yf  flag&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
&lt;br /&gt;
Como discutido anteriormente o mapa de nutrientes utilizado nas simulações de crescimento das hifas interfere diretamente no resultado final referente ao formato do micélio gerado. Para exemplificar essa diferença executamos 3 simulações utilizando cada um dos três estilos de mapas mostrados anteriormente, o Mapa Nâo Homogêneo, o Homogêneo e o Mapa por Imagem utilizando os códigos listados anteriormente. Abaixo está representado o crescimento de real de um fungo. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:Rhizomorhic-mycelium.jpg|250px|thumb|right|Figura 14: Crescimento real de um micélio ]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ref name='REYNDERS'&amp;gt;B. REYNDERS. Grow mushroom cultures from spore, 2018.(https://funguys.co.za/mushroom-cultivation-tips/growing-mushrooms/grow-mushroom-cultures-from-spore/) &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Mapa não homogêneo===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri1.jpeg|250px|thumb|left|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 1.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice1.jpeg|250px|thumb|right|Figura 8: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa Homogêneo===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutrii.jpeg|250px|thumb|center|Figura 13: mapa de nutrientes inicial - e homogêneo - utilizado para obtenção da simulação 2.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 11: mapa de nutrientes utilizado para obtenção da simulação 2.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 10: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Evolução Temporal====&lt;br /&gt;
&lt;br /&gt;
Abaixo está representada a evolução temporal do crescimento de um micélio utilizando um mapa de nutrientes homogêneo como base para desenvolvimento das hifas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 12: 5 etapas da simulação usando o mapa homogêneo de crescimento das hifas de um fungo.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora a mesma evolução representada com a utilização do mapa de nutrientes gerado tendo como base uma imagem.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:angulogrande.jpeg|1000px|thumb|center|Figura 16: Evolução temporal do crescimento de hifas utilizando o mapa de imagem da figura 5.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante ressaltar que para cada simulação diferente, os parâmetros utilizados, para crescimento e divisão, devem ser adaptados, na figura acima, por exemplo, foi utilizado um grande desvio padrão na distribuição normal dos ângulos e por isso a figura não se formou por completo pois as hifas se interceptaram excessivamente e isso fez com que o mapa de nutrientes não fosse completamente aproveitado.&lt;br /&gt;
&lt;br /&gt;
===Mapa por imagem===&lt;br /&gt;
&lt;br /&gt;
A possibilidade de utilizar uma imagem para realizar esse tipo de simulação é de grande importância ois nos permite analisar um grande número de situações e formatos diversos que apresentariam grande dificuldade de serem modeladas matemáticamente como foi feita na primeira implementação. Abaixo está representada a mesma imagem da seção anterior, mas dessa vez utilizando um menor desvio padrão para a distribuição normal. &lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|'''Figura 14''': simulação do crescimento do fungo utilizando o mapa de nutrientes da '''Figura 6'''.]]&lt;br /&gt;
&lt;br /&gt;
== Melhorias a serem realizadas ==&lt;br /&gt;
&lt;br /&gt;
Através do trabalho realizado foi possível simular o crescimente de fungos de uma forma muito satisfatória, mas para um estudo mais aprofundado poderiam ser feitas algumas otimizações na implementação do algorítmo para deixar a simulação mais próxima da realidade, tais como:&lt;br /&gt;
&lt;br /&gt;
* Considerar o translocação de nutrientes realizada pelas hifas do fungo até as extremidades onde há uma escassez desses insumos;&lt;br /&gt;
&lt;br /&gt;
* Levar em conta a divisão lateral e não só a dicotômica;&lt;br /&gt;
&lt;br /&gt;
* Uma melhoria no algoritmo de deteção de intersecções entre as hifas;&lt;br /&gt;
&lt;br /&gt;
* Sistema de mortalidade das hifas levando em conta seu tempo de vida;&lt;br /&gt;
&lt;br /&gt;
* Utilizar um mapa de nutrientes contínuo e não discreto;&lt;br /&gt;
&lt;br /&gt;
* Determinar um custo nutricional para manutenção do fungo.&lt;br /&gt;
&lt;br /&gt;
== Código Completo ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
import matplotlib.pyplot as plt &lt;br /&gt;
import matplotlib.animation as animation &lt;br /&gt;
import numpy as np &lt;br /&gt;
import math &lt;br /&gt;
import random&lt;br /&gt;
from array import *&lt;br /&gt;
import seaborn as sb&lt;br /&gt;
&lt;br /&gt;
global r &lt;br /&gt;
r = 1 # tamanho de passo&lt;br /&gt;
repeticao= 1000 # número de hifas que serão calculadas&lt;br /&gt;
tamanho_mapa=100 # quantas divisões(quadrados) ocorrem no mapa de nutri&lt;br /&gt;
&lt;br /&gt;
# MAPA NUTRIENTE&lt;br /&gt;
&lt;br /&gt;
COORDENADA_MAPA= np.linspace(-30,30,tamanho_mapa) &lt;br /&gt;
&lt;br /&gt;
def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) * 1/2&lt;br /&gt;
  addy1 = r * math.sin(angulo1) * 1/2&lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) * 1/2&lt;br /&gt;
  addy2= r * math.sin(angulo2) * 1/2&lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      #print(&amp;quot;Intersection!&amp;quot;)&lt;br /&gt;
      #print(&amp;quot;X1:&amp;quot;,xi,&amp;quot; Y1:&amp;quot;,yi, &amp;quot; X2:&amp;quot;,xf,&amp;quot; Y2:&amp;quot;,yf)&lt;br /&gt;
      #print(&amp;quot;X3:&amp;quot;,evento[0],&amp;quot; Y3:&amp;quot;,evento[1],&amp;quot; X4:&amp;quot;,evento[2],&amp;quot; Y4:&amp;quot;,evento[3])&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
yCOORDENADA_MAPA,xCOORDENADA_MAPA = COORDENADA_MAPA,COORDENADA_MAPA&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&lt;br /&gt;
# MAPA_NUTRIENTE = mapa_unitario_nutri(COORDENADA_MAPA) &lt;br /&gt;
MAPA_NUTRIENTE = mapa_nutri_Nhomogenea(COORDENADA_MAPA)&lt;br /&gt;
print(MAPA_NUTRIENTE)&lt;br /&gt;
# CONDIÇÕES INICIAIS&lt;br /&gt;
flag = True&lt;br /&gt;
                   # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&lt;br /&gt;
for i in range (0,repeticao): &lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    if not eventos[i][4]:&lt;br /&gt;
      continue&lt;br /&gt;
  except IndexError or Exception:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  c = check_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE)&lt;br /&gt;
  &lt;br /&gt;
  if (random.random() &amp;gt; 0.6857-0.2857*c and c&amp;gt;=0.3):   #faz divisão&lt;br /&gt;
    &lt;br /&gt;
    custo = 0.3&lt;br /&gt;
    &lt;br /&gt;
    c1x,c1y,c2x,c2y= divisao(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    c1x,c1y,flag_1 = check_anastomose(eventos, c1x,c1y, eventos[i][2],eventos[i][3])&lt;br /&gt;
    c2x,c2y,flag_2 = check_anastomose(eventos,c2x,c2y, eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    novo1 = np.array( [eventos[i][2], eventos[i][3], c1x, c1y, flag_1])&lt;br /&gt;
    novo2 = np.array( [eventos[i][2], eventos[i][3], c2x, c2y, flag_2] )&lt;br /&gt;
                      #xf-&amp;gt;xi          yf-&amp;gt;yi       xf   yf    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    eventos = np.append( eventos, [novo1], axis=0)&lt;br /&gt;
    eventos = np.append( eventos, [novo2], axis=0)&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
  &lt;br /&gt;
  elif (c &amp;gt;= 0.01): #faz crescimento&lt;br /&gt;
      &lt;br /&gt;
    custo = 0.01&lt;br /&gt;
    &lt;br /&gt;
    newx,newy = crecimento(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
    &lt;br /&gt;
    newx,newy,flag = check_anastomose(eventos,newx,newy,eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    novo = np.array( [eventos[i][2], eventos[i][3], newx, newy, flag] )&lt;br /&gt;
    &lt;br /&gt;
    eventos = np.append( eventos, [novo], axis=0 )&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
plt.figure(figsize=(10,10))&lt;br /&gt;
plt.axes().set_facecolor(&amp;quot;black&amp;quot;)&lt;br /&gt;
plt.title('Fungo com repeticoes: {}'.format(repeticao))&lt;br /&gt;
&lt;br /&gt;
for j in range (0,repeticao):&lt;br /&gt;
    vet=[[eventos[j][0],eventos[j][2]],[eventos[j][1],eventos[j][3]]]&lt;br /&gt;
    &lt;br /&gt;
    plt.plot(vet[0],vet[1],color='green')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4916</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4916"/>
		<updated>2021-05-24T18:02:55Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Formulação Matemática e Implementação */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
&lt;br /&gt;
O código base que chama as funções é o seguinte:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
flag = True&lt;br /&gt;
                   # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&lt;br /&gt;
for i in range (0,repeticao): &lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    if not eventos[i][4]:&lt;br /&gt;
      continue&lt;br /&gt;
  except IndexError or Exception:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  c = check_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE)&lt;br /&gt;
  &lt;br /&gt;
  if (random.random() &amp;gt; 0.6857-0.2857*c and c&amp;gt;=0.3):   #faz divisão&lt;br /&gt;
    &lt;br /&gt;
    custo = 0.3&lt;br /&gt;
    &lt;br /&gt;
    c1x,c1y,c2x,c2y= divisao(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    c1x,c1y,flag_1 = check_anastomose(eventos, c1x,c1y, eventos[i][2],eventos[i][3])&lt;br /&gt;
    c2x,c2y,flag_2 = check_anastomose(eventos,c2x,c2y, eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    novo1 = np.array( [eventos[i][2], eventos[i][3], c1x, c1y, flag_1])&lt;br /&gt;
    novo2 = np.array( [eventos[i][2], eventos[i][3], c2x, c2y, flag_2] )&lt;br /&gt;
                      #xf-&amp;gt;xi          yf-&amp;gt;yi       xf   yf    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    eventos = np.append( eventos, [novo1], axis=0)&lt;br /&gt;
    eventos = np.append( eventos, [novo2], axis=0)&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
  &lt;br /&gt;
  elif (c &amp;gt;= 0.01): #faz crescimento&lt;br /&gt;
      &lt;br /&gt;
    custo = 0.01&lt;br /&gt;
    &lt;br /&gt;
    newx,newy = crecimento(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
    &lt;br /&gt;
    newx,newy,flag = check_anastomose(eventos,newx,newy,eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    novo = np.array( [eventos[i][2], eventos[i][3], newx, newy, flag] )&lt;br /&gt;
    &lt;br /&gt;
    eventos = np.append( eventos, [novo], axis=0 )&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os principais mecanismos são: ''eventos'' que armazena os segmentos de retas com ''xi yi xf yf  flag''; ''flag'' representa se ocorreu o processo de anastomose, caso ''flag'' armazene ''False'' o primeiro ''try'' faz o segmento parar de crescer; Dentro do ''for'' principal há um ''if'' e ''else'' que junto da condição ''random.random() &amp;gt; 0.6857-0.2857*c'' faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois ''random.random()'' é um valor entre [0,1].&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com os mesmos números horizontal e verticalmente- e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Condições Iniciais===&lt;br /&gt;
&lt;br /&gt;
As condições iniciais são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
[[Arquivo:CondiIni.png|200px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] ) # xi yi xf yf  flag&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Código Completo ==&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|'''Figura x''': simulação do crescimento do fungo utilizando o mapa de nutrientes da '''Figura 6'''.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
import matplotlib.pyplot as plt &lt;br /&gt;
import matplotlib.animation as animation &lt;br /&gt;
import numpy as np &lt;br /&gt;
import math &lt;br /&gt;
import random&lt;br /&gt;
from array import *&lt;br /&gt;
import seaborn as sb&lt;br /&gt;
&lt;br /&gt;
global r &lt;br /&gt;
r = 1 # tamanho de passo&lt;br /&gt;
repeticao= 1000 # número de hifas que serão calculadas&lt;br /&gt;
tamanho_mapa=100 # quantas divisões(quadrados) ocorrem no mapa de nutri&lt;br /&gt;
&lt;br /&gt;
# MAPA NUTRIENTE&lt;br /&gt;
&lt;br /&gt;
COORDENADA_MAPA= np.linspace(-30,30,tamanho_mapa) &lt;br /&gt;
&lt;br /&gt;
def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) * 1/2&lt;br /&gt;
  addy1 = r * math.sin(angulo1) * 1/2&lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) * 1/2&lt;br /&gt;
  addy2= r * math.sin(angulo2) * 1/2&lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      #print(&amp;quot;Intersection!&amp;quot;)&lt;br /&gt;
      #print(&amp;quot;X1:&amp;quot;,xi,&amp;quot; Y1:&amp;quot;,yi, &amp;quot; X2:&amp;quot;,xf,&amp;quot; Y2:&amp;quot;,yf)&lt;br /&gt;
      #print(&amp;quot;X3:&amp;quot;,evento[0],&amp;quot; Y3:&amp;quot;,evento[1],&amp;quot; X4:&amp;quot;,evento[2],&amp;quot; Y4:&amp;quot;,evento[3])&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
yCOORDENADA_MAPA,xCOORDENADA_MAPA = COORDENADA_MAPA,COORDENADA_MAPA&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&lt;br /&gt;
# MAPA_NUTRIENTE = mapa_unitario_nutri(COORDENADA_MAPA) &lt;br /&gt;
MAPA_NUTRIENTE = mapa_nutri_Nhomogenea(COORDENADA_MAPA)&lt;br /&gt;
print(MAPA_NUTRIENTE)&lt;br /&gt;
# CONDIÇÕES INICIAIS&lt;br /&gt;
flag = True&lt;br /&gt;
                   # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&lt;br /&gt;
for i in range (0,repeticao): &lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    if not eventos[i][4]:&lt;br /&gt;
      continue&lt;br /&gt;
  except IndexError or Exception:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  c = check_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE)&lt;br /&gt;
  &lt;br /&gt;
  if (random.random() &amp;gt; 0.6857-0.2857*c and c&amp;gt;=0.3):   #faz divisão&lt;br /&gt;
    &lt;br /&gt;
    custo = 0.3&lt;br /&gt;
    &lt;br /&gt;
    c1x,c1y,c2x,c2y= divisao(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    c1x,c1y,flag_1 = check_anastomose(eventos, c1x,c1y, eventos[i][2],eventos[i][3])&lt;br /&gt;
    c2x,c2y,flag_2 = check_anastomose(eventos,c2x,c2y, eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    novo1 = np.array( [eventos[i][2], eventos[i][3], c1x, c1y, flag_1])&lt;br /&gt;
    novo2 = np.array( [eventos[i][2], eventos[i][3], c2x, c2y, flag_2] )&lt;br /&gt;
                      #xf-&amp;gt;xi          yf-&amp;gt;yi       xf   yf    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    eventos = np.append( eventos, [novo1], axis=0)&lt;br /&gt;
    eventos = np.append( eventos, [novo2], axis=0)&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
  &lt;br /&gt;
  elif (c &amp;gt;= 0.01): #faz crescimento&lt;br /&gt;
      &lt;br /&gt;
    custo = 0.01&lt;br /&gt;
    &lt;br /&gt;
    newx,newy = crecimento(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
    &lt;br /&gt;
    newx,newy,flag = check_anastomose(eventos,newx,newy,eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    novo = np.array( [eventos[i][2], eventos[i][3], newx, newy, flag] )&lt;br /&gt;
    &lt;br /&gt;
    eventos = np.append( eventos, [novo], axis=0 )&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
plt.figure(figsize=(10,10))&lt;br /&gt;
plt.axes().set_facecolor(&amp;quot;black&amp;quot;)&lt;br /&gt;
plt.title('Fungo com repeticoes: {}'.format(repeticao))&lt;br /&gt;
&lt;br /&gt;
for j in range (0,repeticao):&lt;br /&gt;
    vet=[[eventos[j][0],eventos[j][2]],[eventos[j][1],eventos[j][3]]]&lt;br /&gt;
    &lt;br /&gt;
    plt.plot(vet[0],vet[1],color='green')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4913</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4913"/>
		<updated>2021-05-24T17:49:59Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Formulação Matemática e Implementação */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
&lt;br /&gt;
O código base que chama as funções é o seguinte, ''flag'' representa se ocorreu o processo de anastomose, caso ''flag'' armazene ''False'' o primeiro ''try'' faz o segmento parar de crescer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
flag = True&lt;br /&gt;
                   # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&lt;br /&gt;
for i in range (0,repeticao): &lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    if not eventos[i][4]:&lt;br /&gt;
      continue&lt;br /&gt;
  except IndexError or Exception:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  c = check_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE)&lt;br /&gt;
  &lt;br /&gt;
  if (random.random() &amp;gt; 0.6857-0.2857*c and c&amp;gt;=0.3):   #faz divisão&lt;br /&gt;
    &lt;br /&gt;
    custo = 0.3&lt;br /&gt;
    &lt;br /&gt;
    c1x,c1y,c2x,c2y= divisao(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    c1x,c1y,flag_1 = check_anastomose(eventos, c1x,c1y, eventos[i][2],eventos[i][3])&lt;br /&gt;
    c2x,c2y,flag_2 = check_anastomose(eventos,c2x,c2y, eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    novo1 = np.array( [eventos[i][2], eventos[i][3], c1x, c1y, flag_1])&lt;br /&gt;
    novo2 = np.array( [eventos[i][2], eventos[i][3], c2x, c2y, flag_2] )&lt;br /&gt;
                      #xf-&amp;gt;xi          yf-&amp;gt;yi       xf   yf    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    eventos = np.append( eventos, [novo1], axis=0)&lt;br /&gt;
    eventos = np.append( eventos, [novo2], axis=0)&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
  &lt;br /&gt;
  elif (c &amp;gt;= 0.01): #faz crescimento&lt;br /&gt;
      &lt;br /&gt;
    custo = 0.01&lt;br /&gt;
    &lt;br /&gt;
    newx,newy = crecimento(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
    &lt;br /&gt;
    newx,newy,flag = check_anastomose(eventos,newx,newy,eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    novo = np.array( [eventos[i][2], eventos[i][3], newx, newy, flag] )&lt;br /&gt;
    &lt;br /&gt;
    eventos = np.append( eventos, [novo], axis=0 )&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com os mesmos números horizontal e verticalmente- e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Condições Iniciais===&lt;br /&gt;
&lt;br /&gt;
As condições iniciais são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
[[Arquivo:CondiIni.png|200px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] ) # xi yi xf yf  flag&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Código Completo ==&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|'''Figura x''': simulação do crescimento do fungo utilizando o mapa de nutrientes da '''Figura 6'''.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
import matplotlib.pyplot as plt &lt;br /&gt;
import matplotlib.animation as animation &lt;br /&gt;
import numpy as np &lt;br /&gt;
import math &lt;br /&gt;
import random&lt;br /&gt;
from array import *&lt;br /&gt;
import seaborn as sb&lt;br /&gt;
&lt;br /&gt;
global r &lt;br /&gt;
r = 1 # tamanho de passo&lt;br /&gt;
repeticao= 1000 # número de hifas que serão calculadas&lt;br /&gt;
tamanho_mapa=100 # quantas divisões(quadrados) ocorrem no mapa de nutri&lt;br /&gt;
&lt;br /&gt;
# MAPA NUTRIENTE&lt;br /&gt;
&lt;br /&gt;
COORDENADA_MAPA= np.linspace(-30,30,tamanho_mapa) &lt;br /&gt;
&lt;br /&gt;
def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) * 1/2&lt;br /&gt;
  addy1 = r * math.sin(angulo1) * 1/2&lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) * 1/2&lt;br /&gt;
  addy2= r * math.sin(angulo2) * 1/2&lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      #print(&amp;quot;Intersection!&amp;quot;)&lt;br /&gt;
      #print(&amp;quot;X1:&amp;quot;,xi,&amp;quot; Y1:&amp;quot;,yi, &amp;quot; X2:&amp;quot;,xf,&amp;quot; Y2:&amp;quot;,yf)&lt;br /&gt;
      #print(&amp;quot;X3:&amp;quot;,evento[0],&amp;quot; Y3:&amp;quot;,evento[1],&amp;quot; X4:&amp;quot;,evento[2],&amp;quot; Y4:&amp;quot;,evento[3])&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
yCOORDENADA_MAPA,xCOORDENADA_MAPA = COORDENADA_MAPA,COORDENADA_MAPA&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&lt;br /&gt;
# MAPA_NUTRIENTE = mapa_unitario_nutri(COORDENADA_MAPA) &lt;br /&gt;
MAPA_NUTRIENTE = mapa_nutri_Nhomogenea(COORDENADA_MAPA)&lt;br /&gt;
print(MAPA_NUTRIENTE)&lt;br /&gt;
# CONDIÇÕES INICIAIS&lt;br /&gt;
flag = True&lt;br /&gt;
                   # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&lt;br /&gt;
for i in range (0,repeticao): &lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    if not eventos[i][4]:&lt;br /&gt;
      continue&lt;br /&gt;
  except IndexError or Exception:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  c = check_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE)&lt;br /&gt;
  &lt;br /&gt;
  if (random.random() &amp;gt; 0.6857-0.2857*c and c&amp;gt;=0.3):   #faz divisão&lt;br /&gt;
    &lt;br /&gt;
    custo = 0.3&lt;br /&gt;
    &lt;br /&gt;
    c1x,c1y,c2x,c2y= divisao(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    c1x,c1y,flag_1 = check_anastomose(eventos, c1x,c1y, eventos[i][2],eventos[i][3])&lt;br /&gt;
    c2x,c2y,flag_2 = check_anastomose(eventos,c2x,c2y, eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    novo1 = np.array( [eventos[i][2], eventos[i][3], c1x, c1y, flag_1])&lt;br /&gt;
    novo2 = np.array( [eventos[i][2], eventos[i][3], c2x, c2y, flag_2] )&lt;br /&gt;
                      #xf-&amp;gt;xi          yf-&amp;gt;yi       xf   yf    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    eventos = np.append( eventos, [novo1], axis=0)&lt;br /&gt;
    eventos = np.append( eventos, [novo2], axis=0)&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
  &lt;br /&gt;
  elif (c &amp;gt;= 0.01): #faz crescimento&lt;br /&gt;
      &lt;br /&gt;
    custo = 0.01&lt;br /&gt;
    &lt;br /&gt;
    newx,newy = crecimento(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
    &lt;br /&gt;
    newx,newy,flag = check_anastomose(eventos,newx,newy,eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    novo = np.array( [eventos[i][2], eventos[i][3], newx, newy, flag] )&lt;br /&gt;
    &lt;br /&gt;
    eventos = np.append( eventos, [novo], axis=0 )&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
plt.figure(figsize=(10,10))&lt;br /&gt;
plt.axes().set_facecolor(&amp;quot;black&amp;quot;)&lt;br /&gt;
plt.title('Fungo com repeticoes: {}'.format(repeticao))&lt;br /&gt;
&lt;br /&gt;
for j in range (0,repeticao):&lt;br /&gt;
    vet=[[eventos[j][0],eventos[j][2]],[eventos[j][1],eventos[j][3]]]&lt;br /&gt;
    &lt;br /&gt;
    plt.plot(vet[0],vet[1],color='green')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4897</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4897"/>
		<updated>2021-05-24T14:58:49Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Conclusão */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com os mesmos números horizontal e verticalmente- e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Condições Iniciais===&lt;br /&gt;
&lt;br /&gt;
As condições iniciais são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
[[Arquivo:CondiIni.png|200px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] ) # xi yi xf yf  flag&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Código Completo ==&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|'''Figura x''': simulação do crescimento do fungo utilizando o mapa de nutrientes da '''Figura 6'''.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
import matplotlib.pyplot as plt &lt;br /&gt;
import matplotlib.animation as animation &lt;br /&gt;
import numpy as np &lt;br /&gt;
import math &lt;br /&gt;
import random&lt;br /&gt;
from array import *&lt;br /&gt;
import seaborn as sb&lt;br /&gt;
&lt;br /&gt;
global r &lt;br /&gt;
r = 1 # tamanho de passo&lt;br /&gt;
repeticao= 1000 # número de hifas que serão calculadas&lt;br /&gt;
tamanho_mapa=100 # quantas divisões(quadrados) ocorrem no mapa de nutri&lt;br /&gt;
&lt;br /&gt;
# MAPA NUTRIENTE&lt;br /&gt;
&lt;br /&gt;
COORDENADA_MAPA= np.linspace(-30,30,tamanho_mapa) &lt;br /&gt;
&lt;br /&gt;
def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) * 1/2&lt;br /&gt;
  addy1 = r * math.sin(angulo1) * 1/2&lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) * 1/2&lt;br /&gt;
  addy2= r * math.sin(angulo2) * 1/2&lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      #print(&amp;quot;Intersection!&amp;quot;)&lt;br /&gt;
      #print(&amp;quot;X1:&amp;quot;,xi,&amp;quot; Y1:&amp;quot;,yi, &amp;quot; X2:&amp;quot;,xf,&amp;quot; Y2:&amp;quot;,yf)&lt;br /&gt;
      #print(&amp;quot;X3:&amp;quot;,evento[0],&amp;quot; Y3:&amp;quot;,evento[1],&amp;quot; X4:&amp;quot;,evento[2],&amp;quot; Y4:&amp;quot;,evento[3])&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
yCOORDENADA_MAPA,xCOORDENADA_MAPA = COORDENADA_MAPA,COORDENADA_MAPA&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&lt;br /&gt;
# MAPA_NUTRIENTE = mapa_unitario_nutri(COORDENADA_MAPA) &lt;br /&gt;
MAPA_NUTRIENTE = mapa_nutri_Nhomogenea(COORDENADA_MAPA)&lt;br /&gt;
print(MAPA_NUTRIENTE)&lt;br /&gt;
# CONDIÇÕES INICIAIS&lt;br /&gt;
flag = True&lt;br /&gt;
                   # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&lt;br /&gt;
for i in range (0,repeticao): &lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    if not eventos[i][4]:&lt;br /&gt;
      continue&lt;br /&gt;
  except IndexError or Exception:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  c = check_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE)&lt;br /&gt;
  &lt;br /&gt;
  if (random.random() &amp;gt; 0.6857-0.2857*c and c&amp;gt;=0.3):   #faz divisão&lt;br /&gt;
    &lt;br /&gt;
    custo = 0.3&lt;br /&gt;
    &lt;br /&gt;
    c1x,c1y,c2x,c2y= divisao(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    c1x,c1y,flag_1 = check_anastomose(eventos, c1x,c1y, eventos[i][2],eventos[i][3])&lt;br /&gt;
    c2x,c2y,flag_2 = check_anastomose(eventos,c2x,c2y, eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    novo1 = np.array( [eventos[i][2], eventos[i][3], c1x, c1y, flag_1])&lt;br /&gt;
    novo2 = np.array( [eventos[i][2], eventos[i][3], c2x, c2y, flag_2] )&lt;br /&gt;
                      #xf-&amp;gt;xi          yf-&amp;gt;yi       xf   yf    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    eventos = np.append( eventos, [novo1], axis=0)&lt;br /&gt;
    eventos = np.append( eventos, [novo2], axis=0)&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
  &lt;br /&gt;
  elif (c &amp;gt;= 0.01): #faz crescimento&lt;br /&gt;
      &lt;br /&gt;
    custo = 0.01&lt;br /&gt;
    &lt;br /&gt;
    newx,newy = crecimento(eventos[i][0],eventos[i][1],eventos[i][2],eventos[i][3])&lt;br /&gt;
    &lt;br /&gt;
    newx,newy,flag = check_anastomose(eventos,newx,newy,eventos[i][2],eventos[i][3])&lt;br /&gt;
&lt;br /&gt;
    novo = np.array( [eventos[i][2], eventos[i][3], newx, newy, flag] )&lt;br /&gt;
    &lt;br /&gt;
    eventos = np.append( eventos, [novo], axis=0 )&lt;br /&gt;
&lt;br /&gt;
    MAPA_NUTRIENTE= atualiza_mapa_nutri(eventos[i][2],eventos[i][3],xCOORDENADA_MAPA,yCOORDENADA_MAPA,MAPA_NUTRIENTE,custo)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
plt.figure(figsize=(10,10))&lt;br /&gt;
plt.axes().set_facecolor(&amp;quot;black&amp;quot;)&lt;br /&gt;
plt.title('Fungo com repeticoes: {}'.format(repeticao))&lt;br /&gt;
&lt;br /&gt;
for j in range (0,repeticao):&lt;br /&gt;
    vet=[[eventos[j][0],eventos[j][2]],[eventos[j][1],eventos[j][3]]]&lt;br /&gt;
    &lt;br /&gt;
    plt.plot(vet[0],vet[1],color='green')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4895</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4895"/>
		<updated>2021-05-24T14:53:35Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Conclusão */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com os mesmos números horizontal e verticalmente- e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Condições Iniciais===&lt;br /&gt;
&lt;br /&gt;
As condições iniciais são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
[[Arquivo:CondiIni.png|200px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] ) # xi yi xf yf  flag&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|'''Figura x''': simulação do crescimento do fungo utilizando o mapa de nutrientes da '''Figura 6'''.]]&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4894</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4894"/>
		<updated>2021-05-24T14:52:21Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Conclusão */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com os mesmos números horizontal e verticalmente- e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Condições Iniciais===&lt;br /&gt;
&lt;br /&gt;
As condições iniciais são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
[[Arquivo:CondiIni.png|200px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] ) # xi yi xf yf  flag&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4893</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4893"/>
		<updated>2021-05-24T14:51:37Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Conclusão */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com os mesmos números horizontal e verticalmente- e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Condições Iniciais===&lt;br /&gt;
&lt;br /&gt;
As condições iniciais são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
[[Arquivo:CondiIni.png|200px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] ) # xi yi xf yf  flag&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
Muito_obrigado.png&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Muito_obrigado.png&amp;diff=4892</id>
		<title>Arquivo:Muito obrigado.png</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Muito_obrigado.png&amp;diff=4892"/>
		<updated>2021-05-24T14:51:22Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: Muito_obrigado em fungo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Muito_obrigado em fungo&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4891</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4891"/>
		<updated>2021-05-24T14:49:47Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Condições Iniciais */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com os mesmos números horizontal e verticalmente- e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Condições Iniciais===&lt;br /&gt;
&lt;br /&gt;
As condições iniciais são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
[[Arquivo:CondiIni.png|200px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] ) # xi yi xf yf  flag&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4890</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4890"/>
		<updated>2021-05-24T14:49:35Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Formulação Matemática e Implementação */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com os mesmos números horizontal e verticalmente- e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Condições Iniciais===&lt;br /&gt;
&lt;br /&gt;
As condições iniciais são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
[[Arquivo:CondiIni.png|200px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] ) # xi yi xf yf  flag&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Condições Iniciais==&lt;br /&gt;
&lt;br /&gt;
As condições iniciais são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
[[Arquivo:CondiIni.png|200px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] ) # xi yi xf yf  flag&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4889</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4889"/>
		<updated>2021-05-24T14:48:54Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Formulação Matemática e Implementação */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com os mesmos números horizontal e verticalmente- e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Condições Iniciais==&lt;br /&gt;
&lt;br /&gt;
As condições iniciais são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
[[Arquivo:CondiIni.png|200px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] ) # xi yi xf yf  flag&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4888</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4888"/>
		<updated>2021-05-24T14:48:37Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Condições Iniciais */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com os mesmos números horizontal e verticalmente- e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4884</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4884"/>
		<updated>2021-05-24T14:44:38Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Condições Iniciais */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com os mesmos números horizontal e verticalmente- e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Condições Iniciais==&lt;br /&gt;
&lt;br /&gt;
As condições iniciais são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
[[Arquivo:CondiIni.png|200px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] ) # xi yi xf yf  flag&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4883</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4883"/>
		<updated>2021-05-24T14:44:00Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Condições Iniciais */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com os mesmos números horizontal e verticalmente- e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Condições Iniciais==&lt;br /&gt;
&lt;br /&gt;
As condições iniciais são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
[[Arquivo:CondiIni.png|200px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
                     # xi yi xf yf  flag&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4881</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4881"/>
		<updated>2021-05-24T14:42:58Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: c&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com os mesmos números horizontal e verticalmente- e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Condições Iniciais==&lt;br /&gt;
&lt;br /&gt;
As condições iniciais são mostradas na '''Figura 7''' e implementadas assim:&lt;br /&gt;
[[Arquivo:CondiIni.png|200px|thumb|right|'''Figura 7''': Condições iniciais]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
eventos = np.array( [[ 0, 0, 1, 0, True]] )&lt;br /&gt;
for i in range (1,8):&lt;br /&gt;
  eventos = np.append( eventos, [[ 0, 0, r * math.cos(np.pi/4 *i), r * math.sin(np.pi/4*i),  True]], axis=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:CondiIni.png&amp;diff=4880</id>
		<title>Arquivo:CondiIni.png</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:CondiIni.png&amp;diff=4880"/>
		<updated>2021-05-24T14:42:42Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: condições iniciais&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;condições iniciais&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4877</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4877"/>
		<updated>2021-05-24T14:28:29Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Mapa de Nutrientes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com os mesmos números horizontal e verticalmente- e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4876</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4876"/>
		<updated>2021-05-24T14:27:55Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Mapa de Nutrientes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com os mesmos números horizontal e verticalmente- e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A terceira forma é utilizando uma imagem, como a da '''Figura 5''', que transforma o gradiente de preto a branco dos pontos (''x_mapa,y_mapa'') em um mapa de nutriente, mostrado '''Figura 6''', Preto representa 0 nutriente e branco 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import cv2&lt;br /&gt;
import numpy as np&lt;br /&gt;
import sys&lt;br /&gt;
import seaborn as sn&lt;br /&gt;
&lt;br /&gt;
img_path = '/content/OBRIGADO.png'&lt;br /&gt;
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required &lt;br /&gt;
&lt;br /&gt;
img_reverted= cv2.bitwise_not(img)&lt;br /&gt;
&lt;br /&gt;
new_img = img_reverted / 255.0  # now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0&lt;br /&gt;
&lt;br /&gt;
for i in range (0,len(new_img)):&lt;br /&gt;
    for j in range (0,len(new_img[0])):&lt;br /&gt;
        new_img[i][j]=-(new_img[i][j]-1)&lt;br /&gt;
       &lt;br /&gt;
x_mapa = np.linspace(-80,80,int(len(new_img[0])/1))&lt;br /&gt;
y_mapa = np.linspace(-80,80,int(len(new_img)/1))&lt;br /&gt;
&lt;br /&gt;
np.set_printoptions(threshold=sys.maxsize)&lt;br /&gt;
&lt;br /&gt;
sn.heatmap(new_img)&lt;br /&gt;
&lt;br /&gt;
xCOORDENADA_MAPA= x_mapa&lt;br /&gt;
yCOORDENADA_MAPA= y_mapa&lt;br /&gt;
MAPA_NUTRIENTE = new_img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4874</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4874"/>
		<updated>2021-05-24T14:20:13Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Mapa de Nutrientes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com os mesmos números horizontal e verticalmente- e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:OBRIGADO.png|200px|thumb|left|Figura 5: imagem de input para criação do mapa de nutrientes]]&lt;br /&gt;
[[Arquivo:Mapaonrigadp.png|200px|thumb|right|Figura 6: imagem de output para criação do mapa de nutrientes]]&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Mapaonrigadp.png&amp;diff=4873</id>
		<title>Arquivo:Mapaonrigadp.png</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Mapaonrigadp.png&amp;diff=4873"/>
		<updated>2021-05-24T14:18:01Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: output para nutriente&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;output para nutriente&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:OBRIGADO.png&amp;diff=4872</id>
		<title>Arquivo:OBRIGADO.png</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:OBRIGADO.png&amp;diff=4872"/>
		<updated>2021-05-24T14:15:44Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: input para nutriente&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;input para nutriente&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4871</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4871"/>
		<updated>2021-05-24T14:11:49Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Mapa de Nutrientes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com os mesmos números horizontal e verticalmente- e produz o mapa mostrado na '''Figura 5'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''mapa_unitario_nutri'' cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na '''Figura 9'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4870</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4870"/>
		<updated>2021-05-24T14:02:29Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Mapa de Nutrientes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Criação do mapa'''&lt;br /&gt;
Implementamos três formas de criar o mapa. A função ''mapa_nutri_Nhomogenea'' cria um mapa dependente de uma função que necessariamente deve começar a partir de 0, no caso da função mostrada é a função &amp;lt;math&amp;gt;(\sin(A^2+B^2))^2&amp;lt;/math&amp;gt;, ela recebe só uma variável para montar um mapa quadrado -com mesma quantidade de números horizontal e verticalmente-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def mapa_nutri_Nhomogenea(x):&lt;br /&gt;
  A,B=np.meshgrid(x,x)&lt;br /&gt;
  return (np.sin(np.sqrt(A**2+B**2))**2)&lt;br /&gt;
&lt;br /&gt;
def mapa_unitario_nutri(x):&lt;br /&gt;
  return (np.ones((len(x),len(x))))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4865</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4865"/>
		<updated>2021-05-24T13:54:24Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Mapa de Nutrientes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y'', o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Logo, é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está. Para isto usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4862</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4862"/>
		<updated>2021-05-24T13:49:29Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Mapa de Nutrientes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz ''X'' e ''Y''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo, logo é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está, para isso usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4860</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4860"/>
		<updated>2021-05-24T13:47:41Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Mapa de Nutrientes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente (Figura 4) é definido como uma matriz que armazena o valor de nutriente em cada ponto representado pela matriz ''X'' e ''Y''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|thumb|right|Figura 4: Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
MN = \left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
 \quad &lt;br /&gt;
X=Y= [\begin{matrix}-30 &amp;amp; 0 &amp;amp; 30\end{matrix}]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo, logo é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está, para isso usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4856</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4856"/>
		<updated>2021-05-24T13:37:34Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Mapa de Nutrientes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
Um mapa de nutriente é definido como uma matriz que armazena o valor de nutriente em cada espaço&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Nutri.png|300px|right|Exemplo de mapa de nutriente]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\left[\begin{matrix} 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783\\0.97620649 &amp;amp; 0 &amp;amp; 0.97620649 \\ 0.99977783 &amp;amp; 0.97620649 &amp;amp; 0.99977783 \end{matrix}\right]&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo, logo é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está, para isso usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Nutri.png&amp;diff=4855</id>
		<title>Arquivo:Nutri.png</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Nutri.png&amp;diff=4855"/>
		<updated>2021-05-24T13:23:42Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: Mapa de nutriente Fungos&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mapa de nutriente Fungos&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4854</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4854"/>
		<updated>2021-05-24T13:22:09Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Implementação */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fungo.jpg|250px|thumb|left|Figura 1: Ilustração da estrutura de um fungo. &amp;lt;ref name='PAULA'&amp;gt; P. L. Moraes. Fungos. Mundo Educação. Disponível em: https://mundoeducacao.uol.com.br/biologia/os-fungos.htm. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. Info Escola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Um dos grandes obstáculos com a programação de um modelo biológico com variáveis discretas é o processamento de grandes quantidades de dados. Conforme o tempo de simulação aumenta e as redes de hifas se tornam maiores e mais complexas, a quantidade de informação processada aumenta exponencialmente e, devido a esse fato, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional (como a ramificação lateral e a translocação). No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Como comentado anteriormente, a concentração de substrato (nutrientes) presente no local da ponta da hifa irá determinar se a expansão da mesma irá ocorrer ou não. Por isso, computacionalmente, a extensão das hifas é modelada de maneira que a concentração de nutrientes na ponta de um hifa arbitrária é checada e, caso haja substrato o suficiente (é determinado um limiar de acordo com a espécie de fungo), o crescimento da hifa segue adiante, caso contrário ele permanece estagnado. Além disso, a orientação do ângulo de crescimento é dependente da orientação inicial da hifa e de um fator aleatório dependente da espécie a ser analisada.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
===Divisão e Anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si. Computacionalmente e de maneira similar ao crescimento, as divisões também dependem da quantidade de nutrientes presentes no local de possível ramificação e - além disso - dependem de um fator de ângulo aleatório dependente da espécie simulada. A anastomose, por outro lado, possui uma programação mais complexa e utiliza o método de intersecção de linhas, que será mais aprofundado na próxima seção.&lt;br /&gt;
&lt;br /&gt;
== Formulação Matemática e Implementação ==&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos aspectos fundamentais de uma simulação de micélio de fungos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de Linhas e Anastomose===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutrientes===&lt;br /&gt;
&lt;br /&gt;
O mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo, logo é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está, para isso usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discussão de Resultados ==&lt;br /&gt;
Após a implementação bem sucedida dos códigos listados na seção anterior, foi possível plotar os resultados obtidos através do programa e analisá-los.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 7: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 8: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
== Conclusão ==&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4817</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4817"/>
		<updated>2021-05-24T03:34:21Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Mapa de Nutriente */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:micelioo.jpeg|250px|thumb|left|Figura 1: Representação computacional de um micélio fungoso.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. InfoEscola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Devido à grande complexidade e exigência computacional, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional. No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Divisão e anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si.&lt;br /&gt;
&lt;br /&gt;
== Construção do modelo computacional ==&lt;br /&gt;
''Branching na ponta / Computar só os da ponta / Crescimento ocorre só com o nutriente que o ponto final está''&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos três aspectos fundamentais de uma simulação de micélio de fungos:&lt;br /&gt;
&lt;br /&gt;
=== Ramificação nas pontas ===&lt;br /&gt;
&lt;br /&gt;
=== Extensão/Crescimento ===&lt;br /&gt;
&lt;br /&gt;
=== Mapa de Nutrientes ===&lt;br /&gt;
&lt;br /&gt;
=== Anastomose ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementação ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de linhas===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutriente===&lt;br /&gt;
&lt;br /&gt;
O mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo, logo é necessário encontrar em qual &amp;quot;quadrado&amp;quot; de nutriente a posição do final da hifa está, para isso usa-se uma função (''find_nearest'') que encontra o valor mais próximo de ''x'' e ''y'' no ''array'' que representa o mapa de nutriente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Portanto, a função ''check_nutri'' que retorna a quantidade de nutrientes disponível utiliza a ''find_nearest'' para encontrar o index do ponto que é também o do nutriente no ponto na matriz ''mapa_nutri'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A função ''atualiza_mapa_nutri'' funciona de maneira similar a ''check_nutri'' porém essa recebe recebe também a variável ''preco'' que representa o custo de uma ação. Para nossa situação as únicas situações que custam nutrientes são o crescimento e a divisão, 0.01 e 0.3 respectivamente. A função então retorna o mapa de nutriente atualizado:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4816</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4816"/>
		<updated>2021-05-24T03:19:53Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Implementação */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:micelioo.jpeg|250px|thumb|left|Figura 1: Representação computacional de um micélio fungoso.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. InfoEscola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Devido à grande complexidade e exigência computacional, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional. No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Divisão e anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si.&lt;br /&gt;
&lt;br /&gt;
== Construção do modelo computacional ==&lt;br /&gt;
''Branching na ponta / Computar só os da ponta / Crescimento ocorre só com o nutriente que o ponto final está''&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos três aspectos fundamentais de uma simulação de micélio de fungos:&lt;br /&gt;
&lt;br /&gt;
=== Ramificação nas pontas ===&lt;br /&gt;
&lt;br /&gt;
=== Extensão/Crescimento ===&lt;br /&gt;
&lt;br /&gt;
=== Mapa de Nutrientes ===&lt;br /&gt;
&lt;br /&gt;
=== Anastomose ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementação ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de linhas===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutriente===&lt;br /&gt;
&lt;br /&gt;
O mapa de nutrientes implementado foi um mapa discreto, ao contrário do atigo &amp;lt;ref name=Hopkins&amp;gt;&amp;lt;/ref&amp;gt; que implementou um mapa contínuo, logo ele relaciona a posição do final da hifa. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4813</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4813"/>
		<updated>2021-05-24T02:13:55Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Intersecção de linhas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:micelioo.jpeg|250px|thumb|left|Figura 1: Representação computacional de um micélio fungoso.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. InfoEscola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Devido à grande complexidade e exigência computacional, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional. No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Divisão e anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si.&lt;br /&gt;
&lt;br /&gt;
== Construção do modelo computacional ==&lt;br /&gt;
''Branching na ponta / Computar só os da ponta / Crescimento ocorre só com o nutriente que o ponto final está''&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos três aspectos fundamentais de uma simulação de micélio de fungos:&lt;br /&gt;
&lt;br /&gt;
=== Ramificação nas pontas ===&lt;br /&gt;
&lt;br /&gt;
=== Extensão/Crescimento ===&lt;br /&gt;
&lt;br /&gt;
=== Mapa de Nutrientes ===&lt;br /&gt;
&lt;br /&gt;
=== Anastomose ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementação ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de linhas===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutriente===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4812</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4812"/>
		<updated>2021-05-24T02:13:13Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Intersecção de linhas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:micelioo.jpeg|250px|thumb|left|Figura 1: Representação computacional de um micélio fungoso.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. InfoEscola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Devido à grande complexidade e exigência computacional, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional. No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Divisão e anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si.&lt;br /&gt;
&lt;br /&gt;
== Construção do modelo computacional ==&lt;br /&gt;
''Branching na ponta / Computar só os da ponta / Crescimento ocorre só com o nutriente que o ponto final está''&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos três aspectos fundamentais de uma simulação de micélio de fungos:&lt;br /&gt;
&lt;br /&gt;
=== Ramificação nas pontas ===&lt;br /&gt;
&lt;br /&gt;
=== Extensão/Crescimento ===&lt;br /&gt;
&lt;br /&gt;
=== Mapa de Nutrientes ===&lt;br /&gt;
&lt;br /&gt;
=== Anastomose ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementação ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de linhas===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trata-se as linhas como uma curva de Bézier de primeiro grau:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Onde &amp;lt;math&amp;gt;U_a&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;U_b&amp;lt;/math&amp;gt; são números reais definidos como:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
and&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
&lt;br /&gt;
E o ponto de intersecção:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutriente===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4811</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4811"/>
		<updated>2021-05-24T02:08:39Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Intersecção de linhas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:micelioo.jpeg|250px|thumb|left|Figura 1: Representação computacional de um micélio fungoso.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. InfoEscola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Devido à grande complexidade e exigência computacional, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional. No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Divisão e anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si.&lt;br /&gt;
&lt;br /&gt;
== Construção do modelo computacional ==&lt;br /&gt;
''Branching na ponta / Computar só os da ponta / Crescimento ocorre só com o nutriente que o ponto final está''&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos três aspectos fundamentais de uma simulação de micélio de fungos:&lt;br /&gt;
&lt;br /&gt;
=== Ramificação nas pontas ===&lt;br /&gt;
&lt;br /&gt;
=== Extensão/Crescimento ===&lt;br /&gt;
&lt;br /&gt;
=== Mapa de Nutrientes ===&lt;br /&gt;
&lt;br /&gt;
=== Anastomose ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementação ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de linhas===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
and&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os primeiros dois ''if''s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que ''flag = False'', o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a ''get_intersection_point'' para encontrar o ponto:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutriente===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4810</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4810"/>
		<updated>2021-05-24T02:01:23Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Intersecção de linhas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:micelioo.jpeg|250px|thumb|left|Figura 1: Representação computacional de um micélio fungoso.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. InfoEscola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Devido à grande complexidade e exigência computacional, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional. No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Divisão e anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si.&lt;br /&gt;
&lt;br /&gt;
== Construção do modelo computacional ==&lt;br /&gt;
''Branching na ponta / Computar só os da ponta / Crescimento ocorre só com o nutriente que o ponto final está''&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos três aspectos fundamentais de uma simulação de micélio de fungos:&lt;br /&gt;
&lt;br /&gt;
=== Ramificação nas pontas ===&lt;br /&gt;
&lt;br /&gt;
=== Extensão/Crescimento ===&lt;br /&gt;
&lt;br /&gt;
=== Mapa de Nutrientes ===&lt;br /&gt;
&lt;br /&gt;
=== Anastomose ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementação ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de linhas===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
and&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se &amp;lt;math&amp;gt;0 \leqslant U_a \leqslant 1 &amp;lt;/math&amp;gt;, e cai dentro do segmento da segunda linha se &amp;lt;math&amp;gt;0 \leqslant U_b \leqslant 1 &amp;lt;/math&amp;gt;. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se há cruzamento: o ponto final da hifa é o ponto de intersecção entre as retas e ela não pode mais crescer ou dividir.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se não há cruzamento: a hifa pode continuar a crescer e se dividir normalmente.&lt;br /&gt;
&lt;br /&gt;
Devemos tomar cuidado para o algoritmo não identificar a hifa a qual esta foi originada como intersecção!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Após se encontrar usa a func:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutriente===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4809</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4809"/>
		<updated>2021-05-24T01:59:36Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Intersecção de linhas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:micelioo.jpeg|250px|thumb|left|Figura 1: Representação computacional de um micélio fungoso.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. InfoEscola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Devido à grande complexidade e exigência computacional, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional. No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Divisão e anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si.&lt;br /&gt;
&lt;br /&gt;
== Construção do modelo computacional ==&lt;br /&gt;
''Branching na ponta / Computar só os da ponta / Crescimento ocorre só com o nutriente que o ponto final está''&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos três aspectos fundamentais de uma simulação de micélio de fungos:&lt;br /&gt;
&lt;br /&gt;
=== Ramificação nas pontas ===&lt;br /&gt;
&lt;br /&gt;
=== Extensão/Crescimento ===&lt;br /&gt;
&lt;br /&gt;
=== Mapa de Nutrientes ===&lt;br /&gt;
&lt;br /&gt;
=== Anastomose ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementação ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de linhas===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
and&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se 0.0&amp;amp;nbsp;≤&amp;amp;nbsp; ''U_a'' &amp;amp;nbsp;≤&amp;amp;nbsp;1.0, e cai dentro do segmento da segunda linha se 0.0&amp;amp;nbsp;≤&amp;amp;nbsp;''U_b'' &amp;amp;nbsp;≤&amp;amp;nbsp;1.0. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se  &amp;lt;math&amp;gt;0 \leqslant P_x \leqslant 1 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;0 \leqslant P_y \leqslant 1 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se há cruzamento: o ponto final da hifa é o ponto de intersecção entre as retas e ela não pode mais crescer ou dividir.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se não há cruzamento: a hifa pode continuar a crescer e se dividir normalmente.&lt;br /&gt;
&lt;br /&gt;
Devemos tomar cuidado para o algoritmo não identificar a hifa a qual esta foi originada como intersecção!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Após se encontrar usa a func:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutriente===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4808</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4808"/>
		<updated>2021-05-24T01:58:30Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Intersecção de linhas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:micelioo.jpeg|250px|thumb|left|Figura 1: Representação computacional de um micélio fungoso.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. InfoEscola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Devido à grande complexidade e exigência computacional, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional. No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Divisão e anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si.&lt;br /&gt;
&lt;br /&gt;
== Construção do modelo computacional ==&lt;br /&gt;
''Branching na ponta / Computar só os da ponta / Crescimento ocorre só com o nutriente que o ponto final está''&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos três aspectos fundamentais de uma simulação de micélio de fungos:&lt;br /&gt;
&lt;br /&gt;
=== Ramificação nas pontas ===&lt;br /&gt;
&lt;br /&gt;
=== Extensão/Crescimento ===&lt;br /&gt;
&lt;br /&gt;
=== Mapa de Nutrientes ===&lt;br /&gt;
&lt;br /&gt;
=== Anastomose ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementação ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de linhas===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
and&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + U_a (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + U_b (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se 0.0&amp;amp;nbsp;≤&amp;amp;nbsp; &amp;lt;math&amp;gt;U_a&amp;lt;\math&amp;gt; &amp;amp;nbsp;≤&amp;amp;nbsp;1.0, e cai dentro do segmento da segunda linha se 0.0&amp;amp;nbsp;≤&amp;amp;nbsp;&amp;lt;math&amp;gt;U_b&amp;lt;\math&amp;gt; &amp;amp;nbsp;≤&amp;amp;nbsp;1.0. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se  &amp;lt;math&amp;gt;0 \leqslant P_x \leqslant 1 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;0 \leqslant P_y \leqslant 1 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se há cruzamento: o ponto final da hifa é o ponto de intersecção entre as retas e ela não pode mais crescer ou dividir.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se não há cruzamento: a hifa pode continuar a crescer e se dividir normalmente.&lt;br /&gt;
&lt;br /&gt;
Devemos tomar cuidado para o algoritmo não identificar a hifa a qual esta foi originada como intersecção!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Após se encontrar usa a func:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutriente===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4807</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4807"/>
		<updated>2021-05-24T01:54:11Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Intersecção de linhas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:micelioo.jpeg|250px|thumb|left|Figura 1: Representação computacional de um micélio fungoso.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. InfoEscola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Devido à grande complexidade e exigência computacional, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional. No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Divisão e anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si.&lt;br /&gt;
&lt;br /&gt;
== Construção do modelo computacional ==&lt;br /&gt;
''Branching na ponta / Computar só os da ponta / Crescimento ocorre só com o nutriente que o ponto final está''&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos três aspectos fundamentais de uma simulação de micélio de fungos:&lt;br /&gt;
&lt;br /&gt;
=== Ramificação nas pontas ===&lt;br /&gt;
&lt;br /&gt;
=== Extensão/Crescimento ===&lt;br /&gt;
&lt;br /&gt;
=== Mapa de Nutrientes ===&lt;br /&gt;
&lt;br /&gt;
=== Anastomose ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementação ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de linhas===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + U_a \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + U_b \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_a = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
and&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
U_b = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + t (x_2-x_1),\; y_1 + U_a (y_2-y_1)) \quad \text{ou} \quad (P_x, P_y) = (x_3 + u (x_4-x_3),\; y_3 + U_b (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O ponto de interseção cai dentro do segmento da primeira linha se 0,0 &amp;amp; nbsp; ≤ &amp;amp; nbsp; '' &amp;lt;math&amp;gt;U_a&amp;lt;\math&amp;gt; '' &amp;amp; nbsp; ≤ &amp;amp; nbsp; 1,0 e cai dentro do segmento da segunda linha se 0,0 &amp;amp; nbsp; ≤ &amp;amp; nbsp; '' &amp;lt;math&amp;gt;U_b&amp;lt;\math&amp;gt; '' &amp;amp; nbsp; ≤ &amp;amp; nbsp; 1,0. &amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se  &amp;lt;math&amp;gt;0 \leqslant P_x \leqslant 1 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;0 \leqslant P_y \leqslant 1 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se há cruzamento: o ponto final da hifa é o ponto de intersecção entre as retas e ela não pode mais crescer ou dividir.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se não há cruzamento: a hifa pode continuar a crescer e se dividir normalmente.&lt;br /&gt;
&lt;br /&gt;
Devemos tomar cuidado para o algoritmo não identificar a hifa a qual esta foi originada como intersecção!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Após se encontrar usa a func:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutriente===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4806</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4806"/>
		<updated>2021-05-24T01:45:38Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Crescimento */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:micelioo.jpeg|250px|thumb|left|Figura 1: Representação computacional de um micélio fungoso.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. InfoEscola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Devido à grande complexidade e exigência computacional, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional. No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação média de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Divisão e anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si.&lt;br /&gt;
&lt;br /&gt;
== Construção do modelo computacional ==&lt;br /&gt;
''Branching na ponta / Computar só os da ponta / Crescimento ocorre só com o nutriente que o ponto final está''&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos três aspectos fundamentais de uma simulação de micélio de fungos:&lt;br /&gt;
&lt;br /&gt;
=== Ramificação nas pontas ===&lt;br /&gt;
&lt;br /&gt;
=== Extensão/Crescimento ===&lt;br /&gt;
&lt;br /&gt;
=== Mapa de Nutrientes ===&lt;br /&gt;
&lt;br /&gt;
=== Anastomose ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementação ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de linhas===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + t \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + u \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(where ''t'' and ''u'' are real numbers). The intersection point of the lines is found with one of the following values of ''t'' or ''u'', where&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
t = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
and&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
u = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + t (x_2-x_1),\; y_1 + t (y_2-y_1)) \quad \text{or} \quad (P_x, P_y) = (x_3 + u (x_4-x_3),\; y_3 + u (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The intersection point falls within the first line segment if 0.0&amp;amp;nbsp;≤&amp;amp;nbsp;''t''&amp;amp;nbsp;≤&amp;amp;nbsp;1.0, and it falls within the second line segment if 0.0&amp;amp;nbsp;≤&amp;amp;nbsp;''u''&amp;amp;nbsp;≤&amp;amp;nbsp;1.0. These inequalities can be tested without need for division, allowing rapid determination of the existence of any line segment intersection before calculating its exact point.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se  &amp;lt;math&amp;gt;0 \leqslant P_x \leqslant 1 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;0 \leqslant P_y \leqslant 1 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se há cruzamento: o ponto final da hifa é o ponto de intersecção entre as retas e ela não pode mais crescer ou dividir.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se não há cruzamento: a hifa pode continuar a crescer e se dividir normalmente.&lt;br /&gt;
&lt;br /&gt;
Devemos tomar cuidado para o algoritmo não identificar a hifa a qual esta foi originada como intersecção!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Após se encontrar usa a func:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutriente===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4805</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4805"/>
		<updated>2021-05-24T01:41:31Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Intersecção de linhas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:micelioo.jpeg|250px|thumb|left|Figura 1: Representação computacional de um micélio fungoso.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. InfoEscola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Devido à grande complexidade e exigência computacional, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional. No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Divisão e anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente no processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si.&lt;br /&gt;
&lt;br /&gt;
== Construção do modelo computacional ==&lt;br /&gt;
''Branching na ponta / Computar só os da ponta / Crescimento ocorre só com o nutriente que o ponto final está''&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos três aspectos fundamentais de uma simulação de micélio de fungos:&lt;br /&gt;
&lt;br /&gt;
=== Ramificação nas pontas ===&lt;br /&gt;
&lt;br /&gt;
=== Extensão/Crescimento ===&lt;br /&gt;
&lt;br /&gt;
=== Mapa de Nutrientes ===&lt;br /&gt;
&lt;br /&gt;
=== Anastomose ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementação ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de linhas===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; se intersectam calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
L_1 =   \begin{bmatrix}x_1     \\ y_1\end{bmatrix}&lt;br /&gt;
    + t \begin{bmatrix}x_2-x_1 \\ y_2-y_1\end{bmatrix},&lt;br /&gt;
\qquad&lt;br /&gt;
L_2 =   \begin{bmatrix}x_3     \\ y_3\end{bmatrix}&lt;br /&gt;
    + u \begin{bmatrix}x_4-x_3 \\ y_4-y_3\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(where ''t'' and ''u'' are real numbers). The intersection point of the lines is found with one of the following values of ''t'' or ''u'', where&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
t = \frac{\begin{vmatrix} x_1-x_3 &amp;amp; x_3-x_4\\y_1-y_3 &amp;amp; y_3-y_4\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_1 - x_3)(y_3-y_4)-(y_1-y_3)(x_3-x_4)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
and&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
u = \frac{\begin{vmatrix} x_2-x_1 &amp;amp; x_1-x_3\\y_2-y_1 &amp;amp; y_1-y_3\end{vmatrix}}{\begin{vmatrix} x_1-x_2 &amp;amp; x_3-x_4\\y_1-y_2 &amp;amp; y_3-y_4\end{vmatrix}} = \frac{(x_2 - x_1)(y_1-y_3)-(y_2-y_1)(x_1-x_3)}{(x_1-x_2)(y_3-y_4)-(y_1-y_2)(x_3-x_4)},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
with:&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
(P_x, P_y)= (x_1 + t (x_2-x_1),\; y_1 + t (y_2-y_1)) \quad \text{or} \quad (P_x, P_y) = (x_3 + u (x_4-x_3),\; y_3 + u (y_4-y_3))&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The intersection point falls within the first line segment if 0.0&amp;amp;nbsp;≤&amp;amp;nbsp;''t''&amp;amp;nbsp;≤&amp;amp;nbsp;1.0, and it falls within the second line segment if 0.0&amp;amp;nbsp;≤&amp;amp;nbsp;''u''&amp;amp;nbsp;≤&amp;amp;nbsp;1.0. These inequalities can be tested without need for division, allowing rapid determination of the existence of any line segment intersection before calculating its exact point.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se  &amp;lt;math&amp;gt;0 \leqslant P_x \leqslant 1 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;0 \leqslant P_y \leqslant 1 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se há cruzamento: o ponto final da hifa é o ponto de intersecção entre as retas e ela não pode mais crescer ou dividir.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se não há cruzamento: a hifa pode continuar a crescer e se dividir normalmente.&lt;br /&gt;
&lt;br /&gt;
Devemos tomar cuidado para o algoritmo não identificar a hifa a qual esta foi originada como intersecção!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Após se encontrar usa a func:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutriente===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4801</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4801"/>
		<updated>2021-05-24T01:12:27Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Intersecção de linhas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:micelioo.jpeg|250px|thumb|left|Figura 1: Representação computacional de um micélio fungoso.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. InfoEscola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Devido à grande complexidade e exigência computacional, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional. No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Divisão e anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente o processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si.&lt;br /&gt;
&lt;br /&gt;
== Construção do modelo computacional ==&lt;br /&gt;
''Branching na ponta / Computar só os da ponta / Crescimento ocorre só com o nutriente que o ponto final está''&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos três aspectos fundamentais de uma simulação de micélio de fungos:&lt;br /&gt;
&lt;br /&gt;
=== Ramificação nas pontas ===&lt;br /&gt;
&lt;br /&gt;
=== Extensão/Crescimento ===&lt;br /&gt;
&lt;br /&gt;
=== Mapa de Nutrientes ===&lt;br /&gt;
&lt;br /&gt;
=== Anastomose ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementação ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de linhas===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, podemos descobrir se a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt; calculando as seguintes equações matriciais:&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
U_x = \begin{vmatrix} \begin{vmatrix} x_1 &amp;amp; y_1\\x_2 &amp;amp; y_2\end{vmatrix} &amp;amp;  \begin{vmatrix} x_1 &amp;amp; 1\\x_2 &amp;amp; 1\end{vmatrix} \\\\ \begin{vmatrix} x_3 &amp;amp; y_3\\x_4 &amp;amp; y_4\end{vmatrix} &amp;amp; \begin{vmatrix} x_3 &amp;amp; 1\\x_4 &amp;amp; 1\end{vmatrix} \end{vmatrix} \,\! ;&lt;br /&gt;
\qquad&lt;br /&gt;
&lt;br /&gt;
U_y = \begin{vmatrix} \begin{vmatrix} x_1 &amp;amp; y_1\\x_2 &amp;amp; y_2\end{vmatrix} &amp;amp;  \begin{vmatrix} y_1 &amp;amp; 1\\y_2 &amp;amp; 1\end{vmatrix} \\\\ \begin{vmatrix} x_3 &amp;amp; y_3\\x_4 &amp;amp; y_4\end{vmatrix} &amp;amp; \begin{vmatrix} y_3 &amp;amp; 1\\y_4 &amp;amp; 1\end{vmatrix} \end{vmatrix} \,\!;&lt;br /&gt;
\qquad&lt;br /&gt;
&lt;br /&gt;
D = \begin{vmatrix} \begin{vmatrix} x_1 &amp;amp; 1\\x_2 &amp;amp; 1\end{vmatrix} &amp;amp;  \begin{vmatrix} y_1 &amp;amp; 1\\y_2 &amp;amp; 1\end{vmatrix} \\\\ \begin{vmatrix} x_3 &amp;amp; 1\\x_4 &amp;amp; 1\end{vmatrix} &amp;amp; \begin{vmatrix} y_3 &amp;amp; 1\\y_4 &amp;amp; 1\end{vmatrix} \end{vmatrix}\,\!;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P_x=\frac{U_x}{D};\qquad&lt;br /&gt;
P_y=\frac{U_y}{D}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quando duas linhas são paralelas ou coincidentes, o D é igual a zero, o que acarreta em uma divisão por zero. Portanto, problemas numéricos podem ocorrer se as linhas forem quase paralelas.&amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se há cruzamento: o ponto final da hifa é o ponto de intersecção entre as retas e ela não pode mais crescer ou dividir.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se não há cruzamento: a hifa pode continuar a crescer e se dividir normalmente.&lt;br /&gt;
&lt;br /&gt;
Devemos tomar cuidado para o algoritmo não identificar a hifa a qual esta foi originada como intersecção!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Após se encontrar usa a func:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutriente===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4799</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4799"/>
		<updated>2021-05-24T01:06:37Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Intersecção de linhas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:micelioo.jpeg|250px|thumb|left|Figura 1: Representação computacional de um micélio fungoso.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. InfoEscola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Devido à grande complexidade e exigência computacional, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional. No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Divisão e anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente o processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si.&lt;br /&gt;
&lt;br /&gt;
== Construção do modelo computacional ==&lt;br /&gt;
''Branching na ponta / Computar só os da ponta / Crescimento ocorre só com o nutriente que o ponto final está''&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos três aspectos fundamentais de uma simulação de micélio de fungos:&lt;br /&gt;
&lt;br /&gt;
=== Ramificação nas pontas ===&lt;br /&gt;
&lt;br /&gt;
=== Extensão/Crescimento ===&lt;br /&gt;
&lt;br /&gt;
=== Mapa de Nutrientes ===&lt;br /&gt;
&lt;br /&gt;
=== Anastomose ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementação ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de linhas===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
A interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; pode ser definida utilizando determinantes dados dois pontos em cada linha. Portanto, a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; sendo definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; sendo definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt;.&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The intersection &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; of line &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt; can be defined using [[determinant]]s.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se há cruzamento: o ponto final da hifa é o ponto de intersecção entre as retas e ela não pode mais crescer ou dividir.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
U_x = \begin{vmatrix} \begin{vmatrix} x_1 &amp;amp; y_1\\x_2 &amp;amp; y_2\end{vmatrix} &amp;amp;  \begin{vmatrix} x_1 &amp;amp; 1\\x_2 &amp;amp; 1\end{vmatrix} \\\\ \begin{vmatrix} x_3 &amp;amp; y_3\\x_4 &amp;amp; y_4\end{vmatrix} &amp;amp; \begin{vmatrix} x_3 &amp;amp; 1\\x_4 &amp;amp; 1\end{vmatrix} \end{vmatrix} \,\! ;&lt;br /&gt;
\qquad&lt;br /&gt;
&lt;br /&gt;
U_y = \begin{vmatrix} \begin{vmatrix} x_1 &amp;amp; y_1\\x_2 &amp;amp; y_2\end{vmatrix} &amp;amp;  \begin{vmatrix} y_1 &amp;amp; 1\\y_2 &amp;amp; 1\end{vmatrix} \\\\ \begin{vmatrix} x_3 &amp;amp; y_3\\x_4 &amp;amp; y_4\end{vmatrix} &amp;amp; \begin{vmatrix} y_3 &amp;amp; 1\\y_4 &amp;amp; 1\end{vmatrix} \end{vmatrix} \,\!;&lt;br /&gt;
\qquad&lt;br /&gt;
&lt;br /&gt;
D = \begin{vmatrix} \begin{vmatrix} x_1 &amp;amp; 1\\x_2 &amp;amp; 1\end{vmatrix} &amp;amp;  \begin{vmatrix} y_1 &amp;amp; 1\\y_2 &amp;amp; 1\end{vmatrix} \\\\ \begin{vmatrix} x_3 &amp;amp; 1\\x_4 &amp;amp; 1\end{vmatrix} &amp;amp; \begin{vmatrix} y_3 &amp;amp; 1\\y_4 &amp;amp; 1\end{vmatrix} \end{vmatrix}\,\!;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P_x=\frac{U_x}{D};\qquad&lt;br /&gt;
P_y=\frac{U_y}{D}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quando duas linhas são paralelas ou coincidentes, o D é igual a zero. Se as linhas forem quase paralelas uma computacional pode encontrar problemas numéricos ao implementar.&amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se não há cruzamento: a hifa pode continuar a crescer e se dividir normalmente.&lt;br /&gt;
&lt;br /&gt;
Devemos tomar cuidado para o algoritmo não identificar a hifa a qual esta foi originada como intersecção!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Após se encontrar usa a func:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutriente===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4797</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4797"/>
		<updated>2021-05-24T01:01:55Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Intersecção de linhas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:micelioo.jpeg|250px|thumb|left|Figura 1: Representação computacional de um micélio fungoso.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. InfoEscola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Devido à grande complexidade e exigência computacional, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional. No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Divisão e anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente o processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si.&lt;br /&gt;
&lt;br /&gt;
== Construção do modelo computacional ==&lt;br /&gt;
''Branching na ponta / Computar só os da ponta / Crescimento ocorre só com o nutriente que o ponto final está''&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos três aspectos fundamentais de uma simulação de micélio de fungos:&lt;br /&gt;
&lt;br /&gt;
=== Ramificação nas pontas ===&lt;br /&gt;
&lt;br /&gt;
=== Extensão/Crescimento ===&lt;br /&gt;
&lt;br /&gt;
=== Mapa de Nutrientes ===&lt;br /&gt;
&lt;br /&gt;
=== Anastomose ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementação ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de linhas===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
Considerando a interseção &amp;lt;math&amp;gt;P=\{P_x,P_y\}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt;, com  a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; sendo definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; sendo definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt;.&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se há cruzamento: o ponto final da hifa é o ponto de intersecção entre as retas e ela não pode mais crescer ou dividir.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
U_x = \begin{vmatrix} \begin{vmatrix} x_1 &amp;amp; y_1\\x_2 &amp;amp; y_2\end{vmatrix} &amp;amp;  \begin{vmatrix} x_1 &amp;amp; 1\\x_2 &amp;amp; 1\end{vmatrix} \\\\ \begin{vmatrix} x_3 &amp;amp; y_3\\x_4 &amp;amp; y_4\end{vmatrix} &amp;amp; \begin{vmatrix} x_3 &amp;amp; 1\\x_4 &amp;amp; 1\end{vmatrix} \end{vmatrix} \,\! ;&lt;br /&gt;
\qquad&lt;br /&gt;
&lt;br /&gt;
U_y = \begin{vmatrix} \begin{vmatrix} x_1 &amp;amp; y_1\\x_2 &amp;amp; y_2\end{vmatrix} &amp;amp;  \begin{vmatrix} y_1 &amp;amp; 1\\y_2 &amp;amp; 1\end{vmatrix} \\\\ \begin{vmatrix} x_3 &amp;amp; y_3\\x_4 &amp;amp; y_4\end{vmatrix} &amp;amp; \begin{vmatrix} y_3 &amp;amp; 1\\y_4 &amp;amp; 1\end{vmatrix} \end{vmatrix} \,\!;&lt;br /&gt;
\qquad&lt;br /&gt;
&lt;br /&gt;
D = \begin{vmatrix} \begin{vmatrix} x_1 &amp;amp; 1\\x_2 &amp;amp; 1\end{vmatrix} &amp;amp;  \begin{vmatrix} y_1 &amp;amp; 1\\y_2 &amp;amp; 1\end{vmatrix} \\\\ \begin{vmatrix} x_3 &amp;amp; 1\\x_4 &amp;amp; 1\end{vmatrix} &amp;amp; \begin{vmatrix} y_3 &amp;amp; 1\\y_4 &amp;amp; 1\end{vmatrix} \end{vmatrix}\,\!;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P_x=\frac{U_x}{D};\qquad&lt;br /&gt;
P_y=\frac{U_y}{D}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quando duas linhas são paralelas ou coincidentes, o D é igual a zero. Se as linhas forem quase paralelas uma computacional pode encontrar problemas numéricos ao implementar.&amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se não há cruzamento: a hifa pode continuar a crescer e se dividir normalmente.&lt;br /&gt;
&lt;br /&gt;
Devemos tomar cuidado para o algoritmo não identificar a hifa a qual esta foi originada como intersecção!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Após se encontrar usa a func:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutriente===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4794</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4794"/>
		<updated>2021-05-24T00:58:09Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Intersecção de linhas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:micelioo.jpeg|250px|thumb|left|Figura 1: Representação computacional de um micélio fungoso.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. InfoEscola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Devido à grande complexidade e exigência computacional, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional. No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Divisão e anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente o processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si.&lt;br /&gt;
&lt;br /&gt;
== Construção do modelo computacional ==&lt;br /&gt;
''Branching na ponta / Computar só os da ponta / Crescimento ocorre só com o nutriente que o ponto final está''&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos três aspectos fundamentais de uma simulação de micélio de fungos:&lt;br /&gt;
&lt;br /&gt;
=== Ramificação nas pontas ===&lt;br /&gt;
&lt;br /&gt;
=== Extensão/Crescimento ===&lt;br /&gt;
&lt;br /&gt;
=== Mapa de Nutrientes ===&lt;br /&gt;
&lt;br /&gt;
=== Anastomose ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementação ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de linhas===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
Considerando a interseção &amp;lt;math&amp;gt;P={P_x,P_y}&amp;lt;/math&amp;gt; de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt;, com  a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; sendo definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; sendo definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt;.&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se há cruzamento: o ponto final da hifa é o ponto de intersecção entre as retas e ela não pode mais crescer ou dividir.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
U_x = \begin{vmatrix} \begin{vmatrix} x_1 &amp;amp; y_1\\x_2 &amp;amp; y_2\end{vmatrix} &amp;amp;  \begin{vmatrix} x_1 &amp;amp; 1\\x_2 &amp;amp; 1\end{vmatrix} \\\\ \begin{vmatrix} x_3 &amp;amp; y_3\\x_4 &amp;amp; y_4\end{vmatrix} &amp;amp; \begin{vmatrix} x_3 &amp;amp; 1\\x_4 &amp;amp; 1\end{vmatrix} \end{vmatrix} \,\! ;&lt;br /&gt;
\qquad&lt;br /&gt;
&lt;br /&gt;
U_y = \begin{vmatrix} \begin{vmatrix} x_1 &amp;amp; y_1\\x_2 &amp;amp; y_2\end{vmatrix} &amp;amp;  \begin{vmatrix} y_1 &amp;amp; 1\\y_2 &amp;amp; 1\end{vmatrix} \\\\ \begin{vmatrix} x_3 &amp;amp; y_3\\x_4 &amp;amp; y_4\end{vmatrix} &amp;amp; \begin{vmatrix} y_3 &amp;amp; 1\\y_4 &amp;amp; 1\end{vmatrix} \end{vmatrix} \,\!;&lt;br /&gt;
\qquad&lt;br /&gt;
&lt;br /&gt;
D = \begin{vmatrix} \begin{vmatrix} x_1 &amp;amp; 1\\x_2 &amp;amp; 1\end{vmatrix} &amp;amp;  \begin{vmatrix} y_1 &amp;amp; 1\\y_2 &amp;amp; 1\end{vmatrix} \\\\ \begin{vmatrix} x_3 &amp;amp; 1\\x_4 &amp;amp; 1\end{vmatrix} &amp;amp; \begin{vmatrix} y_3 &amp;amp; 1\\y_4 &amp;amp; 1\end{vmatrix} \end{vmatrix}\,\!;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P_x=\frac{U_x}{D};\qquad&lt;br /&gt;
P_y=\frac{U_y}{D}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quando duas linhas são paralelas ou coincidentes, o D é igual a zero. Se as linhas forem quase paralelas uma computacional pode encontrar problemas numéricos ao implementar.&amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se não há cruzamento: a hifa pode continuar a crescer e se dividir normalmente.&lt;br /&gt;
&lt;br /&gt;
Devemos tomar cuidado para o algoritmo não identificar a hifa a qual esta foi originada como intersecção!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Após se encontrar usa a func:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutriente===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4793</id>
		<title>Simulação de Micélio de Fungo</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=4793"/>
		<updated>2021-05-24T00:56:39Z</updated>

		<summary type="html">&lt;p&gt;Brunoztemp: /* Intersecção de linhas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss'''&lt;br /&gt;
&lt;br /&gt;
O objetivo deste trabalho é modelar computacionalmente o desenvolvimento de micélios em fungos com base em mecanismos gerais pré-estabelecidos. O progresso e a complexidade dos modelos cresceram de maneira gradual ao longo do trabalho através de três modelos de crescimento diferentes. O trabalho foi inspirado - principalmente - nos dois primeiros capítulos do artigo de Steven Hopkins &amp;lt;ref name='HOPKINS'&amp;gt;S. Hopkins. A Hybrid Mathematical Model of Fungal Mycelia: Tropisms, Polarised Growth and Application to Colony Competition, tese de doutorado, 2011.(https://core.ac.uk/download/pdf/6117416.pdf) &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Motivação e Introdução aos Fungos ==&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:micelioo.jpeg|250px|thumb|left|Figura 1: Representação computacional de um micélio fungoso.]]&lt;br /&gt;
[[Arquivo:ramifica.png|250px|thumb|right|Figura 2: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (''Dichotomous'') e à direita o processo de ramificação lateral &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos estão integrados em grande parte dos ecossistemas do planeta e cumprem importantes funções na manutenção e sobrevivência dos mesmos. De maneira geral, eles produzem enzimas que são responsáveis pela decomposição de matéria orgânica e - portanto - a reciclagem de diversos nutrientes do ambiente ao seu redor &amp;lt;ref name='SILVA'&amp;gt; P. da Silva. Reino Fungi. InfoEscola (2018). Disponível em: https://www.infoescola.com/biologia/reino-fungi. Acesso em: 15 de Maio de 2021. &amp;lt;/ref&amp;gt;. Em muitos casos, fungos formam fusões simbióticas com plantas ou algas e interagem de diferentes maneiras com diferentes organismos vivos. Neste trabalho, todavia, não faremos a análise dessas interações e focaremos no comportamento individual de crescimento de fungos.&lt;br /&gt;
&lt;br /&gt;
Anatomicamente, fungos são compostos por células que se assemelham a tubos microscópicos, denominadas de '''hifas'''. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de '''anastomose''', formando uma complexa rede chamada de '''micélio''' (figura 1).&lt;br /&gt;
&lt;br /&gt;
A criação de novas hifas, em geral, ocorre ao longo do tempo através de dois processos principais: o primeiro, denominado de '''ramificação dicotômica''', consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de '''ramificação lateral''', no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na figura 2.&lt;br /&gt;
&lt;br /&gt;
Tendo em vista o objetivo deste trabalho, é importante também entender o porquê e quando as ramificações citadas acimas ocorrem, para que possamos programá-las em nosso modelo computacional. A ramificação, portanto, é atribuída ao acúmulo de partículas de nutrientes e materiais no ambiente, o que estimula a extensão das hifas dos fungos em sua direção. Dessa maneira, '''o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor'''. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de '''translocação''', no qual os nutrientes previamente absorvidos pelo fungo podem ser transportados internamente, bancando o crescimento do mesmo em locais com deficiência de nutrientes &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Mecanismos Gerais dos Modelos ==&lt;br /&gt;
Devido à grande complexidade e exigência computacional, algumas características típicas do desenvolvimento de fungos citadas na primeira seção foram deixadas de lado durante a construção de nosso modelo computacional. No entanto, os mecanismos essenciais para o bom funcionamento da simulação foram mantidos e serão abordados mais profundamente nessa seção.  &lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (''Tip to Tip Anastomosis''). À direita, a anastomose de uma ponta com uma hifa (''Tip to Hypha Anastomosis)'' &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Fungos possuem - nas pontas de suas hifas - uma estrutura chamada de Spitzenkörper (''corpo superior'' em alemão). Essa estrutura possui a função de orientar a hifa em seu crescimento e de transformar todo o material de crescimento (nutriente) encontrado em material para as paredes de seus tubos, o que leva à expansão de tamanho do fungo &amp;lt;ref name='SPITZEN'&amp;gt; G. Steinberg (2007). &amp;quot;Hyphal growth: a tale of motors, lipids, and the Spitzenkörper&amp;quot;. Eukaryotic Cell. 6 (3): 351–360. doi:10.1128/EC.00381-06 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
Por isso, tipicamente, as hifas dos fungos crescem de maneira apical (em suas pontas) e em linha reta, possuindo baixa variação em sua orientação e, quando há variação, as mudanças no ângulo de crescimento ocorrem devido a uma deslocação do Spitzenkörper. Estudos anteriores demonstram que essas variações na angulação são - para certas espécies - normalmente distribuídas &amp;lt;ref name= 'crescimento'&amp;gt; Molin, P., P. Gervais, J. Lemiere, and T. Davet (1992). Direction of hyphal growth: a relevant&lt;br /&gt;
parameter in the development of filamentous fungi. Research in Microbiology 143, 777–784. doi: 10.1016/0923-2508(92)90106-x. &amp;lt;/ref&amp;gt;. A espécie ''Mucor hiemalis'', por exemplo, possui uma angulação de 56° e desvio padrão de 17° &amp;lt;ref name=Hutch&amp;gt; Hutchinson, S. A., P. Sharma, K. R. Clarke, and I. Macdonald (1980). Control of hyphal orientation in colonies of Mucor hiemalis. Transactions of the British Mycological Society 75,&lt;br /&gt;
177–191. doi: 10.1016/S0007-1536(80)80078-7 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Divisão e anastomose===&lt;br /&gt;
&lt;br /&gt;
Os dois tipos de divisões  - ou ramificações - citadas anteriormente na seção introdutória variam entre as diferentes espécies de fungo e - da mesma maneira que o crescimento por expansão das hifas - são altamente dependentes da alta concentração de nutrientes em seu ambiente. Além disso, a absorção de novos nutrientes através do Spitzenkörper resulta em uma pressão de Turgor (ou pressão hidrostática) nas paredes internas do fungo, o que também influencia diretamente o processo de ramificação das hifas &amp;lt;ref name='HOPKINS'&amp;gt;&amp;lt;/ref&amp;gt;. Conforme o crescimento do fungo ocorre e suas ramificações acontecem, o processo de encontro e fusão das pontas das hifas dos fungos citado na primeira seção (anastomose) começa a ocorrer. Este processo também pode ocorrer de diferentes maneiras, como pode ser visto na figura 3. Após a ocorrência de ambos os processos, as hifas - agora juntas umas das outras - passam a permitir a transmissão de substâncias internamente entre si.&lt;br /&gt;
&lt;br /&gt;
== Construção do modelo computacional ==&lt;br /&gt;
''Branching na ponta / Computar só os da ponta / Crescimento ocorre só com o nutriente que o ponto final está''&lt;br /&gt;
&lt;br /&gt;
Utilizando as informações biológicas apresentadas nas seções anteriores, é possível criar funções matemáticas e computacionais para a programação dos três aspectos fundamentais de uma simulação de micélio de fungos:&lt;br /&gt;
&lt;br /&gt;
=== Ramificação nas pontas ===&lt;br /&gt;
&lt;br /&gt;
=== Extensão/Crescimento ===&lt;br /&gt;
&lt;br /&gt;
=== Mapa de Nutrientes ===&lt;br /&gt;
&lt;br /&gt;
=== Anastomose ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementação ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Funções:''' &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O Crescimento e divisão dependem do ângulo do segmento originário, uma forma de consegui-lo é através da equação:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \theta = arctan \left(\frac{y_f-y_i}{x_f-x_i}\right)  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
É importante lembrar que para x negativos deve-se somar &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. Esse cálculo, nas duas funções, implementa-se assim:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
x = x2 - x1&lt;br /&gt;
y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
theta= np.arctan(y/x)&lt;br /&gt;
  &lt;br /&gt;
if (x&amp;lt;0) :&lt;br /&gt;
  theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
theta=theta+aleatorio_theta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Crescimento===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Soma-se este ângulo com um número aleatório normalmente distribuído com média zero e sigma dependente de dados estatísticos advindos da observação do fungo que pretende-se modelar. Agora com o ângulo modificado podemos adquirir um x e y final para o novo segmento com &amp;lt;math&amp;gt; r \cos(\theta) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; r \sin(\theta) &amp;lt;/math&amp;gt; respectivamente, onde r é uma variável global que representa o tamanho de cada hifa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def crecimento (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
 &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta+ math.pi&lt;br /&gt;
  &lt;br /&gt;
  aleatorio_theta = random.normalvariate(0, math.pi/4) # angulo de &lt;br /&gt;
  &lt;br /&gt;
  theta=theta+aleatorio_theta&lt;br /&gt;
&lt;br /&gt;
  addx = r * math.cos(theta)&lt;br /&gt;
  addy = r * math.sin(theta)&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  fx = x2 + addx&lt;br /&gt;
  fy = y2 + addy &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return (fx,fy)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Divisão===&lt;br /&gt;
&lt;br /&gt;
A divisão trabalha com uma ideia similar ao crescimento, porém o ângulo aleatório normalmente distribuído é o ângulo que separa as duas hifas criadas&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def divisao (x1,y1,x2,y2):&lt;br /&gt;
  x = x2 - x1&lt;br /&gt;
  y = y2 - y1&lt;br /&gt;
  &lt;br /&gt;
  theta= np.arctan(y/x)&lt;br /&gt;
&lt;br /&gt;
  if (x&amp;lt;0) :&lt;br /&gt;
    theta= theta + math.pi&lt;br /&gt;
&lt;br /&gt;
  angulodivisao= random.normalvariate(0, math.pi/4) &lt;br /&gt;
&lt;br /&gt;
  angulo1= theta- angulodivisao/2&lt;br /&gt;
  angulo2= theta+ angulodivisao/2&lt;br /&gt;
&lt;br /&gt;
  addx1 = r * math.cos(angulo1) &lt;br /&gt;
  addy1 = r * math.sin(angulo1) &lt;br /&gt;
&lt;br /&gt;
  addx2= r * math.cos(angulo2) &lt;br /&gt;
  addy2= r * math.sin(angulo2) &lt;br /&gt;
  &lt;br /&gt;
  Ax = x2 + addx1&lt;br /&gt;
  Ay = y2 + addy1&lt;br /&gt;
  &lt;br /&gt;
  Bx = x2 + addx2&lt;br /&gt;
  By= y2 +addy2&lt;br /&gt;
&lt;br /&gt;
  return (Ax,Ay,Bx,By)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intersecção de linhas===&lt;br /&gt;
&lt;br /&gt;
A cada novo crescimento ou divisão, devemos verificar se há cruzamento entre algumas das linhas. Uma forma de tornar o código mais eficiente seria um algorítimo de detecção de cruzamentos que desconsiderasse alguns segmentos que estão muito longe na hora de calcular. &lt;br /&gt;
&lt;br /&gt;
Considerando a interseção de duas linhas &amp;lt;math&amp;gt;L_1&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;L_2&amp;lt;/math&amp;gt;, com  a linha &amp;lt;math&amp;gt; L_1 &amp;lt;/math&amp;gt; sendo definida por dois pontos distintos &amp;lt;math&amp;gt; (x_1, y_1) &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; (x_2, y_2) &amp;lt;/math&amp;gt;, e a linha &amp;lt;math&amp;gt; L_2 &amp;lt;/math&amp;gt; sendo definida por dois pontos distintos &amp;lt;math&amp;gt;(x_3,y_3)&amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt;(x_4,y_4)&amp;lt;/math&amp;gt;.&amp;lt;ref name=Wolfram&amp;gt; Weisstein, Eric W. &amp;quot;Line-Line Intersection.&amp;quot; From MathWorld Disponível em: http://mathworld.wolfram.com/Line-LineIntersection.html&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se há cruzamento: o ponto final da hifa é o ponto de intersecção entre as retas e ela não pode mais crescer ou dividir.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
U_x = \begin{vmatrix} \begin{vmatrix} x_1 &amp;amp; y_1\\x_2 &amp;amp; y_2\end{vmatrix} &amp;amp;  \begin{vmatrix} x_1 &amp;amp; 1\\x_2 &amp;amp; 1\end{vmatrix} \\\\ \begin{vmatrix} x_3 &amp;amp; y_3\\x_4 &amp;amp; y_4\end{vmatrix} &amp;amp; \begin{vmatrix} x_3 &amp;amp; 1\\x_4 &amp;amp; 1\end{vmatrix} \end{vmatrix} \,\! ;&lt;br /&gt;
\qquad&lt;br /&gt;
&lt;br /&gt;
U_y = \begin{vmatrix} \begin{vmatrix} x_1 &amp;amp; y_1\\x_2 &amp;amp; y_2\end{vmatrix} &amp;amp;  \begin{vmatrix} y_1 &amp;amp; 1\\y_2 &amp;amp; 1\end{vmatrix} \\\\ \begin{vmatrix} x_3 &amp;amp; y_3\\x_4 &amp;amp; y_4\end{vmatrix} &amp;amp; \begin{vmatrix} y_3 &amp;amp; 1\\y_4 &amp;amp; 1\end{vmatrix} \end{vmatrix} \,\!;&lt;br /&gt;
\qquad&lt;br /&gt;
&lt;br /&gt;
D = \begin{vmatrix} \begin{vmatrix} x_1 &amp;amp; 1\\x_2 &amp;amp; 1\end{vmatrix} &amp;amp;  \begin{vmatrix} y_1 &amp;amp; 1\\y_2 &amp;amp; 1\end{vmatrix} \\\\ \begin{vmatrix} x_3 &amp;amp; 1\\x_4 &amp;amp; 1\end{vmatrix} &amp;amp; \begin{vmatrix} y_3 &amp;amp; 1\\y_4 &amp;amp; 1\end{vmatrix} \end{vmatrix}\,\!;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
P_x=\frac{U_x}{D};\qquad&lt;br /&gt;
P_y=\frac{U_y}{D}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quando duas linhas são paralelas ou coincidentes, o D é igual a zero. Se as linhas forem quase paralelas uma computacional pode encontrar problemas numéricos ao implementar.&amp;lt;ref name = Wikipedia&amp;gt; ''Line to line intersection''. Wikipedia, the free encyclopedia. Disponível em: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection. Acesso em: 20 de Maio de 2021. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se não há cruzamento: a hifa pode continuar a crescer e se dividir normalmente.&lt;br /&gt;
&lt;br /&gt;
Devemos tomar cuidado para o algoritmo não identificar a hifa a qual esta foi originada como intersecção!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_anastomose(eventos,xf,yf,xi,yi):&lt;br /&gt;
  flag = True&lt;br /&gt;
  for evento in eventos:&lt;br /&gt;
    if (xi == evento[2] and yi == evento[3]):&lt;br /&gt;
      continue&lt;br /&gt;
    if (xi == evento[0] and yi == evento[1]):&lt;br /&gt;
      continue&lt;br /&gt;
    D = (evento[3]-evento[1])*(xf-xi) - (evento[2]-evento[0])*(yf-yi)&lt;br /&gt;
    uA = ((evento[2]-evento[0])*(yi-evento[1]) - (evento[3]-evento[1])*(xi-evento[0]))/D&lt;br /&gt;
    uB = ((xf-xi)*(yi-evento[1])-(yf-yi)*(xi-evento[0]))/D&lt;br /&gt;
    flag = True&lt;br /&gt;
    if (0&amp;lt;=uA&amp;lt;=1) and (0&amp;lt;=uB&amp;lt;=1):&lt;br /&gt;
      flag = False&lt;br /&gt;
    if not flag:&lt;br /&gt;
      xf, yf = get_intersection_point(uA,xf,yf,xi,yi)&lt;br /&gt;
      break&lt;br /&gt;
  return xf,yf, flag&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Após se encontrar usa a func:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def get_intersection_point(uA,xf,yf,xi,yi):&lt;br /&gt;
  xf = xi + (uA * (xf-xi))&lt;br /&gt;
  yf = yi + (uA * (yf-yi))&lt;br /&gt;
  return xf,yf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa de Nutriente===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def find_nearest(array, value):&lt;br /&gt;
    array = np.asarray(array)&lt;br /&gt;
    idx = (np.abs(array - value)).argmin()&lt;br /&gt;
    return array[idx]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def check_nutri(x,y,xmapa,ymapa,mapa_nutri):&lt;br /&gt;
  &lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri[index_y[0][0]][index_x[0][0]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
def atualiza_mapa_nutri(x,y,xmapa,ymapa,mapa_nutri,preco):&lt;br /&gt;
&lt;br /&gt;
  near_x = find_nearest(xmapa,x) ## encontra valor mais próximo em x&lt;br /&gt;
  near_y = find_nearest(ymapa,y) ## encontra valor mais próximo em y&lt;br /&gt;
&lt;br /&gt;
  index_x = np.where(xmapa == near_x) ## encontra o index do valor de x&lt;br /&gt;
  index_y = np.where(ymapa == near_y) ## encontra o index do valor de y&lt;br /&gt;
  &lt;br /&gt;
  mapa_nutri[index_y[0][0]][index_x[0][0]] -= preco&lt;br /&gt;
&lt;br /&gt;
  return (mapa_nutri)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Referências ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Brunoztemp</name></author>
	</entry>
</feed>