|
递归曲线C-曲线(算法) C Curve Recursive Algorithm 本文是关于递归曲线C-曲線算法的笔记。C-曲線的生成算法如下图所示。
n级中的一根线段可以分解为2根(n-1)级的线段。如果n级的线段的长度是1.0,那么(n-1)级的线段的长度就是0.7010(=1/√2)。它们与n级的线段成45°夹角。上面右侧的图,是10级C-曲線。下面是本人编写的VC++程序片断。 typedef struct tagFPOINT
{
double x;
double y;
} FPOINT;
void CRecursiveCurvesView::DrawLine(FPOINT p1,FPOINT p2, CDC* pDC)
{
pDC->MoveTo((int)(p1.x+0.5), (int)(p1.y+0.5));
pDC->LineTo((int)(p2.x+0.5), (int)(p2.y+0.5));
}
FPOINT CRecursiveCurvesView::RotateLine(FPOINT p1, FPOINT p2, double alpha)
{
double x0 = p1.x;
double y0 = p1.y;
double x1 = p2.x - x0;
double y1 = p2.y - y0;
FPOINT pntRet;
pntRet.x = x1 * cos(alpha) - y1 * sin(alpha) + x0;
pntRet.y = x1 * sin(alpha) + y1 * cos(alpha) + y0;
return pntRet;
}
FPOINT CRecursiveCurvesView::ShortenLine(FPOINT p1,FPOINT p2, double Ratio)
{
FPOINT pntRet;
if (p1.x == p2.x && p1.y == p2.y)
{
pntRet = p1;
}
if (p1.x == p2.x)
{
pntRet.x = p1.x;
pntRet.y = p1.y + (p2.y - p1.y) * Ratio;
}
else if (p1.y == p2.y)
{
pntRet.y = p1.y;
pntRet.x = p1.x + (p2.x - p1.x) * Ratio;
}
else
{
pntRet.x = p1.x + (p2.x - p1.x) * Ratio;
pntRet.y = p1.y + (p2.y - p1.y) * Ratio;
}
return pntRet;
}
void CRecursiveCurvesView::C_Curve(int n, FPOINT p1, FPOINT p2, CDC* pDC)
{
if (n == 1)
{
DrawLine(p1, p2, pDC);
}
else
{
FPOINT pc = ShortenLine(p1, p2, 1.0 / sqrt(2.0));
pc = RotateLine(p1, pc, -atan(1.0));
C_Curve(n - 1, p1, pc, pDC);
C_Curve(n - 1, pc, p2, pDC);
}
}
void CRecursiveCurvesView::OnCCirve()
{
CClientDC dc(this);
FPOINT p1 = {400, 328};
FPOINT p2 = {400, 200};
C_Curve(10, p1, p2, &dc);
}
|