2011-09-21 16 views
7

DÜZENLEME: Yeni bir soru olup olmadığından emin değildim, bu yüzden şimdilik bunu güncelliyorum. Orijinal koordinatları değiştirmediğim sürece kar tanesi artık düzgün bir şekilde üretiliyor. Orijinal üçgen gibi resmi 3 için farklı bir şey olması durumundaKoch kar tanesi döndürülemiyor

enter image description here enter image description here

Ancak, sonuçlar şunlardır: Orijinal üçgen resim 1 gibi ise Örneğin, 5 tekrardan sonra sonuç resim 2'dir çarpıtılmış:

enter image description here enter image description here

tekrar sorun benim normaller ile olduğunu düşünüyorum ama gerçekten kayboldum. Bunu yapmak için doğru formülleri bulmak için saatlerimi denedim ama gerçekten ilerleme kaydetmiyorum. Yeni üçgenlerin tersine çevrilmesinin çoğu kez problem olduğu düşünülürse, sanırım bana olumlu bir değer vermesi gerektiğinde, ataşenin bana olumsuz bir değer verdiğini sanıyorum. Bu konuda alabileceğim matematiksel bir yol var mı? Yardımın için çok teşekkür ederim!

Kodum (eksi openGL bölümlerini onlar sorun olduğunu sanmıyorum çünkü): Ben şu anda ++ c Koch eğrisi uygulamak çalışıyorum

const int NumTimesToSubdivide = 5; 
const int NumSegments = 3072; // 3x4^n lines generated {3, 12, 48, 192, 768, 3072..} 
const int NumVertices = NumSegments * 2; // 2 vertices for each segment 

vec2 arrayA[NumVertices]; 
vec2 arrayB[NumVertices]; 

//---------------------------------------------------------------------------- 
void koch(const vec2 &a, const vec2 &b, vec2 * verts) {   

/* Calculate new segments. 
*   v1  
*   /\ 
*  /\ 
*  / \ 
* a----/  \----b 
*  v0  v2 
*/ 
vec2 v0; 
vec2 v1; 
vec2 v2; 

GLfloat distance(sqrt(pow(b.x - a.x, 2) + pow(b.y - a.y,2))); 
GLfloat deltaX = abs(b.x - a.x); 
GLfloat deltaY = abs(b.y - a.y); 
GLfloat normalX((b.x - a.x)/deltaX); 
GLfloat normalY((b.y - a.y)/deltaY); 
GLfloat theta = atan2(b.y - a.y, b.x - a.x) - M_PI/3.0; 
cout << " theta = " << theta << endl; 

/************************* 
* Find trisection points 
*************************/ 
// horizontal line _____________ 
if(a.y == b.y) { 
    vec2 temp0(a.x + (deltaX * normalX/3) , a.y); 
    vec2 temp2(a.x + (deltaX * normalX * 2/3) , a.y); 
    vec2 temp1((a.x + b.x)/2, a.y + distance * sin(theta)/3); 
    v0 = temp0; 
    v2 = temp2; 
    v1 = temp1; 
} 

//     | 
// vertical line | 
//     | 
else if(a.x == b.x){ 
    vec2 temp0(a.x , (a.y + (deltaY * normalY/3))); 
    vec2 temp2(a.x , (a.y + (deltaY * normalY * 2/3))); 
    vec2 temp1(a.x + distance * cos(theta)/3 , (a.y + b.y)/2); 
    v0 = temp0; 
    v2 = temp2; 
    v1 = temp1; 
} 

// slope != 0 && slope != 1 
else { 
    vec2 temp0(a.x + (deltaX * normalX/3), a.y + (deltaY * normalY/3)); 
    vec2 temp2(a.x + (deltaX * normalX * 2/3), a.y + (deltaY * normalY * 2/3)); 
    // Andrew is the greatest! 
    vec2 temp1(temp0.x + distance * cos(theta)/3, 
       temp0.y + distance * sin(theta)/3);   
    v0 = temp0; 
    v2 = temp2; 
    v1 = temp1; 
} 

verts[0] = a; 
verts[1] = v0; 
verts[2] = v0; 
verts[3] = v1; 
verts[4] = v1; 
verts[5] = v2; 
verts[6] = v2; 
verts[7] = b; 

} 

//---------------------------------------------------------------------------- 

void divide_line(const vec2& a, const vec2& b, const vec2& c, int n) 
{ 

// arrayA = {a, b, b, c, c, a} i.e., the sides of the initial triangle 
arrayA[0] = a; 
arrayA[1] = b; 
arrayA[2] = b; 
arrayA[3] = c; 
arrayA[4] = c; 
arrayA[5] = a; 

// If at least one iteration: 
if(n > 0) { 
    // The current iteration, starting with 0 
    int currentIteration = 1; 
    // Do for every iteration from 0 - n: 
    while (currentIteration <= n) { 
     int i; 
     int j = 0; 
     int size = 3 * 2 * (pow(4,currentIteration-1)); 
     // Call koch() for each pair of vertices in arrayA 
     for(i = 0; i < size; i = i+2) { 
      vec2 verts[8]; 
      koch(arrayA[i], arrayA[i+1], verts); 
      // Store each vertex in arrayB 
      int k; 
      for(k = 0; k <= 7; k++) 
       arrayB[j++] = verts[k]; 
     } 
     // Copy arrayB to arrayA for next iteration. 
     size = 3 * 2 * pow(4, currentIteration); 
     for(i = 0; i < NumVertices; i++) { 
      arrayA[i] = arrayB[i]; 
     } 
     // Increase count of currentIteration. 
     currentIteration++; 
    } 
} else 
    printf("The number of iterations must be >= 0.\n"); 
} 

. Neredeyse doğru şekilde çalışıyor. Temel olarak ele aldığım üç farklı durum var: dört bölüme ayırmam gereken çizgi parçası yatay, dikey veya diğer.

Sorun, program, yeni segmentlerin satır segmentleri için ne olduğunu hesapladığında, iki olasılık vardır: üçgenin "yukarı" ya da üçgenin "aşağıya" karşı karşıya gelmesi olabilir. Vektörleri normalize ederek bunu hesaba katmaya çalıştım, fakat bunu yanlış yaptım ya da birazcık başka bir şey var. Aşağıdaki resimler iki örnektir; her iki fraktalın 3 tekrarı vardır.

üçgenler/dikey, yatay segmentler için yüz gibi doğru bir şekilde görünmektedir çünkü olmayan bir yatay ve dik olmayan bir çizgi parçası ayırmak için kod, aşağıdaki gibidir:

if(a.x == b.x) { 
    ... 
} 
else if (a.y == b.y) { 
    ... 
} 
// slope != 0 && slope != 1 
else { 
    GLfloat deltaX = abs(b.x - a.x); 
    GLfloat deltaY = abs(b.y - a.y); 
    vec2 temp0(a.x + (deltaX * normalX/3), a.y + (deltaY * normalY/3)); 
    vec2 temp2(a.x + (deltaX * normalX * 2/3), a.y + (deltaY * normalY * 2/3)); 
    GLfloat dist(sqrt(pow(temp2.x - temp0.x, 2) + pow(temp2.y - temp0.y,2))); 
    GLfloat theta = (a.x - b.x)/ (b.y - a.y); 
    vec2 temp1((a.x + b.x)/2 + dist * cos(atan(theta)) , 
       (a.y + b.y)/2 + dist * sin(atan(theta))); 
    v0 = temp0; 
    v2 = temp2; 
    v1 = temp1; 
} 

a ve b vektörlerdir segmentin normalX ve normalde şunlardır: Bu sorunu çözmek için neler yapabileceğini

GLfloat normalX((b.x - a.x)/(abs(b.x - a.x))); 
GLfloat normalY((b.y - a.y)/(abs(b.y - a.y))); 

Herhangi bir fikir?

+0

Burada 'a' ve 'b' nedir? Daha fazla kod gönderdiyseniz daha kolay olurdu. – sinelaw

+0

GLfloat normalX ((b.x-a.x)/deltaX); GLfloat normalY ((b.y-a.y)/deltaY); GLfloat normalX ((b.x - a.x)/mesafe) olmalıdır; GLfloat normalY ((b.y-a.y)/mesafe); - Değerleriniz +1 veya -1 –

cevap

11

Sorununuz büyük olasılıkla atan(theta). Alanın genel açı belirleme için kullanılması çok küçük. Bunun yerine atan2(y,x) kullanmalıdır:

GLfloat theta = atan2(b.y - a.y, a.x - b.x); 
vec2 temp1((a.x + b.x)/2 + dist * cos(theta) , 
      (a.y + b.y)/2 + dist * sin(theta)); 

(. Bu kodu test ettik, bu yüzden bazı işaret hatalar meydana gelebilir)

Devamı: Atan2 (Wikipedia)


DÜZENLEME:

Tahminimce koordinatları yanlış sırayla veriyorsunuz.Başlangıç ​​noktasının son noktaya bakan perspektifinden bir segment düşünürseniz, eğri her zaman sağınıza doğru olacaktır. Eğer koordinatları karşı sırayla verirseniz, eğri yansıtılacaktır.

+0

olacaksınız. Sorun bronzlaşmıştı ve şimdi mükemmel çalışıyor. Çok teşekkür ederim! –

+0

Bu cevap orijinal sorunumu düzeltti, ancak yeni bir sorun ortaya çıktı (yukarıdaki düzenlemede belirtildiği gibi) :( –

+0

Teşekkürler! Haklıydın. Bu kadar basit bir şeyin o kadar çok kalpazanlığa neden olabileceği komiktir :) –

1

Tüm başlangıç ​​noktalarınızı saat yönünün tersine sırayla verin ve beklediğiniz şekilde çalışmalıdır.

İlgili konular