Ignore:
Timestamp:
06/07/17 12:01:16 (3 years ago)
Author:
Maciej Komosinski
Message:
  • fF foraminifera encoding supports scaling (radius) of the initial chamber (three new parameters added: radii for x,y,z)
  • mutation ignores these three parameters
  • float -> double for consistency everywhere
File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/genetics/fF/conv_fF.cpp

    r544 r667  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2017  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    1010GenoConv_fF0::GenoConv_fF0()
    1111{
    12         name = "7-value Foraminifera encoding";
     12        name = "10-parameter Foraminifera encoding";
    1313        in_format = 'F';
    1414        out_format = '0';
     
    4242                return ""; //so we return an invalid f0 genotype
    4343
    44         double div_radius_length = 1; //div_radius_length=1 or kx=ky=kz=1
    45         double radius = 1;
    46 
    4744        Model m;
    4845        m.open();
     
    5249        fF_chamber3d **chambers = new fF_chamber3d*[gp.number_of_chambers];
    5350        for (int i = 0; i < gp.number_of_chambers; i++)
    54                 createSphere(i, chambers, radius, div_radius_length, gp.translation, gp.angle1, gp.angle2, gp.scalex, gp.scaley, gp.scalez);
     51                createSphere(i, chambers, gp.radius0x, gp.radius0y, gp.radius0z, gp.translation, gp.angle1, gp.angle2, gp.scalex, gp.scaley, gp.scalez);
    5552
    5653        Part *p1 = addNewPart(&m, chambers[0]);
     54        p1->scale = Pt3D(gp.radius0x, gp.radius0y, gp.radius0z); //size of the initial chamber
    5755        for (int i = 1; i < gp.number_of_chambers; i++)
    5856        {
     
    7169}
    7270
    73 void GenoConv_fF0::createSphere(int which, fF_chamber3d **chambers, double radius_, double div_radius_length_, double div_vector_length_,
    74         double alpha_, double gamma_, double kx_, double ky_, double kz_)
    75 {
    76         chambers[which] = new fF_chamber3d(0.0f, 0.0f, 0.0f,
    77                 (float)radius_, (float)radius_ * (float)kx_, 0.0f, 0.0f,
    78                 (float)(radius_ * div_vector_length_), 0.0f, 0.0f, 0.0f, 0.0f);
     71void GenoConv_fF0::createSphere(int which, fF_chamber3d **chambers, double radius0x, double radius0y, double radius0z, double translation, double alpha_, double gamma_, double kx_, double ky_, double kz_)
     72{
     73        chambers[which] = new fF_chamber3d(0.0, 0.0, 0.0,
     74                radius0x, radius0y, radius0z, radius0x * kx_, 0.0, 0.0,
     75                radius0x * translation, 0.0, 0.0, 0.0, 0.0);
    7976        if (which == 0)
    80                 chambers[which]->points = generate_points(chambers[which], which, kx_, ky_, kz_);
    81         if (which > 0) {
    82                 /* old radius */
    83                 double radiusOld, radius;
    84                 radiusOld = chambers[which - 1]->radius;
    85                 radius = div_radius_length_ * radiusOld;
     77                chambers[which]->points = generate_points(chambers[which]);
     78        if (which > 0)
     79        {
     80                chambers[which]->radius_x = get_radius(chambers[which - 1]->radius_x, kx_, chambers[0]->radius_x);
     81                chambers[which]->radius_y = get_radius(chambers[which - 1]->radius_y, ky_, chambers[0]->radius_y);
     82                chambers[which]->radius_z = get_radius(chambers[which - 1]->radius_z, kz_, chambers[0]->radius_z);
     83
    8684                /* new growth vector length */
    87                 double len = radius * div_vector_length_;
    88                 if (radius < fF_TOO_LITTLE) {
    89                         radius = fF_TOO_LITTLE;
    90                         if (fabs(len) > (fF_TOO_MUCH * radius)) {
    91                                 len = ((len < 0) ? (-1) : 1) * fF_TOO_MUCH * radius;
    92                         }
    93                 }
    94                 if (len == 0) {
     85                double len = chambers[which]->radius_y * translation;
     86                double max_radius = fF_TOO_MUCH * chambers[which]->radius_y;
     87                if (fabs(len) > (max_radius))
     88                        len = ((len < 0) ? (-1) : 1) * max_radius;
     89                if (len == 0)
    9590                        len = -0.0000001;
    96                 }
    9791
    9892                /* aperture of the previous chamber */
     
    131125                double alpha = angle - alpha_;
    132126
    133 
    134127                double gamma = chambers[which - 1]->phi + gamma_;
    135128
    136                 /* x */
    137129                double wx = len * cos(alpha);
    138                 /* y */
    139130                double wy = len * sin(alpha);
    140                 /* y */
    141131                double wz = len * sin(alpha) * sin(gamma);
    142132
     
    146136                double z = pzz + wz;
    147137
    148                 chambers[which]->centerX = (float)x;
    149                 chambers[which]->centerY = (float)y;
    150                 chambers[which]->centerZ = (float)z;
    151                 chambers[which]->radius = (float)radius;
    152                 chambers[which]->vectorTfX = (float)wx;
    153                 chambers[which]->vectorTfY = (float)wy;
    154                 chambers[which]->vectorTfZ = (float)wz;
    155                 chambers[which]->beta = (float)alpha;
    156                 chambers[which]->phi = (float)gamma;
    157 
    158                 chambers[which]->points = generate_points(chambers[which], which, kx_, ky_, kz_);
    159                 search_hid(which, chambers, kx_, ky_, kz_);
     138                chambers[which]->centerX = x;
     139                chambers[which]->centerY = y;
     140                chambers[which]->centerZ = z;
     141                chambers[which]->vectorTfX = wx;
     142                chambers[which]->vectorTfY = wy;
     143                chambers[which]->vectorTfZ = wz;
     144                chambers[which]->beta = alpha;
     145                chambers[which]->phi = gamma;
     146
     147                chambers[which]->points = generate_points(chambers[which]);
     148                search_hid(which, chambers);
    160149                int pun;
    161                 pun = find_hole(which, pzx, pzy, pzz, chambers, kx_, ky_, kz_);
    162 
    163                 chambers[which]->holeX = (float)chambers[which]->points[pun].x;
    164                 chambers[which]->holeY = (float)chambers[which]->points[pun].y;
    165                 chambers[which]->holeZ = (float)chambers[which]->points[pun].z;
    166         }
     150                pun = find_hole(which, pzx, pzy, pzz, chambers);
     151                if (pun < 0) //should never happen
     152                {
     153                        logPrintf("GenoConv_fF0", "createSphere", LOG_ERROR, "find_hole(%d) returned %d", which, pun);
     154                        pun = 0;
     155                }
     156                chambers[which]->holeX = chambers[which]->points[pun].x;
     157                chambers[which]->holeY = chambers[which]->points[pun].y;
     158                chambers[which]->holeZ = chambers[which]->points[pun].z;
     159        }
     160}
     161
     162double GenoConv_fF0::get_radius(double prev_radius, double scale, double start_radius)
     163{
     164        double radius = prev_radius * scale;
     165        double min_radius = fF_TOO_LITTLE*start_radius;
     166        if (radius < min_radius) {
     167                radius = min_radius;
     168        }
     169
     170        return radius;
    167171}
    168172
    169173void GenoConv_fF0::precompute_cos_and_sin()
    170174{
    171         int i;
    172         double pi = acos(-1.0);
    173         double angle = pi / (((double)fF_LATITUDE_NUM)*0.5);
    174         for (i = 0; i < fF_LATITUDE_NUM; i++)
    175         {
    176                 cosines[i] = cos((double)i * angle);
    177                 sines[i] = sin((double)i * angle);
    178         }
    179 }
    180 
    181 fF_point* GenoConv_fF0::generate_points(fF_chamber3d *chamber, int which, double kx_, double ky_, double kz_)
    182 {
    183         float radius = chamber->radius;
    184         float cenx = chamber->centerX;
    185         float ceny = chamber->centerY;
    186         float cenz = chamber->centerZ;
    187 
    188         double maxX = 0;
    189         double maxY = 0;
    190         double minX = 0;
    191         double minY = 0;
    192         double minZ = 0;
    193 
    194         double kx = 1;
    195         double ky = 1;
    196         double kz = 1;
    197 
    198         if (which > 0)
    199         {
    200                 for (int kt = 1; kt < (which + 1); kt++)
    201                 {
    202                         kx = kx * kx_;
    203                         ky = ky * ky_;
    204                         kz = kz * kz_;
    205                 }
    206         }
    207 
    208         bool all_k_ones = kx_ == 1 && ky_ == 1 && kz_ == 1;
    209 
    210         double rx = all_k_ones ? radius : kx;
    211         double ry = all_k_ones ? radius : ky;
    212         double rz = all_k_ones ? radius : kz;
     175        double angle = M_PI * 2 / fF_LATITUDE_NUM;
     176        for (int i = 0; i < fF_LATITUDE_NUM; i++)
     177        {
     178                cosines[i] = cos(i * angle);
     179                sines[i] = sin(i * angle);
     180        }
     181}
     182
     183fF_point* GenoConv_fF0::generate_points(fF_chamber3d *chamber)
     184{
     185        double cenx = chamber->centerX;
     186        double ceny = chamber->centerY;
     187        double cenz = chamber->centerZ;
     188
     189        double rx = chamber->radius_x;
     190        double ry = chamber->radius_y;
     191        double rz = chamber->radius_z;
    213192
    214193        fF_point *points = new fF_point[fF_SIZE];
     
    227206                        p.z = z;
    228207                        p.inside = false;
    229 
    230                         if (x < minX) minX = x;
    231                         if (x > maxX) maxX = x;
    232                         if (y < minY) minY = y;
    233                         if (y > maxY) maxY = y;
    234 
    235                         if (z < minZ) minZ = z;
    236208                }
    237209        }
     
    240212}
    241213
     214template<typename T> T Square(T x) { return x * x; }
     215
    242216double GenoConv_fF0::dist(double x1, double y1, double z1, double x2, double y2, double z2)
    243217{
    244         return sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1) + (z2 - z1)*(z2 - z1));
    245 }
    246 
    247 void GenoConv_fF0::search_hid(int nr, fF_chamber3d **spheres, double kx_, double ky_, double kz_)
    248 {
    249         double kxsq = kx_*kx_;
    250         double kysq = ky_*ky_;
    251         double kzsq = kz_*kz_;
    252 
     218        return sqrt(Square(x2 - x1) + Square(y2 - y1) + Square(z2 - z1));
     219}
     220
     221void GenoConv_fF0::search_hid(int nr, fF_chamber3d **chambers)
     222{
    253223        for (int i = 0; i < nr; i++)
    254224        {
    255                 double srX0 = spheres[i]->centerX;
    256                 double srY0 = spheres[i]->centerY;
    257                 double srZ0 = spheres[i]->centerZ;
    258 
    259                 double radsq = spheres[i]->radius * spheres[i]->radius;
    260 
    261                 double a2 = kx_ != 1 ? kxsq : radsq;
    262                 double b2 = ky_ != 1 ? kysq : radsq;
    263                 double c2 = kzsq * radsq;
     225                fF_chamber3d *chamber = chambers[i];
     226
     227                double rx_sq = Square(chamber->radius_x);
     228                double ry_sq = Square(chamber->radius_y);
     229                double rz_sq = Square(chamber->radius_z);
    264230
    265231                for (int j = 0; j < fF_AMOUNT; j++)
    266232                {
    267                         fF_point &p = spheres[nr]->points[j];
    268 
    269                         double up1 = (p.x - srX0) * (p.x - srX0);
    270                         double up2 = (p.y - srY0) * (p.y - srY0);
    271                         double up3 = (p.z - srZ0) * (p.z - srZ0);
    272 
    273                         double exp1 = up1 / a2;
    274                         double exp2 = up2 / b2;
    275                         double exp3 = up3 / c2;
    276 
    277                         double result = exp1 + exp2 + exp3;
     233                        fF_point &p = chambers[nr]->points[j];
     234
     235                        double upx = Square(p.x - chamber->centerX);
     236                        double upy = Square(p.y - chamber->centerY);
     237                        double upz = Square(p.z - chamber->centerZ);
     238
     239                        double expx = upx / rx_sq;
     240                        double expy = upy / ry_sq;
     241                        double expz = upz / rz_sq;
     242
     243                        double result = expx + expy + expz;
    278244
    279245                        if (result < fF_THICK_RATIO)
     
    285251}
    286252
    287 int GenoConv_fF0::find_hole(int which, double x, double y, double z, fF_chamber3d **chambers, double kx_, double ky_, double kz_)
     253int GenoConv_fF0::find_hole(int which, double x, double y, double z, fF_chamber3d **chambers)
    288254{
    289255        int found = -1;
    290256        double distsq_found;
    291257
    292         double kxsq = kx_*kx_;
    293         double kysq = ky_*ky_;
    294         double kzsq = kz_*kz_;
    295 
    296258        for (int i = 0; i < fF_AMOUNT; i++)
    297259        {
     
    299261                if (!p.inside) //it is not inside another chamber
    300262                {
    301                         double distancesq = (p.x - x)*(p.x - x) + (p.y - y)*(p.y - y) + (p.z - z)*(p.z - z);
     263                        double distancesq = Square(p.x - x) + Square(p.y - y) + Square(p.z - z);
    302264                        if (found < 0)
    303265                        {
     
    312274                                        for (int j = 0; j < which && good; j++)
    313275                                        {
    314                                                 double srX0 = chambers[j]->centerX;
    315                                                 double srY0 = chambers[j]->centerY;
    316                                                 double srZ0 = chambers[j]->centerZ;
    317 
    318                                                 double radsq = chambers[j]->radius * chambers[j]->radius;
    319 
    320                                                 double a2 = kxsq * radsq;
    321                                                 double b2 = kysq * radsq;
    322                                                 double c2 = kzsq * radsq;
    323 
    324                                                 double up1 = (p.x - srX0) * (p.x - srX0);
    325                                                 double up2 = (p.y - srY0) * (p.y - srY0);
    326                                                 double up3 = (p.z - srZ0) * (p.z - srZ0);
    327 
    328                                                 double exp1 = up1 / a2;
    329                                                 double exp2 = up2 / b2;
    330                                                 double exp3 = up3 / c2;
    331 
    332                                                 double result = exp1 + exp2 + exp3;
     276                                                fF_chamber3d *chamber = chambers[j];
     277
     278                                                double rx_sq = Square(chamber->radius_x);
     279                                                double ry_sq = Square(chamber->radius_y);
     280                                                double rz_sq = Square(chamber->radius_z);
     281
     282                                                double upx = Square(p.x - chamber->centerX);
     283                                                double upy = Square(p.y - chamber->centerY);
     284                                                double upz = Square(p.z - chamber->centerZ);
     285
     286                                                double expx = upx / rx_sq;
     287                                                double expy = upy / ry_sq;
     288                                                double expz = upz / rz_sq;
     289
     290                                                double result = expx + expy + expz;
    333291                                                if (result < 1.0)
    334292                                                {
Note: See TracChangeset for help on using the changeset viewer.