Esempio n. 1
0
    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);
    }