Форум: "Начинающим";
Текущий архив: 2008.07.27;
Скачать: [xml.tar.bz2];
ВнизВекторная графика Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.007 c