New tool Quadratic Bézier curve.
Issue #449
on hold
Add new tool Quadratic Bézier curve.
Possible code implementation:
//------------------------------------------------------------------------
void curve3_div::init(double x1, double y1,
double x2, double y2,
double x3, double y3)
{
m_points.remove_all();
m_distance_tolerance = 0.5 / m_approximation_scale;
m_distance_tolerance *= m_distance_tolerance;
bezier(x1, y1, x2, y2, x3, y3);
m_count = 0;
}
//------------------------------------------------------------------------
void curve3_div::recursive_bezier(double x1, double y1,
double x2, double y2,
double x3, double y3,
unsigned level)
{
if(level > curve_recursion_limit)
{
return;
}
// Вычислить все средние точки отрезков
//----------------------
double x12 = (x1 + x2) / 2;
double y12 = (y1 + y2) / 2;
double x23 = (x2 + x3) / 2;
double y23 = (y2 + y3) / 2;
double x123 = (x12 + x23) / 2;
double y123 = (y12 + y23) / 2;
double dx = x3-x1;
double dy = y3-y1;
double d = fabs(((x2 - x3) * dy - (y2 - y3) * dx));
if(d > curve_collinearity_epsilon)
{
// Обыкновенный случай
//-----------------
if(d * d <= m_distance_tolerance * (dx*dx + dy*dy))
{
// Если “кривизна” не превышает значение distance_tolerance,
// то имеется тенденция завершить деление.
//----------------------
if(m_angle_tolerance < curve_angle_tolerance_epsilon)
{
m_points.add(point_type(x123, y123));
return;
}
// Критерии угла и точки перегиба
//----------------------
double da = fabs(atan2(y3 - y2, x3 - x2) –
atan2(y2 - y1, x2 - x1));
if(da >= pi) da = 2*pi - da;
if(da < m_angle_tolerance)
{
// Наконец, можно остановить рекурсию
//----------------------
m_points.add(point_type(x123, y123));
return;
}
}
}
else
{
// Полностью коллинеарный случай
//-----------------
dx = x123 - (x1 + x3) / 2;
dy = y123 - (y1 + y3) / 2;
if(dx*dx + dy*dy <= m_distance_tolerance)
{
m_points.add(point_type(x123, y123));
return;
}
}
// Продолжить деление
//----------------------
recursive_bezier(x1, y1, x12, y12, x123, y123, level + 1);
recursive_bezier(x123, y123, x23, y23, x3, y3, level + 1);
}
//------------------------------------------------------------------------
void curve3_div::bezier(double x1, double y1,
double x2, double y2,
double x3, double y3)
{
m_points.add(point_type(x1, y1));
recursive_bezier(x1, y1, x2, y2, x3, y3, 0);
m_points.add(point_type(x3, y3));
}
Comments (7)
-
-
In maths terms, 'quadratic bezier curve', in tailor's/textile designers terms, 'rounding out a corner' .. yes?
-
reporter No. Don't think so.
-
Not exactly. You can connect any two points with a quadratic bezier curve, there's no need for a third "corner" point between them.
-
reporter - changed status to on hold
Because this proposal doesn't add something really new i have decided to close it.
-
Yes just use the same point twice as control points in current Curve tools.
-
reporter - removed milestone
Removing milestone: v0.5.0 (automated comment)
- Log in to comment