private bool validateAndAddSample(Vector2 sample, ref List<Vector2> samples, ref List<Vector2> active, ref SpacialLookup lookup, PlaceSample place) {
        //Debug.Log("Attempting to add sample: " + sample);
        if (validateBounds(sample) && validateDistSamples(ref lookup, sample) && place(sample)) {
            samples.Add(sample);
            active.Add(sample);
            lookup.Insert(sample);

            //Debug.Log("Sample Added!");
            return true;
        }
        return false;
    }
    private bool AddFirstSamples(ref List<Vector2> samples, ref List<Vector2> active, ref SpacialLookup lookup, PlaceSample place) {
        bool found = false;
        for (int i = 0; i < k; i++) {
            float angle = Random.Range(0f, 2f * Mathf.PI);
            float radius = Random.Range(0f, this.radius);
            Vector2 point = new Vector2(radius * Mathf.Cos(angle), radius * Mathf.Sin(angle));

            if (validateAndAddSample(point, ref samples, ref active, ref lookup, place)) {
                found = true;
            }
        }

        return found;
    }
    public int generateSamples(PlaceSample place, List<Vector2> externalSamples = null) {
        List<Vector2> samples = new List<Vector2>();
        List<Vector2> active = new List<Vector2>();
        SpacialLookup lookup = new SpacialLookup(radius, minDist);

        //Debug.Log("Generating samples!");

        // add external samples
        if (externalSamples != null) {
            //Debug.Log("Sampler adding " + externalSamples.Count + " external samples");
            foreach (Vector2 ex in externalSamples) {
                lookup.Insert(ex);
            }
        }
        
        if (!AddFirstSamples(ref samples, ref active, ref lookup, place)) {
            if (!AddFirstSamples(ref samples, ref active, ref lookup, place)) {
                Debug.LogWarning("Unable to add first sample after 2 attempts.");
                return samples.Count;
            }
        }

        
        while (active.Count > 0) {
            // select random index and move to end
            int index = Random.Range(0, active.Count);
            swap(ref active, index, active.Count - 1);
            Vector2 selected = active[active.Count - 1];
            bool found = false;

            for (int i = 0; i < k; i++) {
                Vector2 newSample = selected + RandomVector();

                if (validateAndAddSample(newSample, ref samples, ref active, ref lookup, place)) {
                    found = true;
                }

            }

            if (!found) {
                //Debug.Log("No point found after " + k + " iterations, removing active point: " + selected);
                active.RemoveAt(active.Count - 1);
            }
        }

        return samples.Count;
    }
    /*private bool validateDistSamples(ref List<Vector2> samples, Vector2 newSample) {
        float sqrDist = minDist * minDist;
        for (int i = 0; i < samples.Count; i++) {
            if ((samples[i] - newSample).sqrMagnitude < sqrDist) {
                return false;
            }
        }

        return true;
    }*/

    private bool validateDistSamples(ref SpacialLookup lookup, Vector2 newSample) {
        return !lookup.Collides(newSample, minDist);
    }