2010-08-17 188 views
0

我試圖實現這一點:從https://docs.google.com/viewer?url=http://www.tinaja.com/glib/bezdist.pdf&pli=1這看起來像僞代碼是什麼樣的?

以下BASIC程序使用找到距離的方法。 程序還搜索曲線之間的最小平方距離和 。

REM BEZIER.BAS JIM 20DEC92 12:37 
DATA 2,3,5,8,8,14,11,17,14,17,16,15,18,11,-1 
DATA 2,10,5,12,8,11,11,8,14,6,17,5,19,10,-1 
DATA 2,5,5,7,8,8,12,12,13,14,12,17,10,18,8,17,7,14,8,12,12,8,15,7,18,5,-1 
OPEN "BEZIER.OUT" FOR OUTPUT AS #1 
OPEN "BEZ.ps" FOR OUTPUT AS #2 
CLS 
psscale = 20 
FOR example% = 1 TO 3 
REDIM rawdata(32) 
FOR I% = 0 TO 32 
READ rawdata(I%) 
IF rawdata(I%) < 0! THEN EXIT FOR 
NEXT I% 
n% = I% - 1 
PRINT "Example "; example%; (n% + 1) \ 2; " points" 
PRINT #1, "" 
PRINT #1, "Example "; example%; (n% + 1) \ 2; " points" 
PRINT #1, " # 
x 
y" 
J% = 0 
FOR I% = 0 TO n% STEP 2 
J% = J% + 1 
PRINT #1, USING "### ####.### ####.###"; J%; rawdata(I%); rawdata(I% + 1) 
LPRINT USING "####.### ####.### 3 0 360 arc fill"; rawdata(I%) * psscale; rawdata(I% + 1) * psscale 
PRINT #2, USING "####.### ####.### 3 0 360 arc fill"; rawdata(I%) * psscale; rawdata(I% + 1) * psscale 
NEXT I% 
x0 = rawdata(0) 
y0 = rawdata(1) 
x1 = rawdata(2) 
y1 = rawdata(3) 
x2 = rawdata(n% - 3) 
y2 = rawdata(n% - 2) 
x3 = rawdata(n% - 1) 
y3 = rawdata(n%) 
IF example% = 3 THEN 
’special guess for loop 
x1 = 8 * x1 - 7 * x0 
y1 = 8 * y1 - 7 * y0 
x2 = 8 * x2 - 7 * x3 
y2 = 8 * y2 - 7 * y3 
ELSE 
x1 = 2 * x1 - x0 
y1 = 2 * y1 - y0 
x2 = 2 * x2 - x3 
y2 = 2 * y2 - y3 
END IF 
GOSUB distance 
LPRINT ".1 setlinewidth" 
PRINT #2, ".1 setlinewidth" 
GOSUB curveto 
e1 = totalerror 
FOR Retry% = 1 TO 6 
PRINT 
PRINT "Retry "; Retry% 
PRINT #1, "Retry "; Retry% 
PRINT #1, " x1 
y1 
x2 
y2 
error" 
e3 = .5 

x1a = x1 
DO 
x1 = x1 + (x1 - x0) * e3 
GOSUB distance 
e2 = totalerror 
IF e2 = e1 THEN 
EXIT DO 
ELSEIF e2 > e1 THEN 
x1 = x1a 
e3 = -e3/3 
IF ABS(e3) < .001 THEN EXIT DO 
ELSE 
e1 = e2 
x1a = x1 
END IF 
LOOP 
e3 = .5 
y1a = y1 
DO 
y1 = y1 + (y1 - y0) * e3 
GOSUB distance 
e2 = totalerror 
IF e2 = e1 THEN 
EXIT DO 
ELSEIF e2 > e1 THEN 
y1 = y1a 
e3 = -e3/3 
IF ABS(e3) < .01 THEN EXIT DO 
ELSE 
e1 = e2 
y1a = y1 
END IF 
LOOP 
e3 = .5 
x2a = x2 
DO 
x2 = x2 + (x2 - x3) * e3 
GOSUB distance 
e2 = totalerror 
IF e2 = e1 THEN 
EXIT DO 
ELSEIF e2 > e1 THEN 
x2 = x2a 
e3 = -e3/3 
IF ABS(e3) < .01 THEN EXIT DO 
ELSE 
e1 = e2 
x2a = x2 
END IF 
LOOP 
e3 = .5 
y2a = y2 
DO 
y2 = y2 + (y2 - y3) * e3 
GOSUB distance 
e2 = totalerror 
IF e2 = e1 THEN 
EXIT DO 
ELSEIF e2 > e1 THEN 
y2 = y2a 
e3 = -e3/3 
IF ABS(e3) < .01 THEN EXIT DO 

ELSE 
e1 = e2 
y2a = y2 
END IF 
LOOP 
IF Retry% = 6 THEN 
LPRINT "1 setlinewidth" 
PRINT #2, "1 setlinewidth" 
END IF 
GOSUB curveto 
NEXT Retry% 
LPRINT "100 200 translate" 
PRINT #2, "100 200 translate" 
NEXT example% 
LPRINT "showpage" 
PRINT #2, "showpage" 
CLOSE #1 
CLOSE #2 
END 
’ 
Bezier: 
x = a0 + u * (a1 + u * (a2 + u * a3)) 
y = b0 + u * (b1 + u * (b2 + u * b3)) 
dx4 = x - x4: dy4 = y - y4 
dx = a1 + u * (2 * a2 + u * 3 * a3) 
dy = b1 + u * (2 * b2 + u * 3 * b3) 
z = dx * dx4 + dy * dy4 
s = dx4 * dx4 + dy4 * dy4 
RETURN 
’ 
distance: 
totalerror = 0! 
a3 = (x3 - x0 + 3 * (x1 - x2))/8 
b3 = (y3 - y0 + 3 * (y1 - y2))/8 
a2 = (x3 + x0 - x1 - x2) * 3/8 
b2 = (y3 + y0 - y1 - y2) * 3/8 
a1 = (x3 - x0)/2 - a3 
b1 = (y3 - y0)/2 - b3 
a0 = (x3 + x0)/2 - a2 
b0 = (y3 + y0)/2 - b2 
FOR I% = 2 TO n% - 2 STEP 2 
x4 = rawdata(I%) 
y4 = rawdata(I% + 1) 
stepsize = 2/(n% + 1) 
FOR u = -1! TO 1.01 STEP stepsize 
GOSUB Bezier 
IF s = 0! THEN u1 = u: z1 = z: s1 = s: EXIT FOR 
IF u = -1! THEN u1 = u: z1 = z: s1 = s 
IF s < s1 THEN u1 = u: z1 = z: s1 = s 
NEXT u 
IF s1 <> 0! THEN 
u = u1 + stepsize 
IF u > 1! THEN u = 1! - stepsize 
DO 
GOSUB Bezier 
IF s = 0! THEN EXIT DO 
IF z = 0! THEN EXIT DO 
u2 = u 
z2 = z 
temp = z2 - z1 
IF temp <> 0! THEN 
u = (z2 * u1 - z1 * u2)/temp 

ELSE 
u = (u1 + u2)/2! 
END IF 
IF u > 1! THEN 
u = 1! 
ELSEIF u < -1! THEN 
u = -1! 
END IF 
IF ABS(u - u2) < .0001 THEN EXIT DO 
u1 = u2 
z1 = z2 
LOOP 
END IF 
totalerror = totalerror + s 
NEXT I% 
PRINT totalerror; 
PRINT #1, USING "####.### ####.### ####.### ####.### ######.###"; x1; y1; x2; y2; totalerror 
RETURN 
’ 
curveto: 
LPRINT USING "####.### ####.### moveto"; x0 * psscale; y0 * psscale 
PRINT #2, USING "####.### ####.### moveto"; x0 * psscale; y0 * psscale 
F$ = "####.### ####.### ####.### ####.### ####.### ####.### curveto stroke" 
LPRINT USING F$; x1 * psscale; y1 * psscale; x2 * psscale; y2 * psscale; x3 * psscale; y3 * psscale 
PRINT #2, USING F$; x1 * psscale; y1 * psscale; x2 * psscale; y2 * psscale; x3 * psscale; y3 * psscale 
RETURN 

我想在C++中實現它,因爲我試圖讓我的算法最好地適合貝齊爾從點。

會是什麼上面看起來像僞代碼或C/C++? 感謝

+0

現在看起來像pseuedocode。 – 2010-08-17 19:24:57

+0

如果你只是想要一條貝塞爾曲線,只需要查找Bezier曲線的算法,不要試圖對一些原始語言進行逆向工程,這些語言被設計爲人類難以閱讀,因此機器閱讀起來更容易。 – 2010-08-17 19:25:37

+0

這不是僞代碼。這顯然是全功能的代碼 – Falmarri 2010-08-17 19:26:51

回答

3

這裏的最好的辦法是通過分割位碼位,做輕微的重構,直到它處於可用狀態。數據首先可以變成全局變量。

然後開始利用代碼的小塊,使之成爲功能。起初他們只會使用一堆全局數據。當你將這些部分改寫成C++的時候,事情會變得更加清晰。

一旦你有大部分的代碼內置了功能,那麼你可以開始重構的變量。目標是去除所有全局非常量數據,並將所有工作數據都當成本地數據。常量值可以保持名稱空間級別的初始化數據。

最後,一旦你擁有它基於過程的,你可以決定是否值得封裝工作納入對象和方法的努力。取決於程序需要維護多久,將數據和方法分組可能是一個很好的長期步驟。

相關問題