Основы компьютерного моделирования физических и технических систем. Основы моделирования физических и технических систем, страница 8

Round((CenterY+Radius)*Scale),   //Y2

-1,1,1,1)

end;

function TCircle.GetMaxX: Extended;

begin

Result := CenterX + Radius

end;

function TCircle.GetMaxY: Extended;

begin

Result := CenterY + Radius

end;

function TCircle.GetMinX: Extended;

begin

Result := CenterX - Radius

end;

function TCircle.GetMinY: Extended;

begin

Result := CenterY - Radius

end;

function TCircle.GetX(aY: Extended; IsFirst: boolean): Extended;

var

dX, dY: Extended;

begin

//Для защиты от ошибок округления

if Equals(aY, GetMinY)or Equals(aY, GetMaxY) then

Result := CenterX

else

begin

dY := (aY - CenterY)/Radius;

if abs(dY) <= 1 then

begin

dX := Sin(ArcCos(dY));

if IsFirst then

dX := -dX;

Result := dX*Radius+CenterX;

end

else

Result := -1;

end;

end;

function TCircle.GetY(aX: Extended; IsFirst: boolean): Extended;

var

dX, dY: Extended;

begin

//Для защиты от ошибок округления

if Equals(aX, GetMinX)or Equals(aX, GetMaxX) then

Result := CenterY

else

begin

dX := (aX - CenterX)/Radius;

if abs(dX) <= 1 then

begin

dY := Cos(ArcSin(dX));

if IsFirst then

dY := -dY;

Result := dY*Radius+CenterY;

end

else

Result := -1;

end;

end;

{ TSquare }

constructor TSquare.Create(X1, Y1, X2, Y2: Extended);

begin

inherited Create;

Left := X1;

Top := Y1;

Right := X2;

Bottom := Y2;

end;

procedure TSquare.Draw(C: TCanvas; Scale: Extended);

begin

C.Pen.Color := clBlack;

C.Polyline([

Point(Round(Left*Scale), Round(Top*Scale)),

Point(Round(Left*Scale), Round(Bottom*Scale)),

Point(Round(Right*Scale), Round(Bottom*Scale)),

Point(Round(Right*Scale), Round(Top*Scale)),

Point(Round(Left*Scale), Round(Top*Scale))

]);

end;

function TSquare.GetMaxX: Extended;

begin

Result := Right;

end;

function TSquare.GetMaxY: Extended;

begin

Result := Bottom;

end;

function TSquare.GetMinX: Extended;

begin

Result := Left;

end;

function TSquare.GetMinY: Extended;

begin

Result := Top;

end;

function TSquare.GetX(aY: Extended; IsFirst: boolean): Extended;

begin

if InRange(aY, Top - 1e-6, Bottom + 1e-6) then

begin

if IsFirst then

Result := Left

else

Result := Right

end

else

Result := -1

end;

function TSquare.GetY(aX: Extended; IsFirst: boolean): Extended;

begin

if InRange(aX, Left - 1e-6, Right + 1e-6) then

begin

if IsFirst then

Result := Top

else

Result := Bottom

end

else

Result := -1

end;

function DistCompare(Item1, Item2: Pointer): Integer;

var

Angle1, Angle2: Extended;

begin

Angle1 := ArcTan2(TRealPoint(Item1).Y-__Y,TRealPoint(Item1).X-__X);

Angle2 := ArcTan2(TRealPoint(Item2).Y-__Y,TRealPoint(Item2).X-__X);

Result := -Round((Angle1-Angle2)*1000);

end;

//Главная процедура тесселяции

procedure Tesselate(Contours: TContours; MinX, MaxX, MinY, MaxY, DX, DY: Extended; Model: TModel);

var

I, iX, iY, nX, nY: Integer;

CurX, CurY, NewX, NewY: Extended;

PointsInSquare: TList;

CornerInSquare: array[1..4]of Boolean;

BasePoint: TRealPoint;

begin

//Очистим модель

Model.Clear;

PointsInSquare := TList.Create;

//Определим число квадратов сетки 

NX := ceil(((MaxX) - MinX)/DX)+1;

NY := ceil(((MaxY) - MinY)/DY)+1;

//Тесселируем квадраты

for iY := 0 to NY do

begin

CurY := MinY+iY*DY;

for iX := 0 to NX do

begin

CurX := MinX+iX*DX;

//CurX, CurY - координаты верхнего левого угла квадрата

//Найдем координаты нижнего правого угла

NewX := CurX + DX;

NewY := CurY + DY;

PointsInSquare.Clear;

//Если первый угол внутри квадрата - добавим его в список

CornerInSquare[1] := Contours.Inside(CurX, CurY);

if CornerInSquare[1] then

PointsInSquare.Add(Model.AddVertex(CurX, CurY));

//Если второй угол внутри квадрата - добавим его в список

CornerInSquare[2] := Contours.Inside(CurX, NewY);

if CornerInSquare[2] then

PointsInSquare.Add(Model.AddVertex(CurX, NewY));

//Если четвертый угол внутри квадрата - добавим его в список

CornerInSquare[4] := Contours.Inside(NewX, CurY);

if CornerInSquare[4] then

PointsInSquare.Add(Model.AddVertex(NewX, CurY));

//Если третий угол внутри квадрата - добавим его в список

CornerInSquare[3] := Contours.Inside(NewX, NewY);

if CornerInSquare[3] then

PointsInSquare.Add(Model.AddVertex(NewX, NewY));

//Если ни одного угла нет - ничего не рисуем