static DoubleMatrix SmoothRidges(DoubleMatrix input, DoubleMatrix orientation, BooleanMatrix mask, BlockMap blocks, double angle, IntPoint[][] lines) { var output = new DoubleMatrix(input.Size); foreach (var block in blocks.Primary.Blocks.Iterate()) { if (mask[block]) { var line = lines[DoubleAngle.Quantize(DoubleAngle.Add(orientation[block], angle), lines.Length)]; foreach (var linePoint in line) { var target = blocks.Primary.Block(block); var source = target.Move(linePoint).Intersect(new IntRect(blocks.Pixels)); target = source.Move(-linePoint); for (int y = target.Top; y < target.Bottom; ++y) { for (int x = target.Left; x < target.Right; ++x) { output.Add(x, y, input[x + linePoint.X, y + linePoint.Y]); } } } var blockArea = blocks.Primary.Block(block); for (int y = blockArea.Top; y < blockArea.Bottom; ++y) { for (int x = blockArea.Left; x < blockArea.Right; ++x) { output.Multiply(x, y, 1.0 / line.Length); } } } } return(output); }
static List <int> ShapeCoverage(EdgeShape edge) { int minLengthBin = (edge.Length - Parameters.MaxDistanceError) / Parameters.MaxDistanceError; int maxLengthBin = (edge.Length + Parameters.MaxDistanceError) / Parameters.MaxDistanceError; int angleBins = (int)Math.Ceiling(2 * Math.PI / Parameters.MaxAngleError); int minReferenceBin = (int)(DoubleAngle.Difference(edge.ReferenceAngle, Parameters.MaxAngleError) / Parameters.MaxAngleError); int maxReferenceBin = (int)(DoubleAngle.Add(edge.ReferenceAngle, Parameters.MaxAngleError) / Parameters.MaxAngleError); int endReferenceBin = (maxReferenceBin + 1) % angleBins; int minNeighborBin = (int)(DoubleAngle.Difference(edge.NeighborAngle, Parameters.MaxAngleError) / Parameters.MaxAngleError); int maxNeighborBin = (int)(DoubleAngle.Add(edge.NeighborAngle, Parameters.MaxAngleError) / Parameters.MaxAngleError); int endNeighborBin = (maxNeighborBin + 1) % angleBins; var coverage = new List <int>(); for (int lengthBin = minLengthBin; lengthBin <= maxLengthBin; ++lengthBin) { for (int referenceBin = minReferenceBin; referenceBin != endReferenceBin; referenceBin = (referenceBin + 1) % angleBins) { for (int neighborBin = minNeighborBin; neighborBin != endNeighborBin; neighborBin = (neighborBin + 1) % angleBins) { coverage.Add((referenceBin << 24) + (neighborBin << 16) + lengthBin); } } } return(coverage); }
static ConsideredOrientation[][] PlanOrientations() { var random = new OrientationRandom(); var splits = new ConsideredOrientation[Parameters.OrientationSplit][]; for (int i = 0; i < Parameters.OrientationSplit; ++i) { var orientations = splits[i] = new ConsideredOrientation[Parameters.OrientationsChecked]; for (int j = 0; j < Parameters.OrientationsChecked; ++j) { var sample = orientations[j] = new ConsideredOrientation(); while (true) { double angle = random.Next() * Math.PI; double distance = Doubles.InterpolateExponential(Parameters.MinOrientationRadius, Parameters.MaxOrientationRadius, random.Next()); sample.Offset = (distance * DoubleAngle.ToVector(angle)).Round(); if (sample.Offset == IntPoint.Zero) { continue; } if (sample.Offset.Y < 0) { continue; } bool duplicate = false; for (int jj = 0; jj < j; ++jj) { if (orientations[jj].Offset == sample.Offset) { duplicate = true; } } if (duplicate) { continue; } break; } sample.Orientation = DoubleAngle.ToVector(DoubleAngle.Add(DoubleAngle.ToOrientation(DoubleAngle.Atan((DoublePoint)sample.Offset)), Math.PI)); } } return(splits); }