Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.07.27;
Скачать: CL | DM;

Вниз

Векторная графика   Найти похожие ветки 

 
batya-x   (2008-06-27 22:54) [0]

Господа...
Задача, есть векторный рисунок, линия, не важно какого формата,
например линия, нужно эту линию разделить на 100 частей и по очереди сообщить их координаты относительне или абсолюные
Весь инет облазял...

Если не совсем правильно вырозился, то ,Мне это нужно для управления координатами сверла фрейзерного станка... Спасиб


 
Правильный-Вася   (2008-06-27 23:01) [1]

простая геометрия, теорема Пифагора
вычисляем длину, делим на 100
применяем для вычисления координат следующей точки в цикле
все


 
batya-x   (2008-06-27 23:22) [2]

Это понятно, но если линия кривая, типа

http://img66.imageshack.us/img66/2379/76549826lj0.gif


 
MBo ©   (2008-06-28 11:25) [3]

Если это кривая в форме Безье, то она легко рекурсивно делится на части.
Иначе нужны подробности о способе задания кривой


 
batya-x   (2008-06-30 00:45) [4]

небыло возможноти выхода в инет пару дней...

Не пооветуете каких нибуть статеек по векторой графике, может ссылки


 
reonid ©   (2008-06-30 13:49) [5]

>нужно эту линию разделить на 100 частей и по очереди сообщить
>их координаты относительне или абсолюные

На рисунке действительно кривая Безье.
В рамках библиотеки RDraw, которая на этом рисунке используется,
это будет выглядеть так:

(алгоритм на основе простого перебора. Я не слишком тщательно его тестировал)

{-------------------------------------------------------------------------}
var
   bzr: TRBezier;
   arr: TDynArrayOfTPointF;
   len, step: Double;
begin
 // bzr := ...
 len := GetBezierTotalLength(bzr);
 step := len/99.000001;
 arr := ConvertBezierToArray(bzr, step); // искомый массив точек
end;

{-------------------------------------------------------------------------}

unit RBzrUtils;

interface

uses
 Classes, RTypes, RCore, RGeom, RBezier;

type
 TDynArrayOfTPointF = array of TPointF;
 TDynArrayOfDouble = array of Double;

function GetBezierTotalLength(Bzr: TRBezier): Double;
function ConvertBezierToArray(Bzr: TRBezier; Step: Double): TDynArrayOfTPointF;
function BezierValuesAt(Bzr: TRBezier; Position: Double; Coord: Char): TDynArrayOfDouble;

implementation

const
 BEZIER_ACCURACY = 2000;

function GetBezierTotalLength(Bzr: TRBezier): Double;
var i, j, N: Integer;
   h: Double;
   pt0, pt1: TPointF;
begin
 N := BEZIER_ACCURACY;
 h := 1/N;

 Result := 0;

 pt1 := Bzr.GetIntermediatePoint(0, 0);

 for i := Bzr.Low to Bzr.High + Integer(Bzr.Closed)-1 do
   for j := 1{!} to N do
   begin
     pt0 := pt1;
     pt1 := Bzr.GetIntermediatePoint(i, j*h);

     Result := Result + DistanceF(pt0, pt1);
   end;
end;

function ConvertBezierToArray(Bzr: TRBezier; Step: Double): TDynArrayOfTPointF;
var i, j, k, N: Integer;
   h, L, D, u: Double;
   pt, pt0, pt1: TPointF;

   procedure Add(const Pt: TPointF);
   var M: Integer;
   begin
     M := Length(Result);
     SetLength(Result, M+1);
     Result[M] := Pt;
   end;

begin
 SetLength(Result, 0);

 N := BEZIER_ACCURACY;
 h := 1/N;

 k := 0;
 L := 0;

 pt1 := Bzr.GetIntermediatePoint(0, 0);

 Add(pt1); {Step*0}
 Inc(k);

 for i := Bzr.Low to Bzr.High + Integer(Bzr.Closed)-1 do
 begin
   for j := 1{!} to N do
   begin
     pt0 := pt1;
     pt1 := Bzr.GetIntermediatePoint(i, j*h);

     D := DistanceF(pt0, pt1);
     L := L + D;

     if L >= Step*k then
     begin
       u := ( Step*k - (L-D) )/D;

       pt.X := u*pt1.X + (1-u)*pt0.X;
       pt.Y := u*pt1.Y + (1-u)*pt0.Y;

       Add(pt);
       Inc(k);
     end;
   end;
 end;
end;

function BezierValuesAt(Bzr: TRBezier; Position: Double; Coord: Char): TDynArrayOfDouble;
var i, j, N: Integer;
   h, L, D, u, z: Double;
   pt, pt0, pt1, d10, d0, d1: TPointF;
   b, skipNext: Boolean;

   procedure Add(const V: Double);
   var M: Integer;
   begin
     M := Length(Result);
     SetLength(Result, M+1);
     Result[M] := V;
   end;

begin
 SetLength(Result, 0);

 N := BEZIER_ACCURACY;
 h := 1/N;
 skipNext := False;

 L := 0;

 pt1 := Bzr.GetIntermediatePoint(0, 0);

 for i := Bzr.Low to Bzr.High + Integer(Bzr.Closed)-1 do
   for j := 1{!} to N do
   begin
     pt0 := pt1;
     pt1 := Bzr.GetIntermediatePoint(i, j*h);

     if skipNext then
     begin
       skipNext := False;
       Continue;
     end;

     d0 := PointF(pt0.X - Position, pt0.Y - Position);
     d1 := PointF(pt1.X - Position, pt1.Y - Position);
     d10  := PointF(pt1.X - pt0.X, pt1.Y - pt0.Y);

     case Coord of
       "x", "X": z := d0.X*d1.X;
       "y", "Y": z := d0.Y*d1.Y;
     end;

     b := (z <= 0);
     if z = 0 then skipNext := True;

     if b then
     begin
       case Coord of
         "x", "X": u := -d0.X/d10.X;
         "y", "Y": u := -d0.Y/d10.Y;
       end;

       pt.X := u*pt1.X + (1-u)*pt0.X;
       pt.Y := u*pt1.Y + (1-u)*pt0.Y;

       case Coord of
         "x", "X": Add(pt.Y);
         "y", "Y": Add(pt.X);
       end;
     end;
   end;
end;

end.

{--------------------------------------------------------------------------}



Страницы: 1 вся ветка

Текущий архив: 2008.07.27;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.019 c
9-1171983109
Kav
2007-02-20 17:51
2008.07.27
smd2v12-src большая модель приводит к Out of memory


2-1214633047
Yury
2008-06-28 10:04
2008.07.27
Access violation...


15-1213004432
LightRipple
2008-06-09 13:40
2008.07.27
Коварный inline :)


2-1214306045
Тын-Дын
2008-06-24 15:14
2008.07.27
Корректность конструкции при переопределении конструктора


2-1214392234
Res
2008-06-25 15:10
2008.07.27
wininet