2011-12-01 18 views
6

Tek boyutlu bir girdim var. onun aralığı bir kayan noktadır. Kayan nokta koordinatında da bir nokta var. En yakın grid noktasına olan mesafesini bulmalıyım. Örneğin
: En yakın nokta bunun arkasında olduğundanKılavuza en yakın noktaya gelinme noktası

  0.12 
      | 
      * 
|---------|---------|---------|---------|---------| 
0  0.1  0.2  0.3  0.4  0.5 

sonuç -0.02 olurdu.
o

   -0.66 
        | 
        * 
|---------|---------|---------|---------|---------| 
-1  -0.8  -0.6  -0.4  -0.2  0 

oldu Ancak eğer sonuç 0.06 olacaktır. Kayan noktasında gördüğünüz gibi ve olumsuz olabilir.
Denedim aşağıdadır:

float spacing = ...; 
float point = ...; 

while(point >= spacing) point -= spacing; 
while(point < 0) point += spacing; 

if(std::abs(point - spacing) < point) point -= spacing; 

O inşaat, ama sadece sayı yuvarlak bu kullanarak gerektiğini

+0

Aralık çizgisi doğrusal mı? – GWW

+0

Onun örneklerinde doğrusaldır. – GWW

+0

@MooingDuck: Doğrusal, sabit değil (parametresi) – Dani

cevap

6

Öncelikle solda en yakın noktaları hesaplamak edelim ve sağ olarak aşağıdaki gibidir:

if ((point - leftBorder) < (rightBorder - point)) 
    distance = leftBorder - point; 
else 
    distance = rightBorder - point; 

Not

biz en yakın bulabildiğim ki:

leftBorder = spacing * floor(point/spacing); 
rightBorder = leftBorder + spacing; 

Sonra mesafe basittir alternatif olarak tavana göre:

rightBorder = spacing * ceil(point/spacing); 
leftBorder = rightBorder - spacing; 
+0

Lütfen kodun açıklamasını da ekleyebilir misiniz? –

+0

Öneriniz için teşekkürler. Değişkenleri kendi kendini ifade edebilmek için değiştirdim. Daha fazla açıklama yapmalı mıyım? – petrichor

+0

Doğal dilde bir açıklama sadece cevabınızı daha iyi hale getiriyor, dolayısıyla bunun için git! –

0

gevreksiz bir yolu vardır eminim:

float spacing = ...; 
float point = ...; 
(point > 0.0) ? floor(point + spacing/2) : ceil(point - spacing/2); 
+0

Aralık sabit değil – Dani

+0

@Dani: Sabit olmayan aralıklarla nasıl yapılabileceğini açıklığa kavuşturdum. –

+0

zemin ve tavan en yakın tamsayıya yuvarlanır, en yakın adım değeri değil. –

2
std::vector<float> spacing = ...; 
float point = ...; 
float result; 

Aralığın (doğrusal) olmadığını belirttiğiniz için, toplamları önbelleğe alırdım:

std::vector<float> sums(1, 0.0); 
float sum=0; 
for(int i=0; i<spacing.size(); ++i) 
    sums.push_back(sum+=spacing[i]); 
//This only needs doing once. 
//sums needs to be in increasing order. 

Sonra sola noktasını bulmak için ikili arama yapın:

std::vector<float>::iterator iter; 
iter = std::lower_bound(sums.begin(), sums.end(), point); 

Sonra oradan sonucunu bulmak:

if (iter+1 == sums.end()) 
    return point-*iter; 
else { 
    float midpoint = (*iter + *(iter+1))/2; 
    if (point < midpoint) 
     result = point - *iter; 
    else 
     result = *(iter+1) - point; 
} 

[DEĞİŞTİR] aptal hissetme. Boşluğun sabit olmadığını söyledin. Ben lineer olmayan olarak yorumladım. Ama sonra örnek kod doğrusal, sadece bir derleme zamanı sabiti değil. Benim hatam. Bu cevabı daha genel bir çözüm olarak bırakacağım, ama (lineer) sorunuz çok daha hızlı çözülebilir.

+0

Aralığın içindeki boşluk sabittir, çağrılar arasında sabit değildir ... – Dani

2

İşte ilk allık girişimi, bunun hiç test edilmediğine dikkat edin.

float remainder = fmod(point, spacing); // This is the fractional difference of the spaces 
int num_spaces = point/spacing; // This is the number of "spaces" down you are, rounded down 


// If our fractional part is greater than half of the space length, increase the number of spaces. 
// Not sure what you want to do when the point is equidistant to both grid points 
if(remainder > .5 * spacing) 
{ 
    ++num_spaces; 
} 

float closest_value = num_spaces*spacing; 
float distance = closest_value - point; 
+0

Cevabınıza yaptığı yorumunda, çağrılar içinde sabit olduğunu söylüyor. –

+0

@MooingDuck: Hayır, sabit olmadığını belirtiyor. – GWW

+0

@MooingDuck: Doğrusunu ifade etmedim, her zaman 0.1 değerini belirtmiyorum. (bir parametre) – Dani

0

Genelde, keyfi aralıklar, boyutlar ve uzaklık ölçüleri (metrik) için, genel olarak, aradığınız yapı bir Voronoi Diyagramı olacaktır.

İlgili konular