2010-08-17 187 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++的时候,事情会变得更加清晰。

一旦你有大部分的代码内置了功能,那么你可以开始重构的变量。目标是去除所有全局非常量数据,并将所有工作数据都当成本地数据。常量值可以保持名称空间级别的初始化数据。

最后,一旦你拥有它基于过程的,你可以决定是否值得封装工作纳入对象和方法的努力。取决于程序需要维护多久,将数据和方法分组可能是一个很好的长期步骤。

相关问题