Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Длина дуги(математика)


Автор: Zorak 14.12.2009, 14:36
Всем привет. Значит есть такая ситуация: В делфи написана програма, которая рисует по точкам кривые безье:

  А1         А2         А3         А4          А5         А6         А7         А8         А9        А10 
  0---------0---------0---------0---------0---------0---------0---------0---------0---------0

Здесь три кривые: А1-А4, А4-А7, А7-А10. Все три линии надо разглядывать как дуги, Мне нужно найти длину каждой из них (координаты известны). Возможно ли такое, а то я пытался рытся у всяких там учебниках, то ничего такого не нашол, помогите кто знает). Если надо какието дополнительные сведения то говорите, все напишу.
Спасибо!

Автор: Dimonka2 14.12.2009, 17:58
Можно разбить кривые на очень короткие отрезки и посчитать длины отрезков. 

Автор: RomanEEP 14.12.2009, 20:30
Если т-ки A1-A4 определяют дугу, то её центр С лежит на пересечении перпендикуляров к отрезкам A1A2 и A3A4. А длина дуги будет равна углу (в радианах) между перепендикулярами умножить на радиус дуги (например расстояние CA1)

Автор: Zorak 15.12.2009, 11:06
Хм.. спасибо большое, сьодня-завтра попробую, отпишу результат.

Автор: Zorak 15.12.2009, 20:31
А как найти радиус и кут, потому что они у нас неизвестные!!!!!!!

Автор: RomanEEP 16.12.2009, 06:59
C - точка пересечения перпендикуляров, 
тогда радиус r = Sqrt(Sqr(Cx-A1x) + Sqr(Cy-A1y))

Автор: Zorak 16.12.2009, 10:43
Хм.. спасибо !. попоже отпишусь)

Автор: Zorak 17.12.2009, 20:01
RomanEEP это все конечно хорошо, но видимо ты не понял ситуации или я плохо выразился). Смотри. я нарисовал прямую, а на самом деле точки могут располагатся примерно вот так http://www.picatom.com/17/03-155.html или так http://www.picatom.com/17/macosxprog310-1.html . Здесь только одна дуга и 4 точки. Зная координаты этих точек и больше ничего нужно найти длину этой дуги. (кривой безье). Возможно ли такое?

Автор: RomanEEP 17.12.2009, 21:29
Обычно когда говорят просто дуга подразумевают дугу окружности.
С безье все несколько сложнее. Вот сишный код:
Код

const double TOLERANCE = 0.0000001;  // Application specific tolerance

extern double sqrt(double);

struct point2d {
        double x, y;
};

double q1, q2, q3, q4, q5;      // These belong to balf()


//---------------------------------------------------------------------------
double balf(double t)                   // Bezier Arc Length Function
{
    double result = q5 + t*(q4 + t*(q3 + t*(q2 + t*q1)));
    result = sqrt(result);
    return result;
}

//---------------------------------------------------------------------------
// NOTES:       TOLERANCE is a maximum error ratio
//                      if n_limit isn't a power of 2 it will be act like the next higher
//                      power of two.
double Simpson (
    double (*f)(double),
    double a,
    double b,
    int n_limit,
    double TOLERANCE)
{
    int n = 1;
    double multiplier = (b - a)/6.0;
    double endsum = f(a) + f(b);
    double interval = (b - a)/2.0;
    double asum = 0;
    double bsum = f(a + interval);
    double est1 = multiplier * (endsum + 2 * asum + 4 * bsum);
    double est0 = 2 * est1;

    while(n < n_limit 
      && (_ABS(est1) > 0 && _ABS((est1 - est0) / est1) > TOLERANCE)) {
    n *= 2;
    multiplier /= 2;
    interval /= 2;
    asum += bsum;
    bsum = 0;
    est0 = est1;
    double interval_div_2n = interval / (2.0 * n);

    for (int i = 1; i < 2 * n; i += 2) {
        double t = a + i * interval_div_2n;
        bsum += f(t);
    }

    est1 = multiplier*(endsum + 2*asum + 4*bsum);
    }

    return est1;
}

//
//---------------------------------------------------------------------------
//
double BezierArcLength(point2d p1, point2d p2, point2d p3, point2d p4)
{
    point2d k1, k2, k3, k4;

    k1 = -p1 + 3*(p2 - p3) + p4;
    k2 = 3*(p1 + p3) - 6*p2;
    k3 = 3*(p2 - p1);
    k4 = p1;

    q1 = 9.0*(sqr(k1.x) + sqr(k1.y));
    q2 = 12.0*(k1.x*k2.x + k1.y*k2.y);
    q3 = 3.0*(k1.x*k3.x + k1.y*k3.y) + 4.0*(sqr(k2.x) + sqr(k2.y));
    q4 = 4.0*(k2.x*k3.x + k2.y*k3.y);
    q5 = sqr(k3.x) + sqr(k3.y);

    double result = Simpson(balf, 0, 1, 1024, 0.001);
    return result;
}

Автор: Zorak 25.12.2009, 15:46
Ступор =(

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)