Ignore:
Timestamp:
11/26/20 01:30:40 (3 years ago)
Author:
Maciej Komosinski
Message:

fS: refactoring

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/genetics/fS/fS_oper.cpp

    r1017 r1030  
    5151                if (errorPosition != 0)
    5252                {
    53                         logPrintf("GenoOper_fS", "checkValidity", LOG_WARN, "Invalid part size");
     53                        logPrintf("GenoOper_fS", "checkValidity", LOG_WARN, "Invalid part scale");
    5454                        return errorPosition;
    5555                }
     
    226226const char *GenoOper_fS::getSimplest()
    227227{
    228         return "1.1:C{x=0.80599;y=0.80599;z=0.80599}";
     228        return "1.1,0,0.4:C{x=0.80599;y=0.80599;z=0.80599}";
    229229}
    230230
     
    297297        geno.getState(false);
    298298        Node *node = geno.chooseNode();
    299         char partType = SHAPE_TO_GENE.at(availablePartShapes[rndUint(availablePartShapes.size())]);
    300 
    301         Substring substring(&partType, 0, 1);
     299        char partShape = SHAPE_TO_GENE.at(availablePartShapes[rndUint(availablePartShapes.size())]);
     300
     301        Substring substring(&partShape, 0, 1);
    302302        Node *newNode = new Node(substring, node, node->genotypeParams);
    303303        // Add random rotation
     
    322322                newNode->params[selectedParam] = RndGen.Uni(-M_PI / 2, M_PI / 2);
    323323        }
    324         // Assign part size to default value
    325         double volumeMultiplier = pow(node->getParam(SIZE) * node->state->s, 3);
     324        // Assign part scale to default value
     325        double volumeMultiplier = pow(node->getParam(SCALE) * node->state->s, 3);
    326326        double minVolume = Model::getMinPart().volume;
    327327        double defVolume = Model::getDefPart().volume * volumeMultiplier;    // Default value after applying modifiers
     
    330330        double relativeVolume = volume / volumeMultiplier;    // Volume without applying modifiers
    331331
    332         double newRadius = std::cbrt(relativeVolume / volumeMultipliers.at(newNode->partType));
    333         newNode->params[SIZE_X] = newRadius;
    334         newNode->params[SIZE_Y] = newRadius;
    335         newNode->params[SIZE_Z] = newRadius;
     332        double newRadius = std::cbrt(relativeVolume / volumeMultipliers.at(newNode->partShape));
     333        newNode->params[SCALE_X] = newRadius;
     334        newNode->params[SCALE_Y] = newRadius;
     335        newNode->params[SCALE_Z] = newRadius;
    336336        node->children.push_back(newNode);
    337337
     
    339339        {
    340340                geno.getState(false);
    341                 mutateSizeParam(newNode, SIZE_X, true);
    342                 mutateSizeParam(newNode, SIZE_Y, true);
    343                 mutateSizeParam(newNode, SIZE_Z, true);
     341                mutateScaleParam(newNode, SCALE_X, true);
     342                mutateScaleParam(newNode, SCALE_Y, true);
     343                mutateScaleParam(newNode, SCALE_Z, true);
    344344        }
    345345        return true;
     
    350350        Node *randomNode, *selectedChild;
    351351        // Choose a parent with children
    352         // It may be difficult to choose a eligible node, so the number of tries should be high
     352        // It may be difficult to choose an eligible node, so the number of tries should be high
    353353        for (int i = 0; i < 10 * mutationTries; i++)
    354354        {
     
    380380                Node *randomNode = geno.chooseNode();
    381381                int index = rndUint(availShapesLen);
    382                 if (availablePartShapes[index] == randomNode->partType)
     382                if (availablePartShapes[index] == randomNode->partShape)
    383383                        index = (index + 1 + rndUint(availShapesLen - 1)) % availShapesLen;
    384384                Part::Shape newType = availablePartShapes[index];
    385385
    386386#ifdef _DEBUG
    387                 if(newType == randomNode->partType)
     387                if(newType == randomNode->partShape)
    388388                        throw fS_Exception("Internal error: invalid part type chosen in mutation.", 1);
    389389#endif
    390390
    391391                geno.getState(false);
    392                 double sizeMultiplier = randomNode->getParam(SIZE) * randomNode->state->s;
    393                 double relativeVolume = randomNode->calculateVolume() / pow(sizeMultiplier, 3.0);
    394 
    395                 if (!ensureCircleSection || newType == Part::Shape::SHAPE_CUBOID || (randomNode->partType == Part::Shape::SHAPE_ELLIPSOID && newType == Part::Shape::SHAPE_CYLINDER))
    396                 {
    397                         double radiusQuotient = std::cbrt(volumeMultipliers.at(randomNode->partType) / volumeMultipliers.at(newType));
    398                         randomNode->params[SIZE_X] = randomNode->getParam(SIZE_X) * radiusQuotient;
    399                         randomNode->params[SIZE_Y] = randomNode->getParam(SIZE_Y) * radiusQuotient;
    400                         randomNode->params[SIZE_Z] = randomNode->getParam(SIZE_Z) * radiusQuotient;
    401                 } else if (randomNode->partType == Part::Shape::SHAPE_CUBOID && newType == Part::Shape::SHAPE_CYLINDER)
    402                 {
    403                         double newRadius = 0.5 * (randomNode->getParam(SIZE_X) + randomNode->getParam(SIZE_Y));
    404                         randomNode->params[SIZE_X] = 0.5 * relativeVolume / (M_PI * newRadius * newRadius);
    405                         randomNode->params[SIZE_Y] = newRadius;
    406                         randomNode->params[SIZE_Z] = newRadius;
     392                double scaleMultiplier = randomNode->getParam(SCALE) * randomNode->state->s;
     393                double relativeVolume = randomNode->calculateVolume() / pow(scaleMultiplier, 3.0);
     394
     395                if (!ensureCircleSection || newType == Part::Shape::SHAPE_CUBOID || (randomNode->partShape == Part::Shape::SHAPE_ELLIPSOID && newType == Part::Shape::SHAPE_CYLINDER))
     396                {
     397                        double radiusQuotient = std::cbrt(volumeMultipliers.at(randomNode->partShape) / volumeMultipliers.at(newType));
     398                        randomNode->params[SCALE_X] = randomNode->getParam(SCALE_X) * radiusQuotient;
     399                        randomNode->params[SCALE_Y] = randomNode->getParam(SCALE_Y) * radiusQuotient;
     400                        randomNode->params[SCALE_Z] = randomNode->getParam(SCALE_Z) * radiusQuotient;
     401                } else if (randomNode->partShape == Part::Shape::SHAPE_CUBOID && newType == Part::Shape::SHAPE_CYLINDER)
     402                {
     403                        double newRadius = 0.5 * (randomNode->getParam(SCALE_X) + randomNode->getParam(SCALE_Y));
     404                        randomNode->params[SCALE_X] = 0.5 * relativeVolume / (M_PI * newRadius * newRadius);
     405                        randomNode->params[SCALE_Y] = newRadius;
     406                        randomNode->params[SCALE_Z] = newRadius;
    407407                } else if (newType == Part::Shape::SHAPE_ELLIPSOID)
    408408                {
    409409                        double newRelativeRadius = cbrt(relativeVolume / volumeMultipliers.at(newType));
    410                         randomNode->params[SIZE_X] = newRelativeRadius;
    411                         randomNode->params[SIZE_Y] = newRelativeRadius;
    412                         randomNode->params[SIZE_Z] = newRelativeRadius;
     410                        randomNode->params[SCALE_X] = newRelativeRadius;
     411                        randomNode->params[SCALE_Y] = newRelativeRadius;
     412                        randomNode->params[SCALE_Z] = newRelativeRadius;
    413413                } else
    414414                {
    415415                        throw fS_Exception("Invalid part type", 1);
    416416                }
    417                 randomNode->partType = newType;
     417                randomNode->partShape = newType;
    418418                return true;
    419419        }
     
    446446                return false;
    447447        // Do not allow invalid changes in part size
    448         bool isRadiusOfBase = key == SIZE_Y || key == SIZE_Z;
    449         bool isRadius = isRadiusOfBase || key == SIZE_X;
     448        bool isRadiusOfBase = key == SCALE_Y || key == SCALE_Z;
     449        bool isRadius = isRadiusOfBase || key == SCALE_X;
    450450        if (ensureCircleSection && isRadius)
    451451        {
    452                 if (randomNode->partType == Part::Shape::SHAPE_ELLIPSOID)
     452                if (randomNode->partShape == Part::Shape::SHAPE_ELLIPSOID)
    453453                        return false;
    454                 if (randomNode->partType == Part::Shape::SHAPE_CYLINDER && isRadiusOfBase)
     454                if (randomNode->partShape == Part::Shape::SHAPE_CYLINDER && isRadiusOfBase)
    455455                        return false;
    456456        }
     
    490490bool GenoOper_fS::mutateParamValue(Node *node, string key)
    491491{
    492         // Do not allow invalid changes in part size
    493         if (std::find(SIZE_PARAMS.begin(), SIZE_PARAMS.end(), key) == SIZE_PARAMS.end())
    494         {
    495                 node->params[key] = GenoOperators::mutateCreep('f', node->getParam(key), Node::minValues.at(key), Node::maxValues.at(key), true);
     492        // Do not allow invalid changes in part scale
     493        if (std::find(SCALE_PARAMS.begin(), SCALE_PARAMS.end(), key) == SCALE_PARAMS.end())
     494        {
     495                double max = Node::maxValues.at(key);
     496                double min = Node::minValues.at(key);
     497                double stddev = (max - min) * node->genotypeParams.paramMutationStrength;
     498                node->params[key] = GenoOperators::mutateCreep('f', node->getParam(key), min, max, stddev, true);
    496499                return true;
    497500        } else
    498                 return mutateSizeParam(node, key, ensureCircleSection);
     501                return mutateScaleParam(node, key, ensureCircleSection);
    499502}
    500503
     
    524527        randomNode->modifiers[randomModifier] += rndUint(2) == 0 ? 1 : -1;
    525528
    526         bool isSizeMod = tolower(randomModifier) == SIZE_MODIFIER;
     529        bool isSizeMod = tolower(randomModifier) == SCALE_MODIFIER;
    527530        if (isSizeMod && geno.checkValidityOfPartSizes() != 0)
    528531        {
     
    678681}
    679682
    680 bool GenoOper_fS::mutateSizeParam(Node *node, string key, bool ensureCircleSection)
     683bool GenoOper_fS::mutateScaleParam(Node *node, string key, bool ensureCircleSection)
    681684{
    682685        double oldValue = node->getParam(key);
    683686        double volume = node->calculateVolume();
    684687        double valueAtMinVolume, valueAtMaxVolume;
    685         if(key == SIZE)
     688        if(key == SCALE)
    686689        {
    687690                valueAtMinVolume = oldValue * std::cbrt(Model::getMinPart().volume / volume);
     
    696699        double min = std::max(Node::minValues.at(key), valueAtMinVolume);
    697700        double max = std::min(Node::maxValues.at(key), valueAtMaxVolume);
    698 
    699         node->params[key] = GenoOperators::mutateCreep('f', node->getParam(key), min, max, true);
    700 
    701         if (!ensureCircleSection || node->isPartSizeValid())
     701        double stdev = (max - min) * node->genotypeParams.paramMutationStrength;
     702
     703        node->params[key] = GenoOperators::mutateCreep('f', node->getParam(key), min, max, stdev, true);
     704
     705        if (!ensureCircleSection || node->isPartScaleValid())
    702706                return true;
    703707        else
Note: See TracChangeset for help on using the changeset viewer.