forked from Liquidwork/Fungus_sim
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Fungus.java
123 lines (112 loc) · 4.32 KB
/
Fungus.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/**
* Fungus class Cloneable as it need to spread by cloning(mitosis)
*/
public class Fungus implements Cloneable{
public static int fungiCount = 0;
private static double lastTemp;
private static double tempPenalty;
private static final double[] A ={0.3769, 0.5144, 0.2450}; //Several Constants for temperature penalty
private static final double[] B ={0.3311, 0.05467, -0.4457};
private static final double[] C ={0.2746, 0.5334, 0.9016};
public int fungusId;
//Basic value is the attributes of the fungi at 22deg, no humidity change.
public double basicV;// Basic value of horizontal spreading speed
public double basicX;// Basic value of Hyphal extenrion rate
public double basicB;// Basic value of decomponent mass per unit area
public double mTradeOff;// Moisture trade-off of this species
public double spreadProgress = 0;
public double decomp = 0;// total decomposition of fungus on this area
public boolean spreaded = false;
/**
* Generate a random species
*/
public Fungus(){
this.fungusId = fungiCount++;// Generate an id for this new species, add the count
this.basicV = generateBasicV(); //Generate a horizontal spreading speed
this.basicX = generateBasicX(); //Generate a Hyphal extenrion rate
this.mTradeOff = generateMTradeOff(); //Generate a Moisture trade-off factor
this.basicB = generatebasicB(this.basicX); //Calculate a Basic value of decomponent mass per unit area
}
/**
* Clone a fungus from another one
* @param f fungi to be clone
*/
private Fungus(Fungus f){
this.basicB = f.basicB;
this.basicV = f.basicV;
this.basicX = f.basicX;
this.mTradeOff = f.mTradeOff;
this.fungusId = f.fungusId;
}
@Override
public Fungus clone(){
return new Fungus(this);
}
/**
* Let the fungi grow, adding the spread progress while decompositing
* @param climate the array representing environment including temperature and humidity changes
*/
public void grow(double[] climate){
double penalty = tempPenalty(climate[0]) * humidityPenalty(climate[1], this.mTradeOff);
if(this.spreaded == false){
this.spreadProgress += this.basicV * penalty;
}
//TODO: Decomposition increment
this.decomp += this.basicB;
}
//Generation Methods:
/*Generate a horizontal spreading speed with Normal distribution mean = 1 Variance = 0.15*/
private static double generateBasicV()
{
double mean = 3.0;
double deviation = 0.15;
double basicV = deviation * Map.random.nextGaussian() + mean;
return basicV;
}
/*Generate a Hyphal extenrion rate with Uniform distribution from 1 to 10*/
private static double generateBasicX()
{
double basicX = 9.0*Map.random.nextDouble() + 1.0;
return basicX;
}
/*Generate a Moisture trade-off factor with Uniform distribution from -1 to 1*/
private static double generateMTradeOff()
{
double mTradeOff = 2.0*Map.random.nextDouble() - 1;
return mTradeOff;
}
/*Calculate a Basic value of decomponent mass per unit area by basicX*/
private static double generatebasicB(double basicX)
{
double basicB;
double x = basicX;
basicB = 3 * Math.log(x+1)/Math.PI;
return basicB;
}
/**
* Get temperature penalty. It is noted that the method is memoriable but idempotent.
* @param temp temperature
* @return the tempPenalty
*/
public static double tempPenalty(double temp){
if (temp == lastTemp) return tempPenalty;
lastTemp = temp;
temp = 0.0629723 * (-22.5 + temp);
double result = 0;
for(int i=0; i<3; i++){
result += A[i] * Math.exp(-Math.pow((temp-B[i])/C[i], 2));
}
tempPenalty = result / 0.765457;
return tempPenalty;
}
/**
*
* @param humidity humidity change, it is an environment factor
* @param mTradeOff Moisture trade off, it is defined by the fungus
* @return The humidity penalty
*/
public static double humidityPenalty(double humidity, double mTradeOff){
double result = Math.exp(0.233 * (1 - 2 * humidity) * mTradeOff + 1.8) / 6.04965;
return result;
}
}