2011-09-21 44 views
7

編輯:我不知道這是否應該是一個新問題或不是,所以我只是現在更新這一個。雪花現在正在正確生成,除非我更改原始座標。例如,如果我的原三角形是等圖片1,經過5次迭代的結果是圖像2:不能旋轉科赫雪花

enter image description here enter image description here

然而,如果我的原三角形是什麼不同,例如圖片3,結果是扭曲:

enter image description here enter image description here

我再想一想,問題是我的正常人,但我真的失去了。我已經嘗試了幾個小時來弄清楚正確的公式,但我並沒有真正取得進展。由於新的三角形被顛倒的問題似乎很多時候,我懷疑atan在給我一個正面價值時給我一個負值。有沒有一種數學方法可以解決這個問題?非常感謝你的幫助!

我的代碼(減去openGL的部分,因爲我不認爲他們有問題)是:

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"); 
} 

目前我正在試圖實現在C Koch曲線++。我有它幾乎正常工作。基本上有三種不同的情況,我正在處理:我需要分成四個分段的線段是水平的,垂直的或其他。

問題是,當程序計算線段的新頂點時,有兩種可能性:三角形可以面向「向上」或三角形可以面向「向下」。我試圖通過歸一化矢量來考慮這個問題,但是我做的不正確,或者有其他的東西稍微偏離。下面的圖片是兩個例子。都有3次迭代的分形。

用於分離非水平和非垂直的線段的代碼是下面,由於三角形看起來像面以正確的方式對垂直/水平段:

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和b是矢量的細分受衆羣。 normalX和normalY是:

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

任何想法,我可以做些什麼來解決這個問題?

+0

這裏的'a'和'b'是什麼?如果你發佈更多的代碼會更容易。 – sinelaw

+0

GLfloat normalX((b.x - a.x)/ deltaX); GLFloat normalY((b.y - a.y)/ deltaY);應該是GLfloat normalX((b.x - a.x)/ distance); GLFloat normalY((b.y - a.y)/ distance); - 你的價值觀將全部+1或-1 –

回答

11

您的問題可能是atan(theta)。它的域太小而不能用於通用角度確定。您應該改用atan2(y,x)

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)); 

(我沒有測試此代碼,所以可能會有一些徵兆錯誤)

瞭解更多:Atan2 (Wikipedia)


編輯:

我的猜測是你給錯誤的順序座標。如果從面向終點的起點角度考慮一個段,曲線將始終向右伸出。如果以相反的順序給出座標,曲線將被鏡像。

+0

你是對的!問題在於曬黑,現在它完美地工作。非常感謝! –

+0

這個答案解決了我原來的問題,但出現了一個新問題(詳見上面的編輯):( –

+0

謝謝!你是對的。很有趣這麼簡單的事情會造成如此多的心痛:) –

1

以逆時針順序提供所有初始頂點,它應該按照您的期望工作。