Ignore:
Timestamp:
06/30/20 00:32:56 (4 years ago)
Author:
Maciej Komosinski
Message:

fS: preserved volume during shape-type changes

File:
1 edited

Legend:

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

    r958 r969  
    1010#include "frams/util/rndutil.h"
    1111#include "frams/neuro/neurolibrary.h"
    12 
     12#include "../genooperators.h"
    1313
    1414int fS_Genotype::precision = 4;
    15 
    16 
    17 double round2(double var)
    18 {
    19         double value = (int) (var * 100 + .5);
    20         return (double) value / 100;
    21 }
     15bool fS_Genotype::TURN_WITH_ROTATION = false;
     16
    2217
    2318double fS_stod(const string&  str, int start, size_t* size)
     
    3025        {
    3126                throw fS_Exception("Invalid numeric value", start);
     27        }
     28        catch(const std::out_of_range& ex)
     29        {
     30                throw fS_Exception("Invalid numeric value; out of range", start);
    3231        }
    3332}
     
    3938        fr = _state->fr;
    4039        s = _state->s;
     40        stif = _state->stif;
    4141}
    4242
     
    5555{
    5656        Orient rotmatrix = Orient_1;
    57         rotmatrix.rotate(Pt3D(
    58                         Convert::toRadians(rotation.x),
    59                         Convert::toRadians(rotation.y),
    60                         Convert::toRadians(rotation.z)
    61         ));
     57        rotmatrix.rotate(rotation);
    6258        vector = rotmatrix.transform(vector);
    6359}
     
    115111}
    116112
    117 Node::Node(Substring &restOfGeno, bool _modifierMode, bool _paramMode, bool _cycleMode, Node *_parent)
     113Node::Node(Substring &restOfGeno, Node *_parent)
    118114{
    119115        parent = _parent;
    120         modifierMode = _modifierMode;
    121         paramMode = _paramMode;
    122         cycleMode = _cycleMode;
    123116        partDescription = new Substring(restOfGeno);
    124117
     
    293286                return item->second;
    294287        else
    295                 return defaultParamValues.at(key);
     288                return defaultValues.at(key);
    296289}
    297290
     
    415408}
    416409
    417 double getDistance(Pt3D radiiParent, Pt3D radii, Pt3D vector, Pt3D rotationParent, Pt3D rotation)
    418 {
     410double Node::getDistance()
     411{
     412        Pt3D size = calculateSize();
     413        Pt3D parentSize = parent->calculateSize();      // Here we are sure that parent is not nullptr
    419414        int parentSphereCount, sphereCount;
    420415        double parentSphereRadius, sphereRadius;
    421         Pt3D *centersParent = findSphereCenters(parentSphereCount, parentSphereRadius, radiiParent, rotationParent);
    422         Pt3D *centers = findSphereCenters(sphereCount, sphereRadius, radii, rotation);
     416        Pt3D *centersParent = findSphereCenters(parentSphereCount, parentSphereRadius, parentSize, parent->getRotation());
     417        Pt3D *centers = findSphereCenters(sphereCount, sphereRadius, size, getRotation());
    423418
    424419        double distanceThreshold = sphereRadius + parentSphereRadius;
    425420        double minDistance = 0.0;
    426         double maxDistance = 2 * (max3(radiiParent) + max3(radii));
     421        double maxDistance = 2 * (max3(parentSize) + max3(size));
    427422        double currentDistance = avg(maxDistance, minDistance);
    428423        int result = -1;
     424        int iterationNo = 0;
    429425        while (result != ADJACENT)
    430426        {
    431                 Pt3D currentVector = vector * currentDistance;
     427                iterationNo++;
     428                Pt3D currentVector = state->v * currentDistance;
    432429                result = isCollision(centersParent, centers, parentSphereCount, sphereCount, currentVector, distanceThreshold);
     430
    433431                if (result == DISJOINT)
    434432                {
     
    440438                        currentDistance = avg(maxDistance, currentDistance);
    441439                }
     440
     441                if(maxDistance <= 0 || iterationNo > 1000)
     442                        throw fS_Exception("Computing of distances between parts failed", 0);
    442443                if (currentDistance > maxDistance)
     444                {
    443445                        throw fS_Exception("Internal error; then maximal distance between parts exceeded.", 0);
     446                }
    444447                if (currentDistance < minDistance)
    445448                        throw fS_Exception("Internal error; the minimal distance between parts exceeded.", 0);
     
    449452        delete[] centersParent;
    450453        delete[] centers;
    451         return round2(currentDistance);
    452 }
    453 
    454 void Node::getState(State *_state, const Pt3D &parentSize)
     454        return currentDistance;
     455}
     456
     457void Node::getState(State *_state)
    455458{
    456459        if (state != nullptr)
     
    473476                else if (mod == MODIFIERS[2])
    474477                        state->s *= multiplier;
    475         }
    476 
    477         Pt3D size = calculateSize();
     478                else if (mod == MODIFIERS[3])
     479                        state->stif *= multiplier;
     480        }
     481
    478482        if (parent != nullptr)
    479483        {
     
    481485                state->rotate(getVectorRotation());
    482486
    483                 double distance = getDistance(parentSize, size, state->v, getRotation(), getRotation());
     487                double distance = getDistance();
    484488                state->addVector(distance);
    485489        }
    486490        for (int i = 0; i < int(children.size()); i++)
    487                 children[i]->getState(state, size);
     491                children[i]->getState(state);
    488492}
    489493
     
    493497        for (int i = 0; i < int(branches.size()); i++)
    494498        {
    495                 children.push_back(new Node(branches[i], modifierMode, paramMode, cycleMode, this));
     499                children.push_back(new Node(branches[i], this));
    496500        }
    497501}
     
    593597Pt3D Node::getVectorRotation()
    594598{
    595         double rx = getParam(ROT_X);
    596         double ry = getParam(ROT_Y);
    597         double rz = getParam(ROT_Z);
    598         return Pt3D(rx, ry, rz);
     599        return Pt3D(getParam(ROT_X), getParam(ROT_Y), getParam(ROT_Z));
    599600}
    600601
    601602Pt3D Node::getRotation()
    602603{
    603         double rx = getParam(RX);
    604         double ry = getParam(RY);
    605         double rz = getParam(RZ);
    606         return Pt3D(rx, ry, rz);
     604        Pt3D rotation = Pt3D(getParam(RX), getParam(RY), getParam(RZ));
     605        if(fS_Genotype::TURN_WITH_ROTATION)
     606                rotation += getVectorRotation();
     607        return rotation;
    607608}
    608609
     
    614615                addJointsToModel(model, parent);
    615616
    616 
    617617        for (int i = 0; i < int(neurons.size()); i++)
    618618        {
     
    639639{
    640640        part = new Part(partType);
    641         part->p = Pt3D(round2(state->location.x),
    642                                    round2(state->location.y),
    643                                    round2(state->location.z));
    644 
    645         part->friction = round2(getParam(FRICTION) * state->fr);
    646         part->ingest = round2(getParam(INGESTION) * state->ing);
     641        part->p = Pt3D(state->location.x,
     642                                   state->location.y,
     643                                   state->location.z);
     644
     645        part->friction = getParam(FRICTION) * state->fr;
     646        part->ingest = getParam(INGESTION) * state->ing;
    647647        Pt3D size = calculateSize();
    648         part->scale.x = round2(size.x);
    649         part->scale.y = round2(size.y);
    650         part->scale.z = round2(size.z);
     648        part->scale.x = size.x;
     649        part->scale.y = size.y;
     650        part->scale.z = size.z;
    651651        part->setRot(getRotation());
    652652}
     
    655655{
    656656        Joint *j = new Joint();
     657        j->stif = getParam(STIFFNESS) * state->stif;
     658        j->rotstif = j->stif;
     659
    657660        j->attachToParts(parent->part, part);
    658661        switch (joint)
     
    698701                        if (i != 0)
    699702                                result += NEURON_SEPARATOR;
    700                         if (n->getClassName() != "N")
    701                         {
    702                                 result += n->getDetails();
    703                                 if (!n->inputs.empty())
    704                                         result += NEURON_INTERNAL_SEPARATOR;
    705                         }
     703
     704                        result += n->getDetails();
     705                        if (!n->inputs.empty())
     706                                result += NEURON_INTERNAL_SEPARATOR;
     707
    706708                        for (auto it = n->inputs.begin(); it != n->inputs.end(); ++it)
    707709                        {
     
    714716                                        result += SString::valueOf(it->second);
    715717                                }
    716 
    717718                        }
    718719                }
     
    754755
    755756
    756 bool Node::changeSizeParam(string paramKey, double multiplier, bool ensureCircleSection)
    757 {
    758         double oldValue = getParam(paramKey);
    759         params[paramKey] = oldValue * multiplier;
     757bool Node::changeSizeParam(string key, bool ensureCircleSection)
     758{
     759        double oldValue = getParam(key);
     760        params[key] = GenoOperators::mutateCreep('f', params[key], minValues.at(key), maxValues.at(key), true);
    760761        if (!ensureCircleSection || isPartSizeValid())
    761762                return true;
    762763        else
    763764        {
    764                 params[paramKey] = oldValue;
     765                params[key] = oldValue;
    765766                return false;
    766767        }
     
    786787        {
    787788                string geno = genotype.c_str();
    788                 // M - modifier mode, S - standard mode
    789                 size_t modeSeparatorIndex = geno.find(':');
    790                 if (modeSeparatorIndex == string::npos)
    791                         throw fS_Exception("No mode separator", 0);
    792 
    793                 string modeStr = geno.substr(0, modeSeparatorIndex).c_str();
    794                 bool modifierMode = modeStr.find(MODIFIER_MODE) != string::npos;
    795                 bool paramMode = modeStr.find(PARAM_MODE) != string::npos;
    796                 bool cycleMode = modeStr.find(CYCLE_MODE) != string::npos;
    797 
    798                 int actualGenoStart = modeSeparatorIndex + 1;
    799                 Substring substring(geno.c_str(), actualGenoStart, geno.length() - actualGenoStart);
    800                 startNode = new Node(substring, modifierMode, paramMode, cycleMode, nullptr);
     789                Substring substring(geno.c_str(), 0, geno.length());
     790                startNode = new Node(substring, nullptr);
    801791                validateNeuroInputs();
    802792        }
     
    816806{
    817807        State *initialState = new State(Pt3D(0), Pt3D(1, 0, 0));
    818         startNode->getState(initialState, Pt3D(1.0));
    819 }
    820 
    821 double fS_Genotype::randomParamMultiplier()
    822 {
    823         double multiplier = 1 + fabs(RndGen.GaussStd());
    824         if (multiplier > PARAM_MAX_MULTIPLIER)
    825                 multiplier = PARAM_MAX_MULTIPLIER;
    826         if (rndUint(2) == 0)
    827                 multiplier = 1.0 / multiplier;
    828         return multiplier;
     808        startNode->getState(initialState);
    829809}
    830810
     
    833813        getState();
    834814        startNode->buildModel(model, nullptr);
    835 
    836815        buildNeuroConnections(model);
    837 
    838         // Additional joints
    839         vector<Node*> allNodes = getAllNodes();
    840         for (int i = 0; i < int(allNodes.size()); i++)
    841         {
    842                 Node *node = allNodes[i];
    843                 if (node->params.find(JOINT_DISTANCE) != node->params.end())
    844                 {
    845                         Node *otherNode = getNearestNode(allNodes, node);
    846                         if (otherNode != nullptr)
    847                         {
    848                                 // If other node is close enough, add a joint
    849                                 double distance = node->state->location.distanceTo(otherNode->state->location);
    850                                 if (distance < node->params[JOINT_DISTANCE])
    851                                 {
    852                                         Joint *joint = new Joint();
    853                                         joint->attachToParts(node->part, otherNode->part);
    854 
    855                                         joint->shape = Joint::Shape::SHAPE_FIXED;
    856                                         model.addJoint(joint);
    857                                 }
    858                         }
    859                 }
    860         }
    861816}
    862817
     
    905860        SString geno;
    906861        geno.memoryHint(100);     // Provide a small buffer from the start to improve performance
    907 
    908         if (startNode->modifierMode)
    909                 geno += MODIFIER_MODE;
    910         if (startNode->paramMode)
    911                 geno += PARAM_MODE;
    912         if (startNode->cycleMode)
    913                 geno += CYCLE_MODE;
    914 
    915         geno += ':';
    916862        startNode->getGeno(geno);
    917863        return geno;
     
    1010956                if (!nodes[i]->isPartSizeValid())
    1011957                {
    1012                         return nodes[i]->partDescription->start;
     958                        return 1 + nodes[i]->partDescription->start;
    1013959                }
    1014960        }
Note: See TracChangeset for help on using the changeset viewer.