Changeset 1030 for cpp/frams/genetics/fS/fS_oper.cpp
- Timestamp:
- 11/26/20 01:30:40 (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/genetics/fS/fS_oper.cpp
r1017 r1030 51 51 if (errorPosition != 0) 52 52 { 53 logPrintf("GenoOper_fS", "checkValidity", LOG_WARN, "Invalid part s ize");53 logPrintf("GenoOper_fS", "checkValidity", LOG_WARN, "Invalid part scale"); 54 54 return errorPosition; 55 55 } … … 226 226 const char *GenoOper_fS::getSimplest() 227 227 { 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}"; 229 229 } 230 230 … … 297 297 geno.getState(false); 298 298 Node *node = geno.chooseNode(); 299 char part Type = SHAPE_TO_GENE.at(availablePartShapes[rndUint(availablePartShapes.size())]);300 301 Substring substring(&part Type, 0, 1);299 char partShape = SHAPE_TO_GENE.at(availablePartShapes[rndUint(availablePartShapes.size())]); 300 301 Substring substring(&partShape, 0, 1); 302 302 Node *newNode = new Node(substring, node, node->genotypeParams); 303 303 // Add random rotation … … 322 322 newNode->params[selectedParam] = RndGen.Uni(-M_PI / 2, M_PI / 2); 323 323 } 324 // Assign part s ize to default value325 double volumeMultiplier = pow(node->getParam(S IZE) * node->state->s, 3);324 // Assign part scale to default value 325 double volumeMultiplier = pow(node->getParam(SCALE) * node->state->s, 3); 326 326 double minVolume = Model::getMinPart().volume; 327 327 double defVolume = Model::getDefPart().volume * volumeMultiplier; // Default value after applying modifiers … … 330 330 double relativeVolume = volume / volumeMultiplier; // Volume without applying modifiers 331 331 332 double newRadius = std::cbrt(relativeVolume / volumeMultipliers.at(newNode->part Type));333 newNode->params[S IZE_X] = newRadius;334 newNode->params[S IZE_Y] = newRadius;335 newNode->params[S IZE_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; 336 336 node->children.push_back(newNode); 337 337 … … 339 339 { 340 340 geno.getState(false); 341 mutateS izeParam(newNode, SIZE_X, true);342 mutateS izeParam(newNode, SIZE_Y, true);343 mutateS izeParam(newNode, SIZE_Z, true);341 mutateScaleParam(newNode, SCALE_X, true); 342 mutateScaleParam(newNode, SCALE_Y, true); 343 mutateScaleParam(newNode, SCALE_Z, true); 344 344 } 345 345 return true; … … 350 350 Node *randomNode, *selectedChild; 351 351 // Choose a parent with children 352 // It may be difficult to choose a eligible node, so the number of tries should be high352 // It may be difficult to choose an eligible node, so the number of tries should be high 353 353 for (int i = 0; i < 10 * mutationTries; i++) 354 354 { … … 380 380 Node *randomNode = geno.chooseNode(); 381 381 int index = rndUint(availShapesLen); 382 if (availablePartShapes[index] == randomNode->part Type)382 if (availablePartShapes[index] == randomNode->partShape) 383 383 index = (index + 1 + rndUint(availShapesLen - 1)) % availShapesLen; 384 384 Part::Shape newType = availablePartShapes[index]; 385 385 386 386 #ifdef _DEBUG 387 if(newType == randomNode->part Type)387 if(newType == randomNode->partShape) 388 388 throw fS_Exception("Internal error: invalid part type chosen in mutation.", 1); 389 389 #endif 390 390 391 391 geno.getState(false); 392 double s izeMultiplier = randomNode->getParam(SIZE) * randomNode->state->s;393 double relativeVolume = randomNode->calculateVolume() / pow(s izeMultiplier, 3.0);394 395 if (!ensureCircleSection || newType == Part::Shape::SHAPE_CUBOID || (randomNode->part Type == Part::Shape::SHAPE_ELLIPSOID && newType == Part::Shape::SHAPE_CYLINDER))396 { 397 double radiusQuotient = std::cbrt(volumeMultipliers.at(randomNode->part Type) / volumeMultipliers.at(newType));398 randomNode->params[S IZE_X] = randomNode->getParam(SIZE_X) * radiusQuotient;399 randomNode->params[S IZE_Y] = randomNode->getParam(SIZE_Y) * radiusQuotient;400 randomNode->params[S IZE_Z] = randomNode->getParam(SIZE_Z) * radiusQuotient;401 } else if (randomNode->part Type == Part::Shape::SHAPE_CUBOID && newType == Part::Shape::SHAPE_CYLINDER)402 { 403 double newRadius = 0.5 * (randomNode->getParam(S IZE_X) + randomNode->getParam(SIZE_Y));404 randomNode->params[S IZE_X] = 0.5 * relativeVolume / (M_PI * newRadius * newRadius);405 randomNode->params[S IZE_Y] = newRadius;406 randomNode->params[S IZE_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; 407 407 } else if (newType == Part::Shape::SHAPE_ELLIPSOID) 408 408 { 409 409 double newRelativeRadius = cbrt(relativeVolume / volumeMultipliers.at(newType)); 410 randomNode->params[S IZE_X] = newRelativeRadius;411 randomNode->params[S IZE_Y] = newRelativeRadius;412 randomNode->params[S IZE_Z] = newRelativeRadius;410 randomNode->params[SCALE_X] = newRelativeRadius; 411 randomNode->params[SCALE_Y] = newRelativeRadius; 412 randomNode->params[SCALE_Z] = newRelativeRadius; 413 413 } else 414 414 { 415 415 throw fS_Exception("Invalid part type", 1); 416 416 } 417 randomNode->part Type = newType;417 randomNode->partShape = newType; 418 418 return true; 419 419 } … … 446 446 return false; 447 447 // Do not allow invalid changes in part size 448 bool isRadiusOfBase = key == S IZE_Y || key == SIZE_Z;449 bool isRadius = isRadiusOfBase || key == S IZE_X;448 bool isRadiusOfBase = key == SCALE_Y || key == SCALE_Z; 449 bool isRadius = isRadiusOfBase || key == SCALE_X; 450 450 if (ensureCircleSection && isRadius) 451 451 { 452 if (randomNode->part Type == Part::Shape::SHAPE_ELLIPSOID)452 if (randomNode->partShape == Part::Shape::SHAPE_ELLIPSOID) 453 453 return false; 454 if (randomNode->part Type == Part::Shape::SHAPE_CYLINDER && isRadiusOfBase)454 if (randomNode->partShape == Part::Shape::SHAPE_CYLINDER && isRadiusOfBase) 455 455 return false; 456 456 } … … 490 490 bool GenoOper_fS::mutateParamValue(Node *node, string key) 491 491 { 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); 496 499 return true; 497 500 } else 498 return mutateS izeParam(node, key, ensureCircleSection);501 return mutateScaleParam(node, key, ensureCircleSection); 499 502 } 500 503 … … 524 527 randomNode->modifiers[randomModifier] += rndUint(2) == 0 ? 1 : -1; 525 528 526 bool isSizeMod = tolower(randomModifier) == S IZE_MODIFIER;529 bool isSizeMod = tolower(randomModifier) == SCALE_MODIFIER; 527 530 if (isSizeMod && geno.checkValidityOfPartSizes() != 0) 528 531 { … … 678 681 } 679 682 680 bool GenoOper_fS::mutateS izeParam(Node *node, string key, bool ensureCircleSection)683 bool GenoOper_fS::mutateScaleParam(Node *node, string key, bool ensureCircleSection) 681 684 { 682 685 double oldValue = node->getParam(key); 683 686 double volume = node->calculateVolume(); 684 687 double valueAtMinVolume, valueAtMaxVolume; 685 if(key == S IZE)688 if(key == SCALE) 686 689 { 687 690 valueAtMinVolume = oldValue * std::cbrt(Model::getMinPart().volume / volume); … … 696 699 double min = std::max(Node::minValues.at(key), valueAtMinVolume); 697 700 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()) 702 706 return true; 703 707 else
Note: See TracChangeset
for help on using the changeset viewer.