public DistanceAndPoint NearestFrom(Vector2 point, DistanceAndPoint nearest) { var result = nearest; // 自分との距離 var dist = (Value - point).sqrMagnitude; // 現在の最小距離の範囲にある領域が探索候補 if (dist < result.Distance) { result = new DistanceAndPoint(dist, Value); } // 存在する可能性のある Area を探索 var areaFlags = new bool[] { false, false, false, false }; var index = (int)Detect(new Vector2(point.x + result.Distance, point.y)); areaFlags[index] = true; index = (int)Detect(new Vector2(point.x - result.Distance, point.y)); areaFlags[index] = true; index = (int)Detect(new Vector2(point.x, point.y + result.Distance)); areaFlags[index] = true; index = (int)Detect(new Vector2(point.x, point.y - result.Distance)); areaFlags[index] = true; for (var i = 0; i < 4; i++) { if (!areaFlags[i]) { continue; } var tree = children[i]; if (tree == null) { continue; } var childResult = tree.NearestFrom(point, result); var d = childResult.Distance; if (d >= result.Distance) { continue; } result = childResult; } return(result); }
private Vector2 BlueNoise() { var candidates = Enumerable.Range(0, CandidateCount).Select(_ => WhiteNoiseGenerator.Next()).ToList(); var sample = samples.Last(); var best = new DistanceAndPoint(0, sample); for (var j = 0; j < CandidateCount; j++) { var candidate = candidates[j]; var nearest = quadTree.NearestFrom(candidate, new DistanceAndPoint(int.MaxValue, sample)); if (nearest.Distance > best.Distance) { best = new DistanceAndPoint(nearest.Distance, candidate); } } quadTree.Insert(best.Point); samples.Add(best.Point); return(best.Point); }
private Vector2 FilledBlueNoise() { if (allSamplesCount == 0) { return(Vector2.zero); } var candidateIndexes = Enumerable.Range(0, CandidateCount) .Select(_ => Random.Range(0, allSamplesCount)); var candidates = candidateIndexes.Select(x => new { index = x, point = allSamples[x] }).ToList(); var sample = samples.Last(); var best = new DistanceAndPoint(0, sample); var bestIndex = 0; for (var j = 0; j < CandidateCount; j++) { var candidate = candidates[j]; var nearest = quadTree.NearestFrom(candidate.point, new DistanceAndPoint(int.MaxValue, sample)); if (nearest.Distance > best.Distance) { best = new DistanceAndPoint(nearest.Distance, candidate.point); bestIndex = candidate.index; } } quadTree.Insert(best.Point); samples.Add(best.Point); allSamples[bestIndex] = allSamples[allSamplesCount - 1]; allSamplesCount--; return(best.Point); }