Войти
ПрограммированиеФорумГрафика

Сгладить ломаную линию (кривые Безье и т.п.) (2 стр)

Страницы: 1 2 3 4 5 Следующая »
#15
23:08, 2 окт 2009

Executor
А это узловой вектор, он может быть юниформным допустим, а может быть со специальными значениями.
Например с помощью юниформного нельзя нарисовать круг, а если сделать специальные значения то можно.
Вобщем тебе хватит юниформного я думаю, т.е. вектор вида 1 ... 1 2 3 4 5 ... 5 (кол-во 1 и 5 зависит от степени
кривой, там в теории должно это поясняться, это чтобы концы кривой точно входили в точку начала и в точку конца).

Если вяло будет идтт процесс я могу поискать исходники, у меня отдельно была програмка с реализацией NURBS с
юниформным узловым вектором и рисованием кривой через GDI. Так что если надо - обращайся, мне просто лень
просто так искать и цеплять бекапный винт :)

ЗЫ. Собственно я описал "uniform open knot vector", как можно догадаться. Вообще значения узлового вектора
используется в качестве параметра для получения точек на кривой, т.е. если уравнение кривой C(u), то u - как раз
может принимать значения от минимального до максимального в значения узлового вектора (в примере выше
это от 1 до 5, с любым шагом). Можно конечно сделать чтобы параметр был от 0 до 1, как кому удобней.

#16
23:14, 2 окт 2009

http://en.wikipedia.org/wiki/B%C3%A9zier_curve
читаем Generalization

#17
2:23, 3 окт 2009

Executor
Когда сам разбирался в теме, нашел одну очень хорошую доку, где очень подробно все разжевано по кривым, сплайнам, параметрическим уравнениям и т.д. Очень рекомендую к изучению:
http://mygdc.gdconf.com/vault/play/1644

#18
2:55, 3 окт 2009

ИМХО нет ничего проще чем взять книжку по выч.мату и начать с азов.

#19
10:32, 3 окт 2009

KpeHDeJIb
> озов
Это что такое?

#20
11:07, 3 окт 2009

Попробуй, например, так:
Есть ломаная состоящая из точек 0,1,2,3....
Для плавного соединение отрезка 0-1 строим кривую по четырем точкам: 0, точке на отрезке 0-1(можно середину), т. на 1-2(тоже середину), но уже зеркальную, и т. 1.
Потом соединяем отрезок 1-2 итд.
Думаю это сработает.

#21
12:55, 3 окт 2009

Ту задачу что на кратинке прекрасно решает Безье. Примерно тот же результат и будет.
С Кэмул-Ромом будет не такая гладкая, но зато проходящая через все точки.

#22
13:53, 3 окт 2009

Sergio666
> Это что такое?
Грамматическая ошибка, очевидно :)

#23
16:51, 3 окт 2009

Буду в НУРБСах пока разбираться пробывать...

Shockwave
Спс, полезная пдфина..

#24
21:37, 3 окт 2009

Executor
http://www.gamedev.ru/community/gamedev_lecture/articles/?id=2921

ку?

#25
22:28, 3 окт 2009

Чтото нурбсы я не асилил... :)
В общем вроде сделал Безье на большое количество точек, но косяк какойто есть, когда точек больше 30... Вот весь код:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Math;

type
  TForm1 = class(TForm)
    procedure FormPaint(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TVec2 = record
    X, Y: Single;
  end;
  TVec2Arr = array of TVec2;

var
  Form1: TForm1;
  Points: TVec2Arr;
  Curve: TVec2Arr;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  I, J, P, R, Y, C: Integer;
  S, T, V: Single;
begin
  SetLength(Points, 0);
  SetLength(Points, 30); // Если 31 - жопа
  for I := 0 to Length(Points) - 1 do
  begin
    Points[I].X := 10 + I * 10;
    Points[I].Y := 10 + I * 2 + Random(100);
  end;
  //
  SetLength(Curve, 0);
  SetLength(Curve, 100);
  for J := 0 to 99 do
  begin
    T := J / 99;
    S := 1.0 - T;
    //
    P := Length(Points) - 1;
    R := 0;
    //
    C := 1;
    Y := Length(Points) - 1;
    Curve[J].X := 0;
    Curve[J].Y := 0;
    for I := 0 to Y do
    begin
      V := Power(S, P) * Power(T, R);
      Curve[J].X := Curve[J].X + C * V * Points[I].X;
      Curve[J].Y := Curve[J].Y + C * V * Points[I].Y;
      Dec(P);
      Inc(R);
      C := C * (Y - I) div (I + 1); // Calculate Pascal Triangle
    end;
  end;
end;

procedure TForm1.FormPaint(Sender: TObject);
var
  I: Integer;
begin
  if Length(Points) > 1 then
  begin
    Canvas.Pen.Width := 1;
    Canvas.Pen.Color := clBlack;
    Canvas.MoveTo(Trunc(Points[0].X), Trunc(Points[0].Y));
    for I := 1 to Length(Points) - 1 do
      Canvas.LineTo(Trunc(Points[I].X), Trunc(Points[I].Y));
  end;
  //
  if Length(Curve) > 1 then
  begin
    Canvas.Pen.Width := 4;
    Canvas.Pen.Color := clBlue;
    Canvas.MoveTo(Trunc(Curve[0].X), Trunc(Curve[0].Y));
    for I := 1 to Length(Curve) - 1 do
      Canvas.LineTo(Trunc(Curve[I].X), Trunc(Curve[I].Y));
  end;
end;

Может я гдето ошибся?

Правка:
Понял в чём косяк, числа в треугольнике паскаля получаются очень большие, что в Integer не входит... Как это решить? 30 точек уж очень мало... Мне бы так тыщёнку сгладить...

JokerR
Спс, почитаю и это...

KpeHDeJIb
Посмотри свой код плиз... :)

#26
22:41, 3 окт 2009
ИзображениеИзображение
#27
22:46, 3 окт 2009

Хотелось бы ещё кривизну в разных участках както регулировать... Какимито может коэффициентами, не знаю...

Zegalur
Ты это к чему?

#28
23:18, 3 окт 2009

Executor
Эм... Ты понимаешь, что чем дальше точка находится тем меньшее влияние она оказывает?
То есть фактически разница между тем, чтобы использовать 10 или 100 точек будет чаще всего вообще незаметна?

#29
23:21, 3 окт 2009

@!!ex
Да, но я пока не очень понял как можно сделать, чтобы было ограничение...

Страницы: 1 2 3 4 5 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.