<?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=Hossa</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=Hossa"/>
	<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Especial:Contribui%C3%A7%C3%B5es/Hossa"/>
	<updated>2026-06-12T18:15:46Z</updated>
	<subtitle>Contribuições do usuário</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Simula%C3%A7%C3%A3o_de_Mic%C3%A9lio_de_Fungo&amp;diff=5148</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=5148"/>
		<updated>2021-05-25T01:56:29Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Melhorias a serem realizadas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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|&#039;&#039;&#039;Figura 1&#039;&#039;&#039;: Ilustração da estrutura de um fungo. &amp;lt;ref name=&#039;PAULA&#039;&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|&#039;&#039;&#039;Figura 2&#039;&#039;&#039;: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (&#039;&#039;&#039;figura 1&#039;&#039;&#039;).&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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na &#039;&#039;&#039;figura 2&#039;&#039;&#039;.&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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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|&#039;&#039;&#039;Figura 3&#039;&#039;&#039;: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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 &#039;&#039;&#039;figura 3&#039;&#039;&#039;. 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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;&#039;(Figura 4)&#039;&#039;&#039; é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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|&#039;&#039;&#039;Figura 4&#039;&#039;&#039;: 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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 13&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais em formato de estrela são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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|&#039;&#039;&#039;Figura 8&#039;&#039;&#039;: Crescimento real de um micélio ]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&#039;REYNDERS&#039;&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 (&#039;&#039;&#039;figura 9&#039;&#039;&#039;) &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|&#039;&#039;&#039;Figura 9&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 10&#039;&#039;&#039;: 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 (&#039;&#039;&#039;figura 8&#039;&#039;&#039;).&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 (&#039;&#039;&#039;figura 10&#039;&#039;&#039;), conforme o fungo vai crescendo parte desses nutrientes é consumida e é representada pelas partes mais claras da &#039;&#039;&#039;figura 11&#039;&#039;&#039;, enquanto o fungo completamente desenvolvido está mostrado na &#039;&#039;&#039;figura 12&#039;&#039;&#039;.&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|&#039;&#039;&#039;Figura 10&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 11&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 12&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 13&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 14&#039;&#039;&#039;: Evolução temporal do crescimento de hifas utilizando o mapa de imagem da &#039;&#039;&#039;figura 6&#039;&#039;&#039;.]]&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|&#039;&#039;&#039;Figura 15&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039; (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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;repeticao/10):&lt;br /&gt;
      axs[0].plot(vet[0],vet[1],color=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;repeticao/4):&lt;br /&gt;
      axs[1].plot(vet[0],vet[1],color=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;repeticao/2):&lt;br /&gt;
      axs[2].plot(vet[0],vet[1],color=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;3*repeticao/4):&lt;br /&gt;
      axs[3].plot(vet[0],vet[1],color=&#039;green&#039;)&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(&#039;Fungo com repeticoes: {}\n&#039;.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>Hossa</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=5147</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=5147"/>
		<updated>2021-05-25T01:56:21Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Melhorias a serem realizadas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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|&#039;&#039;&#039;Figura 1&#039;&#039;&#039;: Ilustração da estrutura de um fungo. &amp;lt;ref name=&#039;PAULA&#039;&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|&#039;&#039;&#039;Figura 2&#039;&#039;&#039;: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (&#039;&#039;&#039;figura 1&#039;&#039;&#039;).&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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na &#039;&#039;&#039;figura 2&#039;&#039;&#039;.&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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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|&#039;&#039;&#039;Figura 3&#039;&#039;&#039;: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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 &#039;&#039;&#039;figura 3&#039;&#039;&#039;. 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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;&#039;(Figura 4)&#039;&#039;&#039; é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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|&#039;&#039;&#039;Figura 4&#039;&#039;&#039;: 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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 13&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais em formato de estrela são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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|&#039;&#039;&#039;Figura 8&#039;&#039;&#039;: Crescimento real de um micélio ]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&#039;REYNDERS&#039;&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 (&#039;&#039;&#039;figura 9&#039;&#039;&#039;) &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|&#039;&#039;&#039;Figura 9&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 10&#039;&#039;&#039;: 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 (&#039;&#039;&#039;figura 8&#039;&#039;&#039;).&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 (&#039;&#039;&#039;figura 10&#039;&#039;&#039;), conforme o fungo vai crescendo parte desses nutrientes é consumida e é representada pelas partes mais claras da &#039;&#039;&#039;figura 11&#039;&#039;&#039;, enquanto o fungo completamente desenvolvido está mostrado na &#039;&#039;&#039;figura 12&#039;&#039;&#039;.&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|&#039;&#039;&#039;Figura 10&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 11&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 12&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 13&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 14&#039;&#039;&#039;: Evolução temporal do crescimento de hifas utilizando o mapa de imagem da &#039;&#039;&#039;figura 6&#039;&#039;&#039;.]]&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|&#039;&#039;&#039;Figura 15&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039; (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 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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;repeticao/10):&lt;br /&gt;
      axs[0].plot(vet[0],vet[1],color=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;repeticao/4):&lt;br /&gt;
      axs[1].plot(vet[0],vet[1],color=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;repeticao/2):&lt;br /&gt;
      axs[2].plot(vet[0],vet[1],color=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;3*repeticao/4):&lt;br /&gt;
      axs[3].plot(vet[0],vet[1],color=&#039;green&#039;)&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(&#039;Fungo com repeticoes: {}\n&#039;.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>Hossa</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=5104</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=5104"/>
		<updated>2021-05-24T23:37:17Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Mapa Homogêneo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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|&#039;&#039;&#039;Figura 1&#039;&#039;&#039;: Ilustração da estrutura de um fungo. &amp;lt;ref name=&#039;PAULA&#039;&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|&#039;&#039;&#039;Figura 2&#039;&#039;&#039;: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (&#039;&#039;&#039;figura 1&#039;&#039;&#039;).&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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na &#039;&#039;&#039;figura 2&#039;&#039;&#039;.&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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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|&#039;&#039;&#039;Figura 3&#039;&#039;&#039;: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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 &#039;&#039;&#039;figura 3&#039;&#039;&#039;. 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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;&#039;(Figura 4)&#039;&#039;&#039; é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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|&#039;&#039;&#039;Figura 4&#039;&#039;&#039;: 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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 13&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais em formato de estrela são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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|&#039;&#039;&#039;Figura 8&#039;&#039;&#039;: Crescimento real de um micélio ]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&#039;REYNDERS&#039;&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 (&#039;&#039;&#039;figura 9&#039;&#039;&#039;) &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|&#039;&#039;&#039;Figura 9&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 10&#039;&#039;&#039;: 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 (&#039;&#039;&#039;figura 8&#039;&#039;&#039;).&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 (&#039;&#039;&#039;figura 10&#039;&#039;&#039;), conforme o fungo vai crescendo parte desses nutrientes é consumida e é representada pelas partes mais claras da &#039;&#039;&#039;figura 11&#039;&#039;&#039;, enquanto o fungo completamente desenvolvido está mostrado na &#039;&#039;&#039;figura 12&#039;&#039;&#039;.&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|&#039;&#039;&#039;Figura 10&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 11&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 12&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 13&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 14&#039;&#039;&#039;: Evolução temporal do crescimento de hifas utilizando o mapa de imagem da &#039;&#039;&#039;figura 6&#039;&#039;&#039;.]]&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|&#039;&#039;&#039;Figura 15&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039; (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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;repeticao/10):&lt;br /&gt;
      axs[0].plot(vet[0],vet[1],color=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;repeticao/4):&lt;br /&gt;
      axs[1].plot(vet[0],vet[1],color=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;repeticao/2):&lt;br /&gt;
      axs[2].plot(vet[0],vet[1],color=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;3*repeticao/4):&lt;br /&gt;
      axs[3].plot(vet[0],vet[1],color=&#039;green&#039;)&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(&#039;Fungo com repeticoes: {}\n&#039;.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>Hossa</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=5103</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=5103"/>
		<updated>2021-05-24T23:37:03Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Mapa Homogêneo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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|&#039;&#039;&#039;Figura 1&#039;&#039;&#039;: Ilustração da estrutura de um fungo. &amp;lt;ref name=&#039;PAULA&#039;&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|&#039;&#039;&#039;Figura 2&#039;&#039;&#039;: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (&#039;&#039;&#039;figura 1&#039;&#039;&#039;).&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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na &#039;&#039;&#039;figura 2&#039;&#039;&#039;.&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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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|&#039;&#039;&#039;Figura 3&#039;&#039;&#039;: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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 &#039;&#039;&#039;figura 3&#039;&#039;&#039;. 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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;&#039;(Figura 4)&#039;&#039;&#039; é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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|&#039;&#039;&#039;Figura 4&#039;&#039;&#039;: 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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 13&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais em formato de estrela são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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|&#039;&#039;&#039;Figura 8&#039;&#039;&#039;: Crescimento real de um micélio ]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&#039;REYNDERS&#039;&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 (&#039;&#039;&#039;figura 9&#039;&#039;&#039;) &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|&#039;&#039;&#039;Figura 9&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 10&#039;&#039;&#039;: 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 (&#039;&#039;&#039;figura 8&#039;&#039;&#039;).&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 (&#039;&#039;&#039;figura 10&#039;&#039;&#039;), conforme o fungo vai crescendo parte desses nutrientes é consumida e é representada pelas partes mais claras da &#039;&#039;&#039;figura 11&#039;&#039;&#039;, enquanto o fungo completamente desenvolvido está mostrado na &#039;&#039;&#039;figura 12&#039;&#039;&#039;.&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|&#039;&#039;&#039;Figura 10&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 11&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 12&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 13&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 14&#039;&#039;&#039;: Evolução temporal do crescimento de hifas utilizando o mapa de imagem da &#039;&#039;&#039;figura 6&#039;&#039;&#039;.]]&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|&#039;&#039;&#039;Figura 15&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039; (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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;repeticao/10):&lt;br /&gt;
      axs[0].plot(vet[0],vet[1],color=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;repeticao/4):&lt;br /&gt;
      axs[1].plot(vet[0],vet[1],color=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;repeticao/2):&lt;br /&gt;
      axs[2].plot(vet[0],vet[1],color=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;3*repeticao/4):&lt;br /&gt;
      axs[3].plot(vet[0],vet[1],color=&#039;green&#039;)&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(&#039;Fungo com repeticoes: {}\n&#039;.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>Hossa</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=5102</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=5102"/>
		<updated>2021-05-24T23:36:07Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Evolução Temporal */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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|&#039;&#039;&#039;Figura 1&#039;&#039;&#039;: Ilustração da estrutura de um fungo. &amp;lt;ref name=&#039;PAULA&#039;&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|&#039;&#039;&#039;Figura 2&#039;&#039;&#039;: Processos de ramificação de fungos. À esquerda a ramificação dicotômica (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (&#039;&#039;&#039;figura 1&#039;&#039;&#039;).&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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, no qual, como o nome sugere, formam-se novos ramos e hifas na lateral de uma hifa já existente, como pode ser visto na &#039;&#039;&#039;figura 2&#039;&#039;&#039;.&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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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|&#039;&#039;&#039;Figura 3&#039;&#039;&#039;: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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 &#039;&#039;&#039;figura 3&#039;&#039;&#039;. 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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;&#039;(Figura 4)&#039;&#039;&#039; é definido como uma matriz que armazena o valor de nutriente em cada ponto identificado pela matriz &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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|&#039;&#039;&#039;Figura 4&#039;&#039;&#039;: 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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 13&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais em formato de estrela são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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|&#039;&#039;&#039;Figura 8&#039;&#039;&#039;: Crescimento real de um micélio ]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&#039;REYNDERS&#039;&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 (&#039;&#039;&#039;figura 9&#039;&#039;&#039;) &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|&#039;&#039;&#039;Figura 9&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 10&#039;&#039;&#039;: 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 (&#039;&#039;&#039;figura 8&#039;&#039;&#039;).&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 (&#039;&#039;&#039;figura 10&#039;&#039;&#039;), conforme o fungo vai crescendo parte desses nutrientes é consumida e é representada pelas partes mais claras da &#039;&#039;&#039;figura 11&#039;&#039;&#039;, enquanto o fungo completamente desenvolvido está mostrado na &#039;&#039;&#039;figura 12&#039;&#039;&#039;.&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|&#039;&#039;&#039;Figura 10&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 11&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 12&#039;&#039;&#039;: 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|&#039;&#039;&#039;Figura 13&#039;&#039;&#039;: 5 etapas da simulação usando o mapa homogênio 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|&#039;&#039;&#039;Figura 14&#039;&#039;&#039;: Evolução temporal do crescimento de hifas utilizando o mapa de imagem da &#039;&#039;&#039;figura 6&#039;&#039;&#039;.]]&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|&#039;&#039;&#039;Figura 15&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039; (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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;repeticao/10):&lt;br /&gt;
      axs[0].plot(vet[0],vet[1],color=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;repeticao/4):&lt;br /&gt;
      axs[1].plot(vet[0],vet[1],color=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;repeticao/2):&lt;br /&gt;
      axs[2].plot(vet[0],vet[1],color=&#039;green&#039;)&lt;br /&gt;
    if (j&amp;lt;3*repeticao/4):&lt;br /&gt;
      axs[3].plot(vet[0],vet[1],color=&#039;green&#039;)&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(&#039;Fungo com repeticoes: {}\n&#039;.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>Hossa</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=4980</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=4980"/>
		<updated>2021-05-24T20:27:06Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Mapa por imagem */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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 (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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;
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;
&lt;br /&gt;
===Mapa não homogêneo===&lt;br /&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;
&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;
&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: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;
&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;
&lt;br /&gt;
&lt;br /&gt;
====Evolução Temporal do Mapa Homogêneo====&lt;br /&gt;
&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 de crescimento das hifas de um fungo.]]&amp;lt;/li&amp;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 original - e homogêneo - utilizado para obtenção da simulação 3.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa por imagem===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|&#039;&#039;&#039;Figura 14&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039;.]]&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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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>Hossa</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=4979</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=4979"/>
		<updated>2021-05-24T20:26:03Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Mapa Homogêneo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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 (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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;
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;
&lt;br /&gt;
===Mapa não homogêneo===&lt;br /&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;
&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;
&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: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;
&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;
&lt;br /&gt;
&lt;br /&gt;
====Evolução Temporal do Mapa Homogêneo====&lt;br /&gt;
&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 de crescimento das hifas de um fungo.]]&amp;lt;/li&amp;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 original - e homogêneo - utilizado para obtenção da simulação 3.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa por imagem===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|&#039;&#039;&#039;Figura x&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039;.]]&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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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>Hossa</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=4978</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=4978"/>
		<updated>2021-05-24T20:25:44Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Mapa não homogêneo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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 (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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;
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;
&lt;br /&gt;
===Mapa não homogêneo===&lt;br /&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;
&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;
&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: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;
====Evolução Temporal do Mapa Homogêneo====&lt;br /&gt;
&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 de crescimento das hifas de um fungo.]]&amp;lt;/li&amp;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 original - e homogêneo - utilizado para obtenção da simulação 3.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa por imagem===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|&#039;&#039;&#039;Figura x&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039;.]]&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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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>Hossa</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=4977</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=4977"/>
		<updated>2021-05-24T20:25:26Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Mapa não homogêneo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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 (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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;
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;
&lt;br /&gt;
===Mapa não homogêneo===&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;
&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: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;
====Evolução Temporal do Mapa Homogêneo====&lt;br /&gt;
&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 de crescimento das hifas de um fungo.]]&amp;lt;/li&amp;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 original - e homogêneo - utilizado para obtenção da simulação 3.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa por imagem===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|&#039;&#039;&#039;Figura x&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039;.]]&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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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>Hossa</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=4976</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=4976"/>
		<updated>2021-05-24T20:24:24Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Evolução Temporal do Mapa Homogêneo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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 (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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;
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;
&lt;br /&gt;
===Mapa não homogêneo===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 1.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice1.jpeg|250px|thumb|center|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: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;
====Evolução Temporal do Mapa Homogêneo====&lt;br /&gt;
&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 de crescimento das hifas de um fungo.]]&amp;lt;/li&amp;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 original - e homogêneo - utilizado para obtenção da simulação 3.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa por imagem===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|&#039;&#039;&#039;Figura x&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039;.]]&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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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>Hossa</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=4974</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=4974"/>
		<updated>2021-05-24T20:23:54Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Evolução Temporal do Mapa Homogêneo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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 (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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;
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;
&lt;br /&gt;
===Mapa não homogêneo===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 1.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice1.jpeg|250px|thumb|center|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: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;
===Evolução Temporal do Mapa Homogêneo===&lt;br /&gt;
&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 de crescimento das hifas de um fungo.]]&amp;lt;/li&amp;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 utilizado para obtenção da simulação 3.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Mapa por imagem===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|&#039;&#039;&#039;Figura x&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039;.]]&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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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>Hossa</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Nutrii.jpeg&amp;diff=4973</id>
		<title>Arquivo:Nutrii.jpeg</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Nutrii.jpeg&amp;diff=4973"/>
		<updated>2021-05-24T20:22:36Z</updated>

		<summary type="html">&lt;p&gt;Hossa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Hossa</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=4972</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=4972"/>
		<updated>2021-05-24T20:22:25Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Evolução Temporal do Mapa Homogêneo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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 (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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;
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;
&lt;br /&gt;
===Mapa não homogêneo===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 1.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice1.jpeg|250px|thumb|center|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: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;
===Evolução Temporal do Mapa Homogêneo===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 12: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutrii.jpeg|250px|thumb|center|Figura 13: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
===Mapa por imagem===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|&#039;&#039;&#039;Figura x&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039;.]]&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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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>Hossa</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=4971</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=4971"/>
		<updated>2021-05-24T20:21:42Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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 (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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;
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;
&lt;br /&gt;
===Mapa não homogêneo===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 1.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice1.jpeg|250px|thumb|center|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: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;
===Evolução Temporal do Mapa Homogêneo===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 12: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 13: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
===Mapa por imagem===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|&#039;&#039;&#039;Figura x&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039;.]]&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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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>Hossa</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=4970</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=4970"/>
		<updated>2021-05-24T20:19:32Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Mapa Homogêneo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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 (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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;
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;
&lt;br /&gt;
===Mapa não homogêneo===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 1.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice1.jpeg|250px|thumb|center|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: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;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 12: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 13: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
===Mapa por imagem===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|&#039;&#039;&#039;Figura x&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039;.]]&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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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>Hossa</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=4968</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=4968"/>
		<updated>2021-05-24T20:19:01Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Mapa não homogêneo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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 (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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;
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;
&lt;br /&gt;
===Mapa não homogêneo===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 1.]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li style=&amp;quot;display: inline-block;&amp;quot;&amp;gt;[[Arquivo:mice1.jpeg|250px|thumb|center|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;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 11: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 10: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 12: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 13: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
===Mapa por imagem===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|&#039;&#039;&#039;Figura x&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039;.]]&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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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>Hossa</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=4967</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=4967"/>
		<updated>2021-05-24T20:18:17Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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 (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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;
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;
&lt;br /&gt;
===Mapa não homogêneo===&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;
&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;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 11: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 10: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 12: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 13: mapa de nutrientes utilizado para obtenção da simulação 3.]]&lt;br /&gt;
&lt;br /&gt;
===Mapa por imagem===&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:Muito_obrigado.png|400px|thumb|center|&#039;&#039;&#039;Figura x&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039;.]]&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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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>Hossa</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=4950</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=4950"/>
		<updated>2021-05-24T19:26:41Z</updated>

		<summary type="html">&lt;p&gt;Hossa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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 (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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;
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 8: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 10: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 11: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 12: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 13: 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|&#039;&#039;&#039;Figura x&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039;.]]&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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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>Hossa</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=4935</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=4935"/>
		<updated>2021-05-24T18:41:19Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Condições Iniciais */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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 (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: Condições iniciais]]&lt;br /&gt;
As condições iniciais são mostradas na &#039;&#039;&#039;Figura 7&#039;&#039;&#039; 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;
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 8: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 10: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 11: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 12: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 13: 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|&#039;&#039;&#039;Figura x&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039;.]]&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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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>Hossa</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=4931</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=4931"/>
		<updated>2021-05-24T18:37:38Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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 (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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: &#039;&#039;eventos&#039;&#039; que armazena os segmentos de retas com &#039;&#039;xi yi xf yf  flag&#039;&#039;; &#039;&#039;flag&#039;&#039; representa se ocorreu o processo de anastomose, caso &#039;&#039;flag&#039;&#039; armazene &#039;&#039;False&#039;&#039; o primeiro &#039;&#039;try&#039;&#039; faz o segmento parar de crescer; Dentro do &#039;&#039;for&#039;&#039; principal há um &#039;&#039;if&#039;&#039; e &#039;&#039;else&#039;&#039; que junto da condição &#039;&#039;random.random() &amp;gt; 0.6857-0.2857*c&#039;&#039; faz com que 60% de chance de ocorrer de divisão quando c é igual a 1, pois &#039;&#039;random.random()&#039;&#039; é 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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 &#039;&#039;X&#039;&#039; e &#039;&#039;Y&#039;&#039;, o mapa de nutrientes implementado foi um mapa discreto, ao contrário do artigo &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&#039;&#039;&#039;Criação do mapa&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implementamos três formas de criar o mapa. A função &#039;&#039;mapa_nutri_Nhomogenea&#039;&#039; 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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;&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 &#039;&#039;mapa_unitario_nutri&#039;&#039; cria um mapa homogêneo com todos os nutrientes começando em 1. Exemplo após crescimento do fungo mostrado na &#039;&#039;&#039;Figura 9&#039;&#039;&#039;&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 &#039;&#039;&#039;Figura 5&#039;&#039;&#039;, que transforma o gradiente de preto a branco dos pontos (&#039;&#039;x_mapa,y_mapa&#039;&#039;) em um mapa de nutriente, mostrado &#039;&#039;&#039;Figura 6&#039;&#039;&#039;, 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 = &#039;/content/OBRIGADO.png&#039;&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 &#039;&#039;&#039;Figura 7&#039;&#039;&#039; e implementadas assim:&lt;br /&gt;
[[Arquivo:CondiIni.png|200px|thumb|right|&#039;&#039;&#039;Figura 7&#039;&#039;&#039;: 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 8: simulação do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|center|Figura 9: mapa de nutrientes utilizado para obtenção da simulação 1.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 10: simulação do crescimento das hifas de um fungo após 90000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri2.jpeg|250px|thumb|center|Figura 11: mapa de nutrientes utilizado para obtenção da simulação 2.]]&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:mice3.jpeg|1000px|thumb|center|Figura 12: 5 etapas da simulação de crescimento das hifas de um fungo.]]&lt;br /&gt;
[[Arquivo:nutri3.jpeg|250px|thumb|center|Figura 13: 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|&#039;&#039;&#039;Figura x&#039;&#039;&#039;: simulação do crescimento do fungo utilizando o mapa de nutrientes da &#039;&#039;&#039;Figura 6&#039;&#039;&#039;.]]&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(&#039;Fungo com repeticoes: {}&#039;.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=&#039;green&#039;)&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>Hossa</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=4853</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=4853"/>
		<updated>2021-05-24T06:36:56Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Mecanismos Gerais dos Modelos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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 (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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>Hossa</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=4852</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=4852"/>
		<updated>2021-05-24T06:35:55Z</updated>

		<summary type="html">&lt;p&gt;Hossa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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>Hossa</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=4851</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=4851"/>
		<updated>2021-05-24T06:35:14Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Mapa de Nutriente */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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>Hossa</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=4850</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=4850"/>
		<updated>2021-05-24T06:34:40Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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>Hossa</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=4849</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=4849"/>
		<updated>2021-05-24T06:34:06Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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>Hossa</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=4848</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=4848"/>
		<updated>2021-05-24T06:33:45Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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|600px|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>Hossa</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Nutri3.jpeg&amp;diff=4847</id>
		<title>Arquivo:Nutri3.jpeg</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Nutri3.jpeg&amp;diff=4847"/>
		<updated>2021-05-24T06:33:25Z</updated>

		<summary type="html">&lt;p&gt;Hossa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Hossa</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Mice3.jpeg&amp;diff=4846</id>
		<title>Arquivo:Mice3.jpeg</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Mice3.jpeg&amp;diff=4846"/>
		<updated>2021-05-24T06:33:14Z</updated>

		<summary type="html">&lt;p&gt;Hossa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Hossa</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=4845</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=4845"/>
		<updated>2021-05-24T06:33:05Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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|250px|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>Hossa</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=4844</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=4844"/>
		<updated>2021-05-24T06:31:04Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
[[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;
== 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>Hossa</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=4843</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=4843"/>
		<updated>2021-05-24T06:30:42Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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 inicial 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;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação inicial 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;
== 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>Hossa</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Nutri2.jpeg&amp;diff=4842</id>
		<title>Arquivo:Nutri2.jpeg</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Nutri2.jpeg&amp;diff=4842"/>
		<updated>2021-05-24T06:30:20Z</updated>

		<summary type="html">&lt;p&gt;Hossa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Hossa</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Mice2.jpeg&amp;diff=4841</id>
		<title>Arquivo:Mice2.jpeg</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Mice2.jpeg&amp;diff=4841"/>
		<updated>2021-05-24T06:30:07Z</updated>

		<summary type="html">&lt;p&gt;Hossa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Hossa</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=4840</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=4840"/>
		<updated>2021-05-24T06:30:00Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação inicial 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;
[[Arquivo:mice2.jpeg|250px|thumb|center|Figura 6: simulação inicial 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;
&lt;br /&gt;
&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;
== 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>Hossa</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=4839</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=4839"/>
		<updated>2021-05-24T06:27:31Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
[[Arquivo:mice1.jpeg|250px|thumb|center|Figura 4: simulação inicial 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;
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;
== 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>Hossa</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=4838</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=4838"/>
		<updated>2021-05-24T06:27:10Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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-left|Figura 4: simulação inicial do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|right|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&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>Hossa</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Nutri1.jpeg&amp;diff=4837</id>
		<title>Arquivo:Nutri1.jpeg</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Nutri1.jpeg&amp;diff=4837"/>
		<updated>2021-05-24T06:26:01Z</updated>

		<summary type="html">&lt;p&gt;Hossa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Hossa</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=4836</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=4836"/>
		<updated>2021-05-24T06:25:51Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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|left|Figura 4: simulação inicial do crescimento das hifas de um fungo após 3000 iterações.]]&lt;br /&gt;
[[Arquivo:nutri1.jpeg|250px|thumb|right|Figura 5: mapa de nutrientes utilizado para obtenção da simulação 1.]]&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>Hossa</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Mice1.jpeg&amp;diff=4835</id>
		<title>Arquivo:Mice1.jpeg</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Mice1.jpeg&amp;diff=4835"/>
		<updated>2021-05-24T06:24:02Z</updated>

		<summary type="html">&lt;p&gt;Hossa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Hossa</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=4834</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=4834"/>
		<updated>2021-05-24T06:23:53Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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 1: simulação inicial do crescimento das hifas de um fungo após 3000 iterações.]]&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>Hossa</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=4833</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=4833"/>
		<updated>2021-05-24T06:23:42Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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|left|Figura 1: simulação inicial do crescimento das hifas de um fungo após 3000 iterações.]]&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>Hossa</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=4832</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=4832"/>
		<updated>2021-05-24T06:23:31Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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|left|Figura 1: simulação inicial do crescimento das hifas de um fungo após 3000 iterações.&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>Hossa</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Fungo.jpg&amp;diff=4831</id>
		<title>Arquivo:Fungo.jpg</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Fungo.jpg&amp;diff=4831"/>
		<updated>2021-05-24T06:20:47Z</updated>

		<summary type="html">&lt;p&gt;Hossa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Hossa</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=4830</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=4830"/>
		<updated>2021-05-24T06:20:39Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Motivação e Introdução aos Fungos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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=&#039;PAULA&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
== 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>Hossa</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=4829</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=4829"/>
		<updated>2021-05-24T06:18:05Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Discussão de Resultados */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
== 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>Hossa</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=4828</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=4828"/>
		<updated>2021-05-24T06:13:22Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Divisão e anastomose */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&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>Hossa</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=4827</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=4827"/>
		<updated>2021-05-24T06:11:39Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Divisão e anastomose */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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.&lt;br /&gt;
&lt;br /&gt;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&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>Hossa</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=4826</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=4826"/>
		<updated>2021-05-24T06:09:53Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Crescimento */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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;
===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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&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>Hossa</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=4825</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=4825"/>
		<updated>2021-05-24T06:06:53Z</updated>

		<summary type="html">&lt;p&gt;Hossa: /* Crescimento */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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.&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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&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>Hossa</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=4824</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=4824"/>
		<updated>2021-05-24T06:01:13Z</updated>

		<summary type="html">&lt;p&gt;Hossa: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Grupo: Arthur Dornelles, Bruno Zanette, Gabriel De David e Guilherme Hoss&#039;&#039;&#039;&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=&#039;HOPKINS&#039;&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 (&#039;&#039;Dichotomous&#039;&#039;) e à direita o processo de ramificação lateral &amp;lt;ref name=&#039;HOPKINS&#039;&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=&#039;SILVA&#039;&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 &#039;&#039;&#039;hifas&#039;&#039;&#039;. Essas hifas então se ramificam e se fundem umas com as outras em um processo chamado de &#039;&#039;&#039;anastomose&#039;&#039;&#039;, formando uma complexa rede chamada de &#039;&#039;&#039;micélio&#039;&#039;&#039; (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 &#039;&#039;&#039;ramificação dicotômica&#039;&#039;&#039;, consiste na ponta de uma hifa já existente se dividindo ao meio. O segundo processo é chamado de &#039;&#039;&#039;ramificação lateral&#039;&#039;&#039;, 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, &#039;&#039;&#039;o crescimento e desenvolvimento dos fungos são altamente dependentes e influenciados pela disponibilidade de nutrientes e materiais no ambiente ao seu redor&#039;&#039;&#039;. Apesar desse fato, fungos podem continuar se desenvolvendo até em ambientes com poucos nutrientes, devido ao processo de &#039;&#039;&#039;translocação&#039;&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
[[Arquivo:anastosomose.png|250px|thumb|right|Figura 3: O processo de anastomose pode ocorrer de duas maneiras distintas. À esquerda, anastomose de duas pontas separadas (&#039;&#039;Tip to Tip Anastomosis&#039;&#039;). À direita, a anastomose de uma ponta com uma hifa (&#039;&#039;Tip to Hypha Anastomosis)&#039;&#039; &amp;lt;ref name=&#039;HOPKINS&#039;&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 (&#039;&#039;corpo superior&#039;&#039; 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=&#039;SPITZEN&#039;&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= &#039;crescimento&#039;&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 &#039;&#039;Mucor hiemalis&#039;&#039;, 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=&#039;HOPKINS&#039;&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;
== 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;
* &#039;&#039;&#039;Funções:&#039;&#039;&#039; &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; &#039;&#039;Line to line intersection&#039;&#039;. 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 &#039;&#039;if&#039;&#039;s identifica se a hifa a qual essa foi originada é quem está sendo calculada. Se não há cruzamento temos que &#039;&#039;flag = False&#039;&#039;, o que significa que a hifa pode continuar crescendo, caso haja ponto de intersecção é chamada a &#039;&#039;get_intersection_point&#039;&#039; 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=&#039;HOPKINS&#039;&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 (&#039;&#039;find_nearest&#039;&#039;) que encontra o valor mais próximo de &#039;&#039;x&#039;&#039; e &#039;&#039;y&#039;&#039; no &#039;&#039;array&#039;&#039; 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 &#039;&#039;check_nutri&#039;&#039; que retorna a quantidade de nutrientes disponível utiliza a &#039;&#039;find_nearest&#039;&#039; para encontrar o index do ponto que é também o do nutriente no ponto na matriz &#039;&#039;mapa_nutri&#039;&#039;:&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 &#039;&#039;atualiza_mapa_nutri&#039;&#039; funciona de maneira similar a &#039;&#039;check_nutri&#039;&#039; porém essa recebe recebe também a variável &#039;&#039;preco&#039;&#039; 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;
&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>Hossa</name></author>
	</entry>
</feed>