private GeneralizedDistanceTransform2D CalculateMinEnergiesForAllParentEdges( ShapeModel model, ShapeConstraints shapeConstraints, int parentEdgeIndex, int currentEdgeIndex, IList <ILengthAngleConstraints> lengthAngleConstraints) { // Calculate child transforms List <GeneralizedDistanceTransform2D> childDistanceTransforms = new List <GeneralizedDistanceTransform2D>(); foreach (int neighborEdgeIndex in model.IterateNeighboringEdgeIndices(currentEdgeIndex)) { // Iterate only through children if (neighborEdgeIndex == parentEdgeIndex) { continue; } GeneralizedDistanceTransform2D childTransform = CalculateMinEnergiesForAllParentEdges( model, shapeConstraints, currentEdgeIndex, neighborEdgeIndex, lengthAngleConstraints); Debug.Assert(childTransform.IsComputed); childDistanceTransforms.Add(childTransform); } ShapeEdgePairParams pairParams = model.GetEdgePairParams(parentEdgeIndex, currentEdgeIndex); GeneralizedDistanceTransform2D transform = this.AllocateDistanceTransform(); SetupTransformFinitePenaltyRanges(transform, pairParams, lengthAngleConstraints[currentEdgeIndex]); SetupTransformInterestRanges(transform, lengthAngleConstraints[parentEdgeIndex]); Func <double, double, double> penaltyFunction = (scaledLength, shiftedAngle) => { double length = scaledLength / pairParams.MeanLengthRatio; double angle = shiftedAngle + pairParams.MeanAngle; double lengthTolerance = transform.GridStepSizeX / pairParams.MeanLengthRatio; double angleTolerance = transform.GridStepSizeY; if (!lengthAngleConstraints[currentEdgeIndex].InRange(length, lengthTolerance, angle, angleTolerance)) { return(1e+20); } double penalty = CalculateMinUnaryEdgeEnergy(currentEdgeIndex, model, shapeConstraints, length) + CalculateMinPairwiseEdgeEnergy(length, angle, childDistanceTransforms); return(penalty); }; transform.Compute( 0.5 / MathHelper.Sqr(pairParams.LengthDiffDeviation), 0.5 / MathHelper.Sqr(pairParams.AngleDeviation), penaltyFunction); return(transform); }
private void SetupTransformFinitePenaltyRanges( GeneralizedDistanceTransform2D transform, ShapeEdgePairParams pairParams, ILengthAngleConstraints lengthAngleConstraints) { Range lengthRange = lengthAngleConstraints.LengthBoundary; Range angleRange = lengthAngleConstraints.AngleBoundary; transform.AddFinitePenaltyRangeX( new Range(lengthRange.Left * pairParams.MeanLengthRatio, lengthRange.Right * pairParams.MeanLengthRatio)); if (!angleRange.Outside) { transform.AddFinitePenaltyRangeY(new Range(angleRange.Left - pairParams.MeanAngle, angleRange.Right - pairParams.MeanAngle)); } else { transform.AddFinitePenaltyRangeY(new Range(-Math.PI - pairParams.MeanAngle, angleRange.Left - pairParams.MeanAngle)); transform.AddFinitePenaltyRangeY(new Range(angleRange.Right - pairParams.MeanAngle, Math.PI - pairParams.MeanAngle)); } }
private void SetupTransformFinitePenaltyRanges( GeneralizedDistanceTransform2D transform, ShapeEdgePairParams pairParams, ILengthAngleConstraints lengthAngleConstraints) { Range lengthRange = lengthAngleConstraints.LengthBoundary; Range angleRange = lengthAngleConstraints.AngleBoundary; transform.AddFinitePenaltyRangeX( new Range(lengthRange.Left * pairParams.MeanLengthRatio, lengthRange.Right * pairParams.MeanLengthRatio)); if (!angleRange.Outside) transform.AddFinitePenaltyRangeY(new Range(angleRange.Left - pairParams.MeanAngle, angleRange.Right - pairParams.MeanAngle)); else { transform.AddFinitePenaltyRangeY(new Range(-Math.PI - pairParams.MeanAngle, angleRange.Left - pairParams.MeanAngle)); transform.AddFinitePenaltyRangeY(new Range(angleRange.Right - pairParams.MeanAngle, Math.PI - pairParams.MeanAngle)); } }