- Timestamp:
- 11/27/20 20:54:50 (4 years ago)
- Location:
- cpp/frams
- Files:
-
- 7 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/genetics/fS/fS_general.cpp
r1030 r1032 12 12 #include "../genooperators.h" 13 13 #include "common/nonstd_math.h" 14 #include " part_distance_estimator.h"14 #include "../../model/geometry/part_distance_estimator.h" 15 15 16 16 int fS_Genotype::precision = 4; … … 81 81 return std::stod(str, size); 82 82 } 83 catch(const std::invalid_argument& ex)83 catch(const std::invalid_argument&) 84 84 { 85 85 throw fS_Exception("Invalid numeric value", start); 86 86 } 87 catch(const std::out_of_range& ex)87 catch(const std::out_of_range&) 88 88 { 89 89 throw fS_Exception("Invalid numeric value; out of range", start); … … 123 123 } 124 124 125 int findEndOfNeuronParamString(SString neuronDefinition) 126 { 127 for(int i=1; i< neuronDefinition.size(); i++) 128 { 129 if(neuronDefinition[i - 1] == ',' && isdigit(neuronDefinition[i])) 130 return i - 1; 131 } 132 133 return neuronDefinition.size(); 134 } 125 135 126 136 fS_Neuron::fS_Neuron(const char *str, int _start, int length) … … 131 141 return; 132 142 133 vector<SString> inputStrings; 134 strSplit(SString(str, length), NEURON_INTERNAL_SEPARATOR, false, inputStrings); 135 if (inputStrings.empty()) 136 return; 137 138 int inputStart = 0; 143 SString neuronDefinition(str, length); 144 int endOfNeuronParamString = findEndOfNeuronParamString(neuronDefinition); 145 SString neuronParamString = neuronDefinition.substr(0, endOfNeuronParamString); 146 SString neuronInputString = neuronDefinition.substr(endOfNeuronParamString + 1); 147 139 148 SString details = "N"; 140 149 141 SString tmp = inputStrings[0];150 SString tmp = neuronParamString; 142 151 if(tmp.indexOf(':') != -1) 143 152 tmp = tmp.substr(0, tmp.indexOf(':')); … … 145 154 if (NeuroLibrary::staticlibrary.findClassIndex(tmp, true) != -1) 146 155 { 147 inputStart = 1; 148 details = inputStrings[0]; 156 details = neuronParamString; 157 } 158 else{ 159 neuronInputString = neuronParamString; 149 160 } 150 161 setDetails(details); 151 162 152 for (int i = inputStart; i < int(inputStrings.size()); i++) 163 vector<SString> inputStrings; 164 strSplit(neuronInputString, NEURON_INTERNAL_SEPARATOR, false, inputStrings); 165 if (inputStrings.empty() || inputStrings[0] == SString()) 166 return; 167 for (int i = 0; i < int(inputStrings.size()); i++) 153 168 { 154 169 SString keyValue = inputStrings[i]; … … 421 436 char c; 422 437 const char *str = restOfGenotype.c_str(); 438 bool insideSpecifiation = false; // True when inside parameter or neuron specification 423 439 for (int i = 0; i < restOfGenotype.len; i++) 424 440 { … … 428 444 if (c == BRANCH_START) 429 445 depth++; 430 else if ((c == BRANCH_SEPARATOR && depth == 1) || i + 1 == restOfGenotype.len) 446 else if (c == PARAM_START || c == NEURON_START) 447 insideSpecifiation = true; 448 else if (c == PARAM_END || c == NEURON_END) 449 insideSpecifiation = false; 450 else if (!insideSpecifiation && ((c == BRANCH_SEPARATOR && depth == 1) || i + 1 == restOfGenotype.len)) 431 451 { 432 452 Substring substring(restOfGenotype); … … 453 473 double Node::calculateVolume() 454 474 { 455 double result; 475 Part *tmpPart = new Part(partShape); 476 calculateScale(tmpPart->scale); 477 return GeometryUtils::calculateSolidVolume(tmpPart); 478 } 479 480 bool Node::isPartScaleValid() 481 { 456 482 Pt3D scale; 457 483 calculateScale(scale); 458 double radiiProduct = scale.x * scale.y * scale.z; 459 switch (partShape) 460 { 461 case Part::Shape::SHAPE_CUBOID: 462 result = 8.0 * radiiProduct; 463 break; 464 case Part::Shape::SHAPE_CYLINDER: 465 result = 2.0 * M_PI * radiiProduct; 466 break; 467 case Part::Shape::SHAPE_ELLIPSOID: 468 result = (4.0 / 3.0) * M_PI * radiiProduct; 469 break; 470 default: 471 logMessage("fS", "calculateVolume", LOG_ERROR, "Invalid part type"); 472 } 473 return result; 474 } 475 476 bool Node::isPartScaleValid() 477 { 478 Pt3D scale; 479 calculateScale(scale); 480 double volume = calculateVolume(); 481 Part_MinMaxDef minP = Model::getMinPart(); 482 Part_MinMaxDef maxP = Model::getMaxPart(); 483 484 if (volume > maxP.volume || minP.volume > volume) 485 return false; 486 if (scale.x < minP.scale.x || scale.y < minP.scale.y || scale.z < minP.scale.z) 487 return false; 488 if (scale.x > maxP.scale.x || scale.y > maxP.scale.y || scale.z > maxP.scale.z) 489 return false; 490 491 if (partShape == Part::Shape::SHAPE_ELLIPSOID && scale.maxComponentValue() != scale.minComponentValue()) 492 // When not all radii have different values 493 return false; 494 if (partShape == Part::Shape::SHAPE_CYLINDER && scale.y != scale.z) 495 // If base radii have different values 496 return false; 497 return true; 484 return GeometryUtils::isSolidPartScaleValid(partShape, scale); 498 485 } 499 486 … … 663 650 } 664 651 665 fS_Genotype::fS_Genotype(const string &g) 666 { 667 string geno(g); 668 geno.erase(remove(geno.begin(), geno.end(), ' '), geno.end()); 669 geno.erase(remove(geno.begin(), geno.end(), '\n'), geno.end()); 652 fS_Genotype::fS_Genotype(const string &geno) 653 { 670 654 try 671 655 { … … 708 692 delete startNode; 709 693 throw e; 710 }711 catch(...)712 {713 delete startNode;714 throw fS_Exception("Unknown exception in fS", 0);715 694 } 716 695 } … … 789 768 geno += doubleToString(gp.modifierMultiplier, precision).c_str(); 790 769 geno += ","; 791 geno += doubleToString(gp.turnWithRotation, precision).c_str();770 geno += std::to_string(int(gp.turnWithRotation)).c_str(); 792 771 geno += ","; 793 772 geno += doubleToString(gp.paramMutationStrength, precision).c_str(); … … 932 911 933 912 double result; 934 try 935 { 936 tmpPart->p = state->v; 937 result = PartDistanceEstimator::calculateDistance(*tmpPart, *parentTmpPart, genotypeParams.distanceTolerance, genotypeParams.relativeDensity); 938 } 939 catch (...) 940 { 941 throw fS_Exception("Exception thrown while calculating distance from parent", 0); 942 } 913 tmpPart->p = state->v; 914 result = PartDistanceEstimator::calculateDistance(*tmpPart, *parentTmpPart, genotypeParams.distanceTolerance, genotypeParams.relativeDensity); 915 943 916 944 917 delete tmpPart; -
cpp/frams/genetics/fS/fS_general.h
r1030 r1032 19 19 #define BRANCH_START '(' 20 20 #define BRANCH_END ')' 21 #define BRANCH_SEPARATOR ' ^'21 #define BRANCH_SEPARATOR ',' 22 22 #define PARAM_START '{' 23 23 #define PARAM_END '}' 24 const char PARAM_SEPARATOR = ' ;';24 const char PARAM_SEPARATOR = ','; 25 25 const char PARAM_KEY_VALUE_SEPARATOR = '='; 26 26 #define NEURON_START '[' 27 27 const char NEURON_END = ']'; 28 28 const char NEURON_SEPARATOR = ';'; 29 const SString NEURON_INTERNAL_SEPARATOR(" '");29 const SString NEURON_INTERNAL_SEPARATOR(","); 30 30 #define NEURON_I_W_SEPARATOR ':' 31 31 //@} … … 274 274 Part *part; /// A part object built from node. Used in building the Model 275 275 int partCodeLen; /// The length of substring that directly describes the corresponding part 276 276 277 static std::map<string, double> minValues; /// Min parameter values 277 278 static std::map<string, double> defaultValues; /// Default parameter values -
cpp/frams/genetics/fS/fS_oper.cpp
r1030 r1032 226 226 const char *GenoOper_fS::getSimplest() 227 227 { 228 return "1.1,0,0.4: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}"; 229 229 } 230 230 -
cpp/frams/genetics/genooperators.cpp
r1023 r1032 455 455 return isupper(firstchar) || firstchar == '|' || firstchar == '@' || firstchar == '*'; 456 456 } 457 458 double GenoOperators::calculateSolidVolume(Part * part)459 {460 double radiiProduct = part->scale.x * part->scale.y * part->scale.z;461 switch (part->shape)462 {463 case Part::Shape::SHAPE_CUBOID:464 return 8.0 * radiiProduct;465 case Part::Shape::SHAPE_CYLINDER:466 return 2.0 * M_PI * radiiProduct;467 case Part::Shape::SHAPE_ELLIPSOID:468 return (4.0 / 3.0) * M_PI * radiiProduct;469 default:470 logMessage("GenoOperators", "calculateSolidVolume", LOG_ERROR, "Unsupported part shape");471 return -1;472 }473 } -
cpp/frams/genetics/genooperators.h
r1023 r1032 215 215 static bool canStartNeuroClassName(const char firstchar); ///<determines if \e firstchar may start NeuroClass name. If not, it might start NeuroClass' (or Neuro's) property name. 216 216 217 static double calculateSolidVolume(Part *part);218 217 219 218 //@} -
cpp/frams/model/geometry/geometryutils.cpp
r1026 r1032 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-20 15Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2020 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 369 369 return M_PI * ((3 * (a+b)) - sqrt((3*a + b) * (a + 3*b))); 370 370 } 371 372 double GeometryUtils::calculateSolidVolume(Part * part) 373 { 374 double radiiProduct = part->scale.x * part->scale.y * part->scale.z; 375 switch (part->shape) 376 { 377 case Part::Shape::SHAPE_CUBOID: 378 return 8.0 * radiiProduct; 379 case Part::Shape::SHAPE_CYLINDER: 380 return 2.0 * M_PI * radiiProduct; 381 case Part::Shape::SHAPE_ELLIPSOID: 382 return (4.0 / 3.0) * M_PI * radiiProduct; 383 default: 384 logMessage("GeometryUtils", "calculateSolidVolume", LOG_ERROR, "Unsupported part shape"); 385 return -1; 386 } 387 } 388 389 bool GeometryUtils::isSolidPartScaleValid(const Part::Shape &partShape, const Pt3D &scale) 390 { 391 Part *tmpPart = new Part(partShape); 392 tmpPart->scale = scale; 393 double volume = GeometryUtils::calculateSolidVolume(tmpPart); 394 395 Part_MinMaxDef minP = Model::getMinPart(); 396 Part_MinMaxDef maxP = Model::getMaxPart(); 397 398 if (volume > maxP.volume || minP.volume > volume) 399 return false; 400 if (scale.x < minP.scale.x || scale.y < minP.scale.y || scale.z < minP.scale.z) 401 return false; 402 if (scale.x > maxP.scale.x || scale.y > maxP.scale.y || scale.z > maxP.scale.z) 403 return false; 404 405 if (partShape == Part::Shape::SHAPE_ELLIPSOID && scale.maxComponentValue() != scale.minComponentValue()) // When any radius has a different value than the others 406 return false; 407 if (partShape == Part::Shape::SHAPE_CYLINDER && scale.y != scale.z) // If base radii have different values 408 return false; 409 return true; 410 } -
cpp/frams/model/geometry/geometryutils.h
r286 r1032 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-20 15Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2020 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 177 177 double ellipsoidArea(const double a, const double b, const double c); 178 178 double ellipsePerimeter(const double a, const double b); 179 180 double calculateSolidVolume(Part *part); 181 bool isSolidPartScaleValid(const Part::Shape &partShape, const Pt3D &scale); 179 182 } 180 183 -
cpp/frams/model/geometry/part_distance_estimator.h
r1031 r1032 56 56 /// tmpPart1 and tmpPart2 are copied for purpose and should not be passed as reference 57 57 /// This function can change some of the properties of those parts 58 /// tmpPart1 will be approximated by surface points. 59 /// The collision between the parts is detected when any of those points is inside tmpPart2 60 /// If tmpPart1 and tmpPart2 are swapped, the calculated distance may slightly differ 58 61 Pt3D directionVersor = tmpPart1.p - tmpPart2.p; 59 62 directionVersor.normalize(); 60 63 61 tmpPart1.p = Pt3D (0);62 tmpPart2.p = Pt3D (0);64 tmpPart1.p = Pt3D_0; 65 tmpPart2.p = Pt3D_0; 63 66 64 67 static double CBRT_3 = std::cbrt(3);
Note: See TracChangeset
for help on using the changeset viewer.