3.1 Способы визуализации трехмерного пространства

Для визуализации используются два вида проекций: параллельные (аксонометрические) (на рисунке слева) и центральные (перспективные)

(на рисунке справа). При построении аксонометрической проекции пространственного тела его отдельные точки сносятся на плоскость проекции параллельным пучком лучей, а при построении центральной проекции – пучком лучей исходящих из одной точки, соответствующей положению глаз наблюдателя. Частным случаем аксонометрической проекции является проекция ортографическая, при построении которой плоскость проекции выравнивается параллельно одной из координатных плоскостей.

3.2 Перекрытие

Под перекрытием понимается тот факт, что невозможно одновременно видеть все грани многогранника и какие - то грани обязательно окажутся невидимыми. Проблема состоит в том, как узнать какие грани видны, а какие нет. В проекте мы рассматриваем только выпуклые многогранники, поэтому для реализации перекрытия используется тот факт, что нормальный вектор к каждой грани направлен извне. Т.е. если использовать ортографическую проекцию, то тот факт, что координатная составляющая (оси проекции) нормального вектора положительна, то грань видима, если отрицательна, то грань перекрыта.

3.3 Освещенность

Освещенность граней вычисляется путем, вычисления угла (синуса угла) между нормальным вектором к грани и осью ортографической проекции.


Глава IV. Создание компьютерного приложения

4.1 Постановка требований к реализуемому проекту

1.         Простота использования.

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

3.         Интерактивность.

4.         Быстрота работы.

5.         Простота создания входного файла.

4.2 Разработка интерфейса программы

При разработке интерфейса программы уклон делался на стандартизацию меню и удобство использования. Также необходима функция встроенных подсказок (всплывающих и в строке состояния).

4.2.1 Окна проекций

В программе используются три окна проекции: вид сверху, вид слева, вид спереди, перспектива. Размер окон проекции изменяется путем перемещения цента разделителя. Также здесь показаны оси координат. Существует возможность включения координатной сетки.


4.2.2 Меню пользователя

Файл

Открыть (загрузка файла многогранника).

Сохранить (сохранение файла).

Выход (выход из программы).

Правка

Сброс (сброс всех измененных параметров).

Вид

Каркас (отображаются ребра многогранника).

Заливка (вывод граней, с расчетом их освещенности).

Обозначить (обозначить вершины многогранника).

Сетка (вывод сетки координат).

Инструменты

Выбрать (позволяет выбирать и перемещать точки задающие сечение).

Переместить (перемещение многогранника).

Повернуть (поворот многогранника).

Масштаб (масштаб окон проекций).

Стирка (позволяет отключать заливку выбранной грани).

Заливка (позволяет включить заливку выбранной грани).

Ограничить (ограничение манипулирования сценой по осям координат).

Цент поворота (изменение центра поворота).

Распространить (изменять координаты точек задающих сечение вместе с координатами многогранника).

Сечение

Построить (построение сечения путем задания трех точек плоскости сечения).

Удалить (удаление сечения).

Вид (настройка вида сечения).

Привязать (привязка выбранной точки сечения к элементам многогранника).

Просмотр (окно просмотра сечения).

Настройка

Цвет (вызов диалога изменения цветовой схемы)

4.2.3 Основные методы работы

Основной метод работы заключается в выборе инструмента, затем наведении курсора на объект действия и манипуляция с помощью нажатия клавиши мыши.

4.2.4 Диалог просмотра сечения

Вывод многоугольника сечения производится с помощью поворота плоскости сечения в положение параллельности плоскости XOY.


Заключение

В заключении данного проекта рассмотрим возможные пути дальнейшего развития проекта и его использования, а также оценку выполнения поставленной задачи и отметим полученные результаты. Поставленная перед началом работы цель: создание инструмента, позволяющего наглядно и интерактивно изучать пространственные тела и их сечения – реализована.

Создано приложение, которое позволяет загружать пространственные тела и манипулировать ими – это уже можно использовать при начальном изучении пространственных тел. Далее в программе реализована функция построения сечения пространственных фигур плоскостью, которая задается тремя точками, координаты которых можно изменять. Минусом программы является возможность изучения только выпуклых фигур и невозможность построения более одного сечения.

Пути дальнейшего развития проекта:

1.         Построение нескольких сечений;

2.         Возможность загрузки невыпуклых фигур;

3.         Подбор задач решаемых с помощью созданного приложения;

4.         Разработка методик применения программы в обучении;

5.         Создание конструктора пространственных тел;

6.         Создание интерактивного инструмента для построения сечений пространственных фигур аксиоматическим методом («Живая стереометрия»);

7.         Создание обучающего модуля и методического сопровождения к нему;

8.         Применение на практике.

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


Приложение

Текст программы

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, ComCtrls, Menus, ExtCtrls, jpeg, ToolWin, StdCtrls, ImgList;

type

Point=record x,y,z:real end; {координаты точки}

Vector=record x,y,z:real end; {координаты ветора}

type

TForm1 = class(TForm)

StatusBar1: TStatusBar; StatusBar2: TStatusBar; MainMenu1: TMainMenu;

N1: TMenuItem; N2: TMenuItem; N3: TMenuItem; N4: TMenuItem; N5: TMenuItem; N6: TMenuItem;

N20: TMenuItem; N21: TMenuItem; N22: TMenuItem; N18: TMenuItem; N25: TMenuItem; N30: TMenuItem;

N31: TMenuItem; N32: TMenuItem; N33: TMenuItem; OD1: TOpenDialog; SD1: TSaveDialog;

PTop: TPanel; ITop: TImage; PFront: TPanel; PLeft: TPanel; PPerspective: TPanel; IFront: TImage;

ILeft: TImage; IPerspective: TImage; GroupBox1: TGroupBox; Vertikal: TPanel; Horizontal: TPanel; Panel3: TPanel;

Centr: TPanel; ImList1: TImageList; N23: TMenuItem; ToolBar1: TToolBar;

ToolButton1: TToolButton; ToolButton2: TToolButton; ToolButton3: TToolButton; ToolButton4: TToolButton;

ToolButton5: TToolButton; ToolButton6: TToolButton; ToolButton7: TToolButton; ToolButton8: TToolButton;

ToolButton9: TToolButton; ToolButton10: TToolButton; ToolButton14: TToolButton; ToolButton19: TToolButton;

ToolButton11: TToolButton; ToolButton12: TToolButton; Label1: TLabel; ToolButton13: TToolButton;

N26: TMenuItem; N27: TMenuItem; N28: TMenuItem; N29: TMenuItem; N34: TMenuItem; N35: TMenuItem;

N36: TMenuItem; N37: TMenuItem; N38: TMenuItem; N39: TMenuItem; N40: TMenuItem; N41: TMenuItem;

N42: TMenuItem; N43: TMenuItem; N45: TMenuItem; N46: TMenuItem; N47: TMenuItem; N51: TMenuItem;

IntWiew: TMenuItem; N7: TMenuItem; N8: TMenuItem; N9: TMenuItem; N10: TMenuItem; N11: TMenuItem;

N12: TMenuItem; N13: TMenuItem; N14: TMenuItem; N15: TMenuItem; N16: TMenuItem; N17: TMenuItem;

N24: TMenuItem; N19: TMenuItem; Mag1: TMenuItem; Mag2: TMenuItem; Mag3: TMenuItem;

procedure N5Click(Sender: TObject);

procedure CentrMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

procedure CentrMouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure FormCreate(Sender: TObject); procedure FormResize(Sender: TObject); procedure N2Click(Sender: TObject);

procedure ITopClick(Sender: TObject); procedure IFrontClick(Sender: TObject); procedure ILeftClick(Sender: TObject);

procedure ITopMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);

procedure IFrontMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);

procedure ILeftMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);

procedure N3Click(Sender: TObject); procedure N33Click(Sender: TObject); procedure ToolButton1Click(Sender: TObject); procedure ToolButton2Click(Sender: TObject); procedure FormPaint(Sender: TObject);

procedure ITopMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure IFrontMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure ILeftMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure N25Click(Sender: TObject); procedure N21Click(Sender: TObject);

procedure N22Click(Sender: TObject); procedure N8Click(Sender: TObject);

procedure N16Click(Sender: TObject); procedure IntWiewClick(Sender: TObject);

procedure N27Click(Sender: TObject); procedure N28Click(Sender: TObject);

procedure N29Click(Sender: TObject); procedure N34Click(Sender: TObject);

procedure N36Click(Sender: TObject); procedure N37Click(Sender: TObject);

procedure N9Click(Sender: TObject); procedure N10Click(Sender: TObject);

procedure IPerspectiveClick(Sender: TObject);

procedure N41Click(Sender: TObject); procedure N14Click(Sender: TObject);

procedure N18Click(Sender: TObject); procedure ToolButton4Click(Sender: TObject);

procedure ToolButton5Click(Sender: TObject); procedure ToolButton6Click(Sender: TObject);

procedure ToolButton7Click(Sender: TObject); procedure ToolButton8Click(Sender: TObject);

procedure ToolButton9Click(Sender: TObject); procedure ToolButton12Click(Sender: TObject);

procedure ToolButton11Click(Sender: TObject); procedure ToolButton19Click(Sender: TObject);

procedure ToolButton13Click(Sender: TObject); procedure N24Click(Sender: TObject);

procedure N19Click(Sender: TObject); Function Normal (A,B,C:Point):Vector;

procedure Mag1Click(Sender: TObject); procedure Mag2Click(Sender: TObject);

procedure Mag3Click(Sender: TObject);

private

{ Private declarations }

Procedure DrawGrane;

public

{ Public declarations }

end;

const Gran=10000;{Максимум ганей}

Pointer=10000;{Максимум вершин}

Lok=0.00001;{Погрешность сечения}

SizeT=5;{Размер точек сечения}

Sumbol='A';{Обозначение точек}

type

TView=array [1..gran]of record Visible:boolean;{Флаг активного окна}

Paint:boolean;

BrushGr:boolean;{Флаг заливки грани}

PenRb:boolean;{Флаг отрисовки ребер}

Intersection:boolean;{Флаг наличия сечения}

ColorGr,ColorRb:TColor{Цвет: грани,ребра} end;

TMainVar=record Cx,Cy:integer; Mash:real;Net:boolean; end;

var

Form1: TForm1;

V:array[1..pointer]of Point;{координаты вершин}

E:array[1..gran,0..pointer]of integer;{грани [номер грани, номер вершины]}

Scene:array[1..4]of record G:TView; M:TMainVar; Active:boolean; end;

M,N:word;{количество граней, количество вершин}

X0,Y0,Num:integer;{координаты щелчка мыши}

ActivColor,ColorEder,ColorUnEder,ColorRebro,ColorIntersection,ColorPointIntersection,ColorNet:TColor;{Цвет: активного окна}

InterPoint:array[1..3]of Point;

Count:byte;

kl:integer;

A,B,C,D,P1,P2,P3:real;

PanelWindow:array[1..4]of TPanel;

WindowProection:array[1..4]of TImage;

NameWindows:array[1..4]of string=('Вид сверху','Вид спереди','Вид слева','Перспектива');{Название окон}

OsiX:array[1..4]of string=('x','x','y','x');

OsiY:array[1..4]of string=('z','y','x','z');

OsiZ:array[1..4]of string=('y','z','z','y');

Magnit:array[1..3]of TMenuItem;

MagPoint:array[1..3,1..2]of Point;

First:array[1..3]of boolean;

MPI:boolean;

implementation

uses Unit2,Unit3;

//Перевод вещественных координат в экранные

Function Ser(win:byte; T:Point; Main:TMainVar):TPoint;

var CopySer:Tpoint;

begin

case win of

1: begin CopySer.X:=round(Main.Cx+(T.x*Main.Mash));

CopySer.Y:=round(Main.Cy-(T.y*Main.Mash)) end;

2: begin CopySer.X:=round(Main.Cx+(T.x*Main.Mash));

CopySer.Y:=round(Main.Cy-(T.z*Main.Mash)) end;

3: begin CopySer.X:=round(Main.Cx+(T.y*Main.Mash));

CopySer.Y:=round(Main.Cy-(T.z*Main.Mash)) end;

4: begin CopySer.X:=round(Main.Cx+(T.x*Main.Mash));

CopySer.Y:=round(Main.Cy-(T.y*Main.Mash)) end;

end;

Ser:=CopySer

end;

Function UnSer(win:byte; X,Y:integer;Tx,Ty,Tz:real; Main:TMainVar):Point;

var CopyUnSer:Point;

begin

case win of

1: begin CopyUnSer.x:=(X-Main.Cx)/Main.Mash;

CopyUnSer.y:=(Main.Cy-Y)/Main.Mash; CopyUnSer.z:=Tz end;

2: begin CopyUnSer.x:=(X-Main.Cx)/Main.Mash;

CopyUnSer.y:=Ty; CopyUnSer.z:=(Main.Cy-Y)/Main.Mash end;

3: begin CopyUnSer.x:=Tx; CopyUnSer.y:=(X-Main.Cx)/Main.Mash;

CopyUnSer.z:=(Main.Cy-Y)/Main.Mash end;

end;

UnSer:=CopyUnSer

end;

Procedure TForm1.DrawGrane;

Procedure GranBrush(Main:TMainVar; win:byte; i:integer; P:TPenStyle; var Can:TImage);

var j:integer;

w:array of TPoint;

begin

SetLength(w,E[i,0]);

for j:=1 to E[i,0] do

w[j-1]:=Ser(win,V[E[i,j]],Main);

if Scene[win].G[i].BrushGr and Scene[win].G[i].Paint then

begin

Can.Canvas.Pen.Style:=psSolid;

Can.Canvas.Pen.Color:=Scene[win].G[i].ColorGr;

Can.Canvas.Brush.Color:=Scene[win].G[i].ColorGr;

Can.Canvas.Polygon(w);

end;

if Scene[win].G[i].PenRb then

begin

Can.Canvas.Pen.Style:=P;

Can.Canvas.Pen.Color:=Scene[win].G[i].ColorRb;

Can.Canvas.Brush.Style:=bsClear;

Can.Canvas.MoveTo(w[0].X,w[0].Y);

for j:=1 to E[i,0]-1 do

Can.Canvas.LineTo(w[j].X,w[j].Y);

Can.Canvas.LineTo(w[0].X,w[0].Y);

end;

end;

//* Оси координат

Procedure LineOs(i:byte;var Can:TImage);

var j,k,a,b:integer;

begin

Can.Canvas.Pen.Color:=ColorNet;

a:=round(Can.Width/Scene[i].M.Mash) div 2;

b:=round(Can.Height/Scene[i].M.Mash) div 2;

for j:=-a to a do

begin

Can.Canvas.MoveTo(Scene[i].M.Cx+round(j*Scene[i].M.Mash),0);

Can.Canvas.LineTo(Scene[i].M.Cx+round(j*Scene[i].M.Mash),Can.Height);

end;

for j:=-b to b do

begin

Can.Canvas.MoveTo(0,Scene[i].M.Cy+round(j*Scene[i].M.Mash));

Can.Canvas.LineTo(Can.Width,Scene[i].M.Cy+round(j*Scene[i].M.Mash));

end;

Can.Canvas.Pen.Color:=clBlack;

Can.Canvas.MoveTo(Scene[i].M.Cx,0);

Can.Canvas.LineTo(Scene[i].M.Cx,Can.Height);

Can.Canvas.MoveTo(0,Scene[i].M.Cy);

Can.Canvas.LineTo(Can.Width,Scene[i].M.Cy);

end;

// Система координат

Procedure InpOboz(i,k:integer);

var j:integer;

A:TPoint;

s:string;

begin

WindowProection[k].Canvas.Pen.Color:=clBlack;

WindowProection[k].Canvas.Brush.Style:=bsClear;

WindowProection[k].Canvas.Font.Height:=8;

for j:=1 to E[i,0] do

begin

s:='';

A:=Ser(k,V[E[i,j]],Scene[k].M);

if Form1.N24.Checked then

s:=s+Sumbol+inttostr(E[i,j]);

if Form1.N19.Checked then

s:=s+'('+floattostrf(V[E[i,j]].x,ffGeneral,3,5)+';'+floattostrf(V[E[i,j]].y,ffGeneral,3,5)+';'+floattostrf(V[E[i,j]].z,ffGeneral,3,5)+')';

WindowProection[k].Canvas.TextOut(A.X,A.Y,s);

end;

end;

Procedure InpOsi(k:byte);

var i:integer;

begin

WindowProection[k].Canvas.Pen.Color:=clBlack;

WindowProection[k].Canvas.Brush.Style:=bsClear;

WindowProection[k].Canvas.MoveTo(10,WindowProection[k].Height-10);

WindowProection[k].Canvas.LineTo(10,WindowProection[k].Height-40);

WindowProection[k].Canvas.MoveTo(10,WindowProection[k].Height-10);

WindowProection[k].Canvas.LineTo(40,WindowProection[k].Height-10);

WindowProection[k].Canvas.Font.Height:=8;

WindowProection[k].Canvas.Font.Color:=clBlue;

WindowProection[k].Canvas.TextOut(12,WindowProection[k].Height-50,OsiX[K]);

WindowProection[k].Canvas.TextOut(12,WindowProection[k].Height-23,OsiY[K]);

WindowProection[k].Canvas.TextOut(40,WindowProection[k].Height-20,OsiZ[K]);

end;

var i,j:integer;

begin

for j:=1 to 4 do

begin

if Scene[j].M.Net then

LineOs(j,WindowProection[j]);

if Form1.IntWiew.Enabled and Form1.N46.Checked then

GranBrush(Scene[j].M,j,M+1,psSolid,WindowProection[j]);

for i:=1 to M do

if (not Scene[j].G[i].Visible) then

GranBrush(Scene[j].M,j,i,psDot,WindowProection[j]);

if Form1.IntWiew.Enabled and Form1.N45.Checked then

GranBrush(Scene[j].M,j,M+1,psSolid,WindowProection[j]);

for i:=1 to M do

if Scene[j].G[i].Visible then

GranBrush(Scene[j].M,j,i,psSolid,WindowProection[j]);

if Form1.N24.Checked or Form1.N19.Checked then

for i:=1 to M do

if Scene[j].G[i].Visible then

InpOboz(i,j);

WindowProection[j].Canvas.Brush.Style:=bsClear;

WindowProection[j].Canvas.Font.Height:=8;

WindowProection[j].Canvas.Font.Color:=clBlack;

WindowProection[j].Canvas.TextOut(1,1,NameWindows[j]);

InpOsi(j);

end;

end;

{$R *.dfm}

//* Активация окна

Procedure ActivWindowProection(i:byte);

var j:byte;

begin

for j:=1 to 3 do

begin

PanelWindow[j].Color:=clBtnFace;

Scene[j].Active:=false

end;

PanelWindow[i].Color:=ActivColor;

Scene[i].Active:=true

end;

//* Полуплоскость

Function SelectGran(i,x,y:integer):integer;

Function Poluploscost(x1,y1,x2,y2,x,y:real):boolean;

begin

Poluploscost:=((x-x1)*(y2-y1)-((y-y1)*(x2-x1)))>0

end;

var j,k,l,rez:integer;

Inter:boolean;

begin

rez:=0; Inter:=true;

for k:=1 to M do

if Scene[i].G[k].Visible then

begin

for j:=1 to E[k,0]-1 do

case i of

1: if Poluploscost(V[E[k,j]].x,V[E[k,j]].y,V[E[k,j+1]].x,V[E[k,j+1]].y,(X-Scene[i].M.Cx)/Scene[i].M.Mash,(Scene[i].M.Cy-Y)/Scene[i].M.Mash) then Inter:=false;

2: if not Poluploscost(V[E[k,j]].x,V[E[k,j]].z,V[E[k,j+1]].x,V[E[k,j+1]].z,(X-Scene[i].M.Cx)/Scene[i].M.Mash,(Scene[i].M.Cy-Y)/Scene[i].M.Mash) then Inter:=false;

3: if Poluploscost(V[E[k,j]].y,V[E[k,j]].z,V[E[k,j+1]].y,V[E[k,j+1]].z,(X-Scene[i].M.Cx)/Scene[i].M.Mash,(Scene[i].M.Cy-Y)/Scene[i].M.Mash) then Inter:=false;

end;

if Inter then

case i of

1: if Poluploscost(V[E[k,E[k,0]]].x,V[E[k,E[k,0]]].y,V[E[k,1]].x,V[E[k,1]].y,(X-Scene[i].M.Cx)/Scene[i].M.Mash,(Scene[i].M.Cy-Y)/Scene[i].M.Mash) then Inter:=false;

2: if not Poluploscost(V[E[k,E[k,0]]].x,V[E[k,E[k,0]]].z,V[E[k,1]].x,V[E[k,1]].z,(X-Scene[i].M.Cx)/Scene[i].M.Mash,(Scene[i].M.Cy-Y)/Scene[i].M.Mash) then Inter:=false;

3: if Poluploscost(V[E[k,E[k,0]]].y,V[E[k,E[k,0]]].z,V[E[k,1]].y,V[E[k,1]].z,(X-Scene[i].M.Cx)/Scene[i].M.Mash,(Scene[i].M.Cy-Y)/Scene[i].M.Mash) then Inter:=false;

end;

if Inter then

begin

rez:=k;

Break;

end

else

begin

rez:=0;

Inter:=true;

end;

end;

SelectGran:=rez;

end;

//* Выбор точек сечения

Procedure MoveP(win,j,X,Y:integer);

Procedure PNormal(P1,P2:Point;var M:Point);

var i:integer;

Li,No:Vector;

O:Point;

Q,P1O,P2O:real;

begin

Li.x:=P1.x-P2.x;

Li.y:=P1.y-P2.y;

Li.z:=P1.z-P2.z;

No.x:=M.x-P1.x;

No.y:=M.y-P1.y;

No.z:=M.z-P1.z;

Q:=sqr(Li.x)+sqr(Li.y)+sqr(Li.z);

O.x:=(Li.x*((Li.y*No.y)+(Li.z*No.z)+(Li.x*M.x))+(P1.x*(sqr(Li.y)+sqr(Li.z))))/Q;

O.y:=(Li.y*((Li.x*No.x)+(Li.z*No.z)+(Li.y*M.x))+(P1.y*(sqr(Li.x)+sqr(Li.z))))/Q;

O.z:=(Li.z*((Li.x*No.x)+(Li.y*No.y)+(Li.z*M.x))+(P1.z*(sqr(Li.x)+sqr(Li.y))))/Q;

P1O:=sqrt(sqr(O.x-P1.x)+sqr(O.y-P1.y)+sqr(O.z-P1.z));

P2O:=sqrt(sqr(O.x-P2.x)+sqr(O.y-P2.y)+sqr(O.z-P2.z));

if (P1O<>0) and (P2O<>0) then

if (sqrt(Q)/P1O<1)or(sqrt(Q)/P2O<1) then

if P1O/P2O<1 then O:=P1 else O:=P2;

M:=O;

end;

begin

InterPoint[j]:=UnSer(win,X,Y,InterPoint[j].x,InterPoint[j].y,InterPoint[j].z,Scene[win].M);

if Magnit[j].Checked and (not first[j]) then

PNormal(MagPoint[j,1],MagPoint[j,2], InterPoint[j]);

Form1.StatusBar2.Panels[0].Text:='X= '+floattostrf(InterPoint[j].x,ffGeneral,3,5);

Form1.StatusBar2.Panels[1].Text:='Y= '+floattostrf(InterPoint[j].y,ffGeneral,3,5);

Form1.StatusBar2.Panels[2].Text:='Z= '+floattostrf(InterPoint[j].z,ffGeneral,3,5);

end;

Procedure SelectPointIntersection(i,x,y:integer;var Num:integer);

Function SelP(X,Y,Xt,Yt,ST:real):boolean;

var Obl:boolean;

begin

Obl:=false;

if (X<(Xt+ST)) and (X>(Xt-ST)) then

if (Y<(Yt+ST)) and (Y>(Yt-ST)) then

Obl:=true;

SelP:=Obl;

end;

var j:integer;

begin

Num:=0;

for j:=1 to 3 do

case i of

1: if SelP((X-Scene[i].M.Cx)/Scene[i].M.Mash,(Scene[i].M.Cy-Y)/Scene[i].M.Mash,InterPoint[j].x,InterPoint[j].y,SizeT/Scene[i].M.Mash) then Num:=j;

2: if SelP((X-Scene[i].M.Cx)/Scene[i].M.Mash,(Scene[i].M.Cy-Y)/Scene[i].M.Mash,InterPoint[j].x,InterPoint[j].z,SizeT/Scene[i].M.Mash) then Num:=j;

3: if SelP((X-Scene[i].M.Cx)/Scene[i].M.Mash,(Scene[i].M.Cy-Y)/Scene[i].M.Mash,InterPoint[j].y,InterPoint[j].z,SizeT/Scene[i].M.Mash) then Num:=j;

end;

end;

Function SelReber(win,x,y:integer;var ds:TPoint):boolean;

var rez:boolean;

Function LinEx(i:integer; x1,y1,x2,y2,x,y:real):boolean;

begin

LinEx:=abs(round(((x-x1)*(y2-y1)-((y-y1)*(x2-x1)))*Scene[i].M.Mash))<5

end;

Procedure FindRb(ind1,ind2:integer);

begin

ds.x:=ind1;

ds.y:=ind2;

rez:=true;

end;

var j,k:integer;

begin

rez:=false;

for j:=1 to M do

if Scene[win].G[j].Visible then

begin

for k:=1 to E[j,0]-1 do

begin

case win of

1: if LinEx(win,V[E[j,k]].x,V[E[j,k]].y,V[E[j,k+1]].x,V[E[j,k+1]].y,(X-Scene[win].M.Cx)/Scene[win].M.Mash,(Scene[win].M.Cy-Y)/Scene[win].M.Mash) then FindRb(E[j,k],E[j,k+1]);

2: if LinEx(win,V[E[j,k]].x,V[E[j,k]].z,V[E[j,k+1]].x,V[E[j,k+1]].z,(X-Scene[win].M.Cx)/Scene[win].M.Mash,(Scene[win].M.Cy-Y)/Scene[win].M.Mash) then FindRb(E[j,k],E[j,k+1]);

3: if LinEx(win,V[E[j,k]].y,V[E[j,k]].z,V[E[j,k+1]].y,V[E[j,k+1]].z,(X-Scene[win].M.Cx)/Scene[win].M.Mash,(Scene[win].M.Cy-Y)/Scene[win].M.Mash) then FindRb(E[j,k],E[j,k+1]);

end;

end;

case win of

1: if LinEx(win,V[E[j,E[j,0]]].x,V[E[j,E[j,0]]].y,V[E[j,1]].x,V[E[j,1]].y,(X-Scene[win].M.Cx)/Scene[win].M.Mash,(Scene[win].M.Cy-Y)/Scene[win].M.Mash) then FindRb(E[j,E[j,0]],E[j,1]);

2: if LinEx(win,V[E[j,E[j,0]]].x,V[E[j,E[j,0]]].z,V[E[j,1]].x,V[E[j,1]].z,(X-Scene[win].M.Cx)/Scene[win].M.Mash,(Scene[win].M.Cy-Y)/Scene[win].M.Mash) then FindRb(E[j,E[j,0]],E[j,1]);

3: if LinEx(win,V[E[j,E[j,0]]].y,V[E[j,E[j,0]]].z,V[E[j,1]].y,V[E[j,1]].z,(X-Scene[win].M.Cx)/Scene[win].M.Mash,(Scene[win].M.Cy-Y)/Scene[win].M.Mash) then FindRb(E[j,E[j,0]],E[j,1]);

end;

end;

SelReber:=rez;

end;

Procedure PenRebPr(d,ind1,ind2:integer);

var t:integer;

begin

WindowProection[d].Canvas.Pen.Color:=clRed;

WindowProection[d].Canvas.MoveTo(Ser(d,V[ind1],Scene[d].M).X,Ser(d,V[ind1],Scene[d].M).Y);

WindowProection[d].Canvas.LineTo(Ser(d,V[ind2],Scene[d].M).X,Ser(d,V[ind2],Scene[d].M).Y);

end;

//* Нормальный вектор к грани

Function TForm1.Normal (A,B,C:Point):Vector;

begin

Normal.x:=((B.y-A.y)*(C.z-B.z))-((B.z-A.z)*(C.y-B.y));

Normal.y:=((B.z-A.z)*(C.x-B.x))-((B.x-A.x)*(C.z-B.z));

Normal.z:=((B.x-A.x)*(C.y-B.y))-((B.y-A.Y)*(C.x-B.x));

end;

//* Реализация поворота

Procedure Rotate(Ax,Ay,Az:real;Ox,Oy,Oz:real);{поворот вокруг оси все точки многогранника}

procedure Transfer(var T:Point;Ox,Oy,Oz:real);

var W:Point;

begin

T.x:=T.x-Ox;

T.y:=T.y-Oy;

T.z:=T.z-Oz;

end;

Procedure UnTransfer(var T:Point;Ox,Oy,Oz:real);

var W:Point;

begin

T.x:=T.x+Ox;

T.y:=T.y+Oy;

T.z:=T.z+Oz;

end;

Procedure RX(a:real; var P:Point);{поворот вокруг оси OX одной точки}

var Q:Point;

begin Q.x:=P.x; Q.y:=P.y*Cos(a)+P.z*Sin(a); Q.z:=-P.y*sin(a)+P.z*Cos(a); P:=Q end;

Procedure RY(a:real; var P:Point);{поворот вокруг оси OY одной точки}

var Q:Point;

begin Q.x:=P.x*Cos(a)-P.z*Sin(a);Q.y:=P.y;Q.z:=P.x*sin(a)+P.z*Cos(a); P:=Q end;

Procedure RZ(a:real; var P:Point);{поворот вокруг оси OZ одной точки}

var Q:Point;

begin Q.x:=P.x*Cos(a)-P.y*Sin(a);Q.y:=P.x*Sin(a)+P.y*Cos(a);Q.z:=P.z; P:=Q end;

var i:integer;

begin

if Form1.N17.Checked then

for i:=1 to Count do begin Transfer(InterPoint[i],Ox,Oy,Oz);RX(Ax,InterPoint[i]);RY(Ay,InterPoint[i]);RZ(Az,InterPoint[i]);UnTransfer(InterPoint[i],Ox,Oy,Oz) end;

for i:=1 to N do begin Transfer(V[i],Ox,Oy,Oz);RX(Ax,V[i]);RY(Ay,V[i]);RZ(Az,V[i]);UnTransfer(V[i],Ox,Oy,Oz); end;

end;

//* Реализация перемещение

Procedure Move(Lx,Ly,Lz:real);

var i:integer;

begin

if Form1.N17.Checked then

for i:=1 to Count do begin InterPoint[i].x:=InterPoint[i].x+Lx;InterPoint[i].y:=InterPoint[i].y+Ly;InterPoint[i].z:=InterPoint[i].z+Lz; end;

for i:=1 to N do begin V[i].x:=V[i].x+Lx;V[i].y:=V[i].y+Ly;V[i].z:=V[i].z+Lz end;

end;

//* Размещение осей перемещения

Procedure MoveOs;

begin

if Form1.Centr.Left+Form1.Centr.Width>Form1.ClientWidth then

Form1.Centr.Left:=Form1.ClientWidth-Form1.Centr.Width;

if Form1.Centr.Top+Form1.Centr.Height>Form1.GroupBox1.Top then

Form1.Centr.Top:=Form1.GroupBox1.Top-Form1.Centr.Height;

if Form1.Centr.Top<Form1.ToolBar1.Top+Form1.ToolBar1.Height then

Form1.Centr.Top:=Form1.ToolBar1.Top+Form1.ToolBar1.Height;

Form1.Vertikal.Top:=Form1.ToolBar1.Height;

Form1.Vertikal.Left:=Form1.Centr.Left;

Form1.Vertikal.Height:=Form1.GroupBox1.Top-Form1.ToolBar1.Height;

Form1.Vertikal.Width:=Form1.Centr.Width;

Form1.Horizontal.Top:=Form1.Centr.Top;

Form1.Horizontal.Left:=0;

Form1.Horizontal.Height:=Form1.Centr.Height;

Form1.Horizontal.Width:=Form1.ClientWidth

end;

//* Размещение окон проекций.

Procedure MoveWindow;

var i:byte;

begin

{Вид сверху}

Form1.PTop.Top:=Form1.ToolBar1.Height;

Form1.PTop.Left:=0;

Form1.PTop.Height:=Form1.Centr.Top-Form1.PTop.Top;

Form1.PTop.Width:=Form1.Centr.Left;

{Вид спереди}

Form1.PFront.Top:=Form1.ToolBar1.Height;

Form1.PFront.Left:=Form1.Centr.Left+Form1.Centr.Width;

Form1.PFront.Height:=Form1.Centr.Top-Form1.PFront.Top;

Form1.PFront.Width:=Form1.ClientWidth-Form1.Centr.Left-Form1.Centr.Width;

{Вид слева}

Form1.PLeft.Top:=Form1.Centr.Top+Form1.Centr.Height;

Form1.PLeft.Left:=0;

Form1.PLeft.Height:=Form1.GroupBox1.Top-Form1.PLeft.Top;

Form1.PLeft.Width:=Form1.Centr.Left;

{Окно перспективы}

Form1.PPerspective.Top:=Form1.Centr.Top+Form1.Centr.Height;

Form1.PPerspective.Left:=Form1.Centr.Left+Form1.Centr.Width;

Form1.PPerspective.Height:=Form1.GroupBox1.Top-Form1.PPerspective.Top;

Form1.PPerspective.Width:=Form1.ClientWidth-Form1.Centr.Left-Form1.Centr.Width;

{Задаем координаты мирового центра}

for i:=1 to 4 do

begin

Scene[i].M.Cx:=WindowProection[i].Width div 2;

Scene[i].M.Cy:=WindowProection[i].Height div 2;

end;

end;

//* Вывод точек сечения

Procedure Puk;

var i,j:byte;

begin

for j:=1 to Count do

for i:=1 to 3 do

begin

WindowProection[i].Canvas.Pen.Color:=ColorPointIntersection;

WindowProection[i].Canvas.Ellipse(Ser(i,InterPoint[j],Scene[i].M).X-SizeT,Ser(i,InterPoint[j],Scene[i].M).Y-SizeT,Ser(i,InterPoint[j],Scene[i].M).X+SizeT,Ser(i,InterPoint[j],Scene[i].M).Y+SizeT);

end;

end;

//* Построение сечения

Procedure BildInter;

var i,j:integer;

Dipol:array[1..gran,1..2]of Point;

Para,Count:integer;

Gp:array[0..gran]of Point;

Procedure UravPl(A1,A2,A3:Point; var A,B,C,D:real);{Уравнение плоскости сечения}

var P:Vector;

begin

p:=Form1.Normal(A1,A2,A3);

A:=p.x;

B:=p.y;

C:=P.z;

D:=-((A*A1.x)+(B*A1.y)+(C*A1.z))

end;

Function Sec(n,p:Point; A,B,C,D:real; var IP:Point):boolean;{Точки сечения}

var Kx,Ky,Kz,P1,P2,P3:real;

Yes:boolean;

begin

Yes:=false;

P1:=(A*n.x)+(B*n.y)+(C*n.z)+D;

P2:=(A*p.x)+(B*p.y)+(C*p.z)+D;

if P1=0 then begin IP:=n; Yes:=true end

else if P2=0 then begin IP:=p; Yes:=true end else

if P1*P2<0 then

begin

Yes:=true;

P1:=n.x-p.x; P2:=n.y-p.y; P3:=n.z-p.z;

if P1=0 then IP.x:=n.x

else

begin

Kx:=((B*P2)+(C*P3))/P1;

IP.x:=((Kx*n.x)-(B*n.y)-(C*n.z)-D)/(A+Kx);

end;

if P2=0 then IP.y:=n.y

else

begin

Ky:=((A*P1)+(C*P3))/P2;

IP.y:=((Ky*n.y)-(A*n.x)-(C*n.z)-D)/(B+Ky);

end;

if P3=0 then IP.z:=n.z

else

begin

Kz:=((A*P1)+(B*P2))/P3;

IP.z:=((Kz*n.z)-(A*n.x)-(B*n.y)-D)/(C+Kz);

end;

end;

Sec:=Yes;

end;

Procedure Cep;{Построение многоугольника сечения}

Function RavPoi(a,b:point; Er:real):boolean;

var rez:boolean;

begin

rez:=false;

if abs(a.x-b.x)<Er then

if abs(a.y-b.y)<Er then

if abs(a.z-b.z)<Er then rez:=true;

RavPoi:=rez;

end;

var i,j:integer;

h,f:Point;

begin

for i:=1 to Count-1 do

begin

for j:=i+1 to Count do

begin

if RavPoi(Dipol[j,1],Dipol[i,2],Lok) then

begin

h:=Dipol[i+1,1];

f:=Dipol[i+1,2];

Dipol[i+1,1]:=Dipol[j,1];

Dipol[i+1,2]:=Dipol[j,2];

Dipol[j,1]:=h;

Dipol[j,2]:=f;

Break;

end;

if RavPoi(Dipol[j,2],Dipol[i,2],Lok) then

begin

h:=Dipol[i+1,1];

f:=Dipol[i+1,2];

Dipol[i+1,1]:=Dipol[j,2];

Dipol[i+1,2]:=Dipol[j,1];

Dipol[j,2]:=h;

Dipol[j,1]:=f;

Break;

end;

end;

end;

Form1.Label1.Caption:='Сечение- '+inttostr(Count)+' угольник.';

E[M+1,0]:=Count;

for i:=1 to Count do

begin

V[N+i]:=Dipol[i,1];

E[M+1,i]:=N+i;

end;

for i:=1 to 3 do

begin

Scene[i].G[M+1].Visible:=true;

Scene[i].G[M+1].Paint:=true;

Scene[i].G[M+1].BrushGr:=true;

end;

end;

begin

UravPl(InterPoint[1],InterPoint[2],InterPoint[3],A,B,C,D);

Count:=0;

for i:=1 to M do

begin

Para:=0;

for j:=1 to E[i,0]-1 do

begin

if Sec(V[E[i,j]],V[E[i,j+1]],A,B,C,D,Gp[Para]) then inc(para);

if Para>2 then Break;

end;

if Sec(V[E[i,E[i,0]]],V[E[i,1]],A,B,C,D,Gp[Para])then inc(para);

if Para=2 then

begin

inc(Count);

Dipol[Count,1]:=Gp[0];

Dipol[Count,2]:=Gp[1];

end;

end;

if Count>2 then

begin

Form1.IntWiew.Enabled:=true;

Cep;

end;

end;

Procedure WindowsMove(X,Y,i:integer;shift:TShiftState);

var a,b,c:string;

h,k:integer;

Par:TPoint;

t,firsttrue:boolean;

begin

firsttrue:=false;

if MPI then begin MoveP(i,kl,X,Y); MPI:=false end;

Form1.StatusBar2.Panels[0].Text:='X= '+floattostrf(UnSer(i,X,Y,0,0,0,Scene[i].M).x,ffGeneral,3,5);

Form1.StatusBar2.Panels[1].Text:='Y= '+floattostrf(UnSer(i,X,Y,0,0,0,Scene[i].M).y,ffGeneral,3,5);

Form1.StatusBar2.Panels[2].Text:='Z= '+floattostrf(UnSer(i,X,Y,0,0,0,Scene[i].M).z,ffGeneral,3,5);

if (ssleft in shift) and Form1.N34.Checked then

if Scene[i].M.Mash-(Y-Y0)>0 then Scene[i].M.Mash:=Scene[i].M.Mash-(Y-Y0) else ShowMessage('Масштаб: меньше нельзя!');

if Form1.N8.Checked and ((i=1) or (i=2))then X0:=X;

if Form1.N9.Checked and (i=1) then Y0:=Y;

if Form1.N10.Checked and ((i=2)or(i=3)) then Y0:=Y;

if Form1.N9.Checked and (i=3) then X0:=X;

if Form1.N36.Checked then

begin

k:=SelectGran(i,X,Y);

if k<>0 then

begin

t:=Scene[i].G[k].Paint;

Scene[i].G[k].Paint:=false;

Form1.Repaint;

Scene[i].G[k].Paint:=t;

end

else Form1.Repaint;

end;

if Form1.N37.Checked then

begin

k:=SelectGran(i,X,Y);

if k<>0 then

begin

t:=Scene[i].G[k].Paint;

Scene[i].G[k].Paint:=true;

Form1.Repaint;

Scene[i].G[k].Paint:=t;

end

else Form1.Repaint;

end;

if Form1.N27.Checked and Form1.IntWiew.Enabled then

for h:=1 to 3 do if First[h] then

begin

Firsttrue:=true;

Form1.Repaint;

if SelReber(i,x,y,Par) then

PenRebPr(i,Par.x,Par.y);

end;

if ssleft in shift then

begin

if Form1.N27.Checked and Form1.IntWiew.Enabled and (not FirstTrue)then

begin

SelectPointIntersection(i,X,Y,kl);

if kl<>0 then

begin

MoveP(i,kl,X,Y);

MPI:=true

end

else MPI:=false

end;

if Form1.N29.Checked then

if Form1.N12.Checked then

Rotate((UnSer(i,Y,X,0,0,0,Scene[i].M).x-UnSer(i,Y0,X0,0,0,0,Scene[i].M).x)*Pi/180*Scene[i].M.Mash,(UnSer(i,Y,X,0,0,0,Scene[i].M).y-UnSer(i,Y0,X0,0,0,0,Scene[i].M).y)*Pi/180*Scene[i].M.Mash,(UnSer(i,Y,X,0,0,0,Scene[i].M).z-UnSer(i,Y0,X0,0,0,0,Scene[i].M).z)*Pi/180*Scene[i].M.Mash,V[1].x,V[1].y,V[1].z)

else if Form1.N13.Checked then

Rotate((UnSer(i,Y,X,0,0,0,Scene[i].M).x-UnSer(i,Y0,X0,0,0,0,Scene[i].M).x)*Pi/180*Scene[i].M.Mash,(UnSer(i,Y,X,0,0,0,Scene[i].M).y-UnSer(i,Y0,X0,0,0,0,Scene[i].M).y)*Pi/180*Scene[i].M.Mash,(UnSer(i,Y,X,0,0,0,Scene[i].M).z-UnSer(i,Y0,X0,0,0,0,Scene[i].M).z)*Pi/180*Scene[i].M.Mash,0,0,0);

if Form1.N28.Checked then

Move(UnSer(i,X,Y,0,0,0,Scene[i].M).x-UnSer(i,X0,Y0,0,0,0,Scene[i].M).x,UnSer(i,X,Y,0,0,0,Scene[i].M).y-UnSer(i,X0,Y0,0,0,0,Scene[i].M).y,UnSer(i,X,Y,0,0,0,Scene[i].M).z-UnSer(i,X0,Y0,0,0,0,Scene[i].M).z);

X0:=X; Y0:=Y; Form1.Repaint;

end;

end;

procedure TForm1.N5Click(Sender: TObject);

begin

Form1.Close;

end;

//* Изминение размер окон проекций

procedure TForm1.CentrMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

begin

if ssLeft in Shift then

begin

if (Form1.Centr.Left+X>=0)and(Form1.Centr.Left+X<Form1.ClientWidth-Form1.Centr.Width) then

Form1.Centr.Left:=Form1.Centr.Left+X;

if (Form1.Centr.Top+Y>=Form1.ToolBar1.Height)and((Form1.Centr.Top+Y)<=(Form1.ToolBar1.Height+Form1.Vertikal.Height-Form1.Centr.Height)) then

Form1.Centr.Top:=Form1.Centr.Top+Y;

MoveOs;

end

end;

procedure TForm1.CentrMouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

MoveWindow;

end;

procedure TForm1.FormCreate(Sender: TObject);

var i:byte;

begin

//* Присваиваем ярлыки

WindowProection[1]:=Form1.ITop;

WindowProection[2]:=Form1.IFront;

WindowProection[3]:=Form1.ILeft;

WindowProection[4]:=Form1.IPerspective;

PanelWindow[1]:=Form1.PTop;

PanelWindow[2]:=Form1.PFront;

PanelWindow[3]:=Form1.PLeft;

PanelWindow[4]:=Form1.PPerspective;

Magnit[1]:=Mag1;

Magnit[2]:=Mag2;

Magnit[3]:=Mag3;

//* Первоначальная установка цвета

ActivColor:=clYellow;

ColorEder:=clAqua;

ColorUnEder:=clSilver;

ColorRebro:=clBlack;

ColorIntersection:=clRed;

ColorPointIntersection:=clBlue;

ColorNet:=clBtnFace;

//* Рапологаем окна проекций и оси

MoveWindow;

MoveOs;

//* Задаем масштаб окон проекций

for i:=1 to 3 do

Scene[i].M.Mash:=100;

Scene[4].M.Mash:=50;

for i:=1 to 3 do

First[i]:=false;

//Установка режима

Form1.IntWiew.Enabled:=false;

Count:=0;

MPI:=false;

//Активация вида сверху

ActivWindowProection(1);

end;

procedure TForm1.FormResize(Sender: TObject);

begin

MoveOs;

MoveWindow;

end;

//Загрузка многогранника из файла

procedure TForm1.N2Click(Sender: TObject);

var

f:textfile;

i,j,k,l:integer;

Max,Q:real;

begin

if Form1.OD1.Execute then

begin

assignfile(f,Form1.OD1.FileName);

reset(f);

readln(f,N);

for i:=1 to N do{загрузка координат вершин}

readln(f,V[i].x,V[i].y,V[i].z);

readln(f,M);

for i:=1 to M do

begin

j:=0;

while not eoln(f) do{загрузка граней}

begin

inc(j);

read(f,E[i,j]);

end;

readln(f);

E[i,0]:=j;

end;

Form1.StatusBar2.Panels[3].Text:='Файл: '+Form1.OD1.FileName;

Form1.N3.Enabled:=true;

Form1.ToolButton2.Enabled:=true;

closefile(f);

for i:=1 to 4 do

begin

for j:=1 to M do{Установка вида изображения}

begin

Scene[i].G[j].Paint:=true;

Scene[i].G[j].BrushGr:=true;

Scene[i].G[j].PenRb:=false;

Scene[i].G[j].ColorRb:=ColorRebro;

Form1.N21.Checked:=false;

Form1.N22.Checked:=true;

Form1.N41.Click;

Num:=1;

end;

Max:=sqrt(sqr(V[1].x-V[N].x)+sqr(V[1].y-V[N].y)+sqr(V[1].z-V[N].z));

for l:=1 to N-1 do

for k:=1 to N-1 do

begin

Q:=sqrt(sqr(V[i].x-V[l].x)+sqr(V[i].y-V[l].y)+sqr(V[i].z-V[l].z));

if Q>Max then Max:=Q

end;

for k:=1 to 4 do

Scene[k].M.Mash:=WindowProection[k].Height/Max;

end;

Form1.Repaint;

end;

end;

procedure TForm1.ITopClick(Sender: TObject);

begin

if not Scene[1].Active then{Активация окна проекции вид сверху}

ActivWindowProection(1);

end;

procedure TForm1.IFrontClick(Sender: TObject);

begin

if not Scene[2].Active then{Активация окна проекции вид спереди}

ActivWindowProection(2);

end;

procedure TForm1.ILeftClick(Sender: TObject);

begin

if not Scene[3].Active then{Активация окна проекции вид слева}

ActivWindowProection(3);

end;

procedure TForm1.ITopMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

begin

if Scene[1].Active then

begin

WindowsMove(X,Y,1,shift);

end;

end;

procedure TForm1.IFrontMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

begin

if Scene[2].Active then

WindowsMove(X,Y,2,shift);

end;

procedure TForm1.ILeftMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

begin

if Scene[3].Active then

WindowsMove(X,Y,3,shift);

end;

//* Сохранение многогранника

procedure TForm1.N3Click(Sender: TObject);

var

f:textfile;

i,j:integer;

begin

if Form1.SD1.Execute then

begin

assignfile(f,Form1.SD1.FileName+'.txt');

rewrite(f);

writeln(f,N);

for i:=1 to N do{запись координат вершин}

begin

writeln(f,V[i].x:5:3,' ',V[i].y:5:3,' ',V[i].z:5:3);

end;

writeln(f,M);

for i:=1 to M do

begin

for j:=1 to E[i,0] do{запись обхода гнаней}

write(f,' ',E[i,j]);

writeln(f);

end;

Form1.StatusBar2.Panels[3].Text:='Файл: '+Form1.SD1.FileName;

closefile(f);

Repaint;

end;

end;

procedure TForm1.N33Click(Sender: TObject);

begin

ShowMessage('Курсовая работа. Мосин Е.В. ФМ-43');

end;

procedure TForm1.ToolButton1Click(Sender: TObject);

begin

Form1.N2.Click;

end;

procedure TForm1.ToolButton2Click(Sender: TObject);

begin

Form1.N3.Click;

end;

//* Перерисовка формы

procedure TForm1.FormPaint(Sender: TObject);

Procedure ColorLight(i:integer;ColorEder,ColorUnEder:TColor);

var

j:integer;

n:vector;

c:real;

NorVec:array[1..4]of real;

begin

{Нормальный вектор}

n:=Normal(V[E[i,1]],V[E[i,2]],V[E[i,3]]);

NorVec[1]:=n.z;NorVec[2]:=n.y;NorVec[3]:=n.x;NorVec[4]:=n.z;

for j:=1 to 4 do

Scene[j].G[i].Visible:=NorVec[j]>0;

{Освещенность}

c:=sqrt(sqr(n.x)+sqr(n.y)+sqr(n.z));

for j:=1 to 4 do

if Scene[j].G[i].Visible then

Scene[j].G[i].colorgr:=(round(NorVec[j]/c*(ColorEder mod 256))*$1)+(round(NorVec[j]/c*((ColorEder div $100) mod 256))*$100)+(round(NorVec[j]/c*((ColorEder div $10000) mod 256))*$10000)

else if c<>0 then

Scene[j].G[i].colorgr:=abs((round(NorVec[j]/c*(ColorUnEder mod 256))*$1)+(round(NorVec[j]/c*((ColorUnEder div $100) mod 256))*$100)+(round(NorVec[j]/c*((ColorUnEder div $10000) mod 256))*$10000));

end;

var

i,j:integer;

k:TColor;

begin

{Стираем старое изображение}

for j:=1 to 4 do

WindowProection[j].Picture:=nil;

for i:=1 to M do

ColorLight(i,ColorEder,ColorUnEder);

if Form1.IntWiew.Enabled then

begin

BildInter;

ColorLight(M+1,ColorIntersection,ColorIntersection);

for j:=1 to 3 do

Scene[j].G[M+1].Visible:=true;

end;

DrawGrane;

Puk;

end;

//* Задание точек сечения

Procedure EnterPointIntersection(i:byte;X,Y:integer);

var k:integer;

Par:TPoint;

begin

if Scene[i].Active then

begin

X0:=X;

Y0:=Y;

if Form1.N36.Checked then

begin

k:=SelectGran(i,X,Y);

if k<>0 then

Scene[i].G[k].Paint:=false;

end;

if Form1.N37.Checked then

begin

k:=SelectGran(i,X,Y);

if k<>0 then

Scene[i].G[k].Paint:=true;

end;

if Form1.N40.Checked then

begin

inc(Count);

InterPoint[Count]:=UnSer(i,X,Y,0,0,0,Scene[i].M);

Puk;

if Count=3 then

begin

Form1.N40.Checked:=false;

Form1.N40.Enabled:=false;

Form1.N41.Enabled:=true;

Form1.ToolButton13.Enabled:=false;

BildInter;

end;

end;

if Form1.N27.Checked and Form1.IntWiew.Enabled then

for k:=1 to 3 do

if First[k] and SelReber(i,x,y,Par) then

begin

MagPoint[k,1]:=V[Par.x];

MagPoint[k,2]:=V[Par.y];

First[k]:=false;

end;

Form1.Repaint;

end;

end;

procedure TForm1.ITopMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

EnterPointIntersection(1,X,Y);

end;

procedure TForm1.IFrontMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

EnterPointIntersection(2,X,Y);

end;

procedure TForm1.ILeftMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

EnterPointIntersection(3,X,Y);

end;

//* Включение сетки

procedure TForm1.N25Click(Sender: TObject);

var i:byte;

begin

for i:=1 to 3 do

if Scene[i].Active then

Scene[i].M.Net:=not Scene[i].M.Net;

Form1.Repaint;

end;

//* Включение ребер

procedure TForm1.N21Click(Sender: TObject);

var i,j:integer;

begin

Form1.N21.Checked:=not Form1.N21.Checked;

for i:=1 to 4 do

for j:=1 to M do

Scene[i].G[j].PenRb:=Form1.N21.Checked;

Form1.Repaint;

end;

//* Включение заливки

procedure TForm1.N22Click(Sender: TObject);

var i,j:integer;

begin

Form1.N22.Checked:=not Form1.N22.Checked;

for i:=1 to 3 do

for j:=1 to M do

Scene[i].G[j].BrushGr:=Form1.N22.Checked;

Form1.Repaint;

end;

//* Вызов диалога изменения цвета

procedure TForm1.N16Click(Sender: TObject);

begin

Application.CreateForm(TForm2,Form2);

end;

//* Вызов окна просмотра сечения

procedure TForm1.IntWiewClick(Sender: TObject);

begin

Application.CreateForm(TForm3,Form3);

end;

//Панель инструментов--------------------------------------

procedure TForm1.N8Click(Sender: TObject);

var i:integer;

begin

Form1.ToolButton12.Down:=Form1.N8.Checked;

end;

procedure TForm1.N27Click(Sender: TObject);

begin

Form1.ToolButton4.Down:=true;

end;

procedure TForm1.N28Click(Sender: TObject);

begin

Form1.ToolButton5.Down:=true;

end;

procedure TForm1.N29Click(Sender: TObject);

begin

Form1.ToolButton6.Down:=true;

end;

procedure TForm1.N34Click(Sender: TObject);

begin

Form1.ToolButton7.Down:=true;

end;

procedure TForm1.N36Click(Sender: TObject);

begin

Form1.ToolButton8.Down:=true;

end;

procedure TForm1.N37Click(Sender: TObject);

begin

Form1.ToolButton9.Down:=true;

end;

procedure TForm1.N9Click(Sender: TObject);

begin

Form1.ToolButton11.Down:=Form1.N9.Checked;

end;

procedure TForm1.N10Click(Sender: TObject);

begin

Form1.ToolButton19.Down:=Form1.N10.Checked;

end;

//---------------------------------------------------------

procedure TForm1.IPerspectiveClick(Sender: TObject);

begin

if not Scene[4].Active then{Активация окна перспективы}

ActivWindowProection(4);

end;

//* Удаление сечения

procedure TForm1.N41Click(Sender: TObject);

var i:integer;

begin

Count:=0;

for i:=1 to 3 do

First[i]:=false;

Form1.N40.Enabled:=true;

Form1.N40.Checked:=false;

Form1.N41.Enabled:=false;

Form1.ToolButton13.Enabled:=true;

Form1.ToolButton13.Down:=false;

Form1.IntWiew.Enabled:=false;

Form1.Label1.Caption:='Сечение не задано.';

for i:=1 to 3 do

Scene[i].G[M+1].Visible:=false;

Form1.Repaint;

end;

//* Сброс

procedure TForm1.N14Click(Sender: TObject);

var i:integer;

begin

ActivColor:=clYellow;

ColorEder:=clAqua;

ColorUnEder:=clSilver;

ColorRebro:=clBlack;

ColorIntersection:=clRed;

ColorPointIntersection:=clBlue;

ColorNet:=clBtnFace;

for i:=1 to 3 do

Scene[i].M.Mash:=100;

Form1.N41.Click;

M:=0;

N:=0;

Form1.StatusBar2.Panels[3].Text:='Файл не загружен';

Form1.Repaint;

end;

//---------------------------------------------------------

procedure TForm1.N18Click(Sender: TObject);

begin

Form1.Repaint;

end;

procedure TForm1.ToolButton4Click(Sender: TObject);

begin

Form1.N27.Click;

end;

procedure TForm1.ToolButton5Click(Sender: TObject);

begin

Form1.N28.Click;

end;

procedure TForm1.ToolButton6Click(Sender: TObject);

begin

Form1.N29.Click;

end;

procedure TForm1.ToolButton7Click(Sender: TObject);

begin

Form1.N34.Click;

end;

procedure TForm1.ToolButton8Click(Sender: TObject);

begin

Form1.N36.Click;

end;

procedure TForm1.ToolButton9Click(Sender: TObject);

begin

Form1.N37.Click;

end;

procedure TForm1.ToolButton12Click(Sender: TObject);

begin

Form1.N8.Click;

end;

procedure TForm1.ToolButton11Click(Sender: TObject);

begin

Form1.N9.Click;

end;

procedure TForm1.ToolButton19Click(Sender: TObject);

begin

Form1.N10.Click;

end;

procedure TForm1.ToolButton13Click(Sender: TObject);

begin

Form1.N40.Click;

end;

procedure TForm1.N24Click(Sender: TObject);

begin

Form1.Repaint;

end;

procedure TForm1.N19Click(Sender: TObject);

begin

Form1.Repaint;

end;

//---------------------------------------------------------

procedure TForm1.Mag1Click(Sender: TObject);

begin

if Mag1.Checked then

First[1]:=true;

end;

procedure TForm1.Mag2Click(Sender: TObject);

begin

if Mag2.Checked then

First[2]:=true;

end;

procedure TForm1.Mag3Click(Sender: TObject);

begin

if Mag3.Checked then

First[3]:=true;

end;

end.

unit Unit2;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, Buttons, ComCtrls, ExtCtrls;

type

TForm2 = class(TForm)

BitBtn1: TBitBtn;

Label1: TLabel;

Label2: TLabel;

Label3: TLabel;

Label4: TLabel;

Label5: TLabel;

Shape1: TShape;

Shape2: TShape;

Shape3: TShape;

Shape4: TShape;

Shape5: TShape;

Label6: TLabel;

Shape6: TShape;

CD1: TColorDialog;

Label7: TLabel;

Shape7: TShape;

procedure FormCreate(Sender: TObject);

procedure Shape1MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure Shape2MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure Shape3MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure Shape4MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure Shape5MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure Shape6MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure BitBtn1Click(Sender: TObject);

procedure CD1Close(Sender: TObject);

procedure Shape7MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form2: TForm2;

implementation

uses Unit1,Unit3;

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);

begin

Shape1.Brush.Color:=ColorIntersection;

Shape2.Brush.Color:=ColorEder;

Shape3.Brush.Color:=ColorRebro;

Shape4.Brush.Color:=ColorNet;

Shape5.Brush.Color:=ActivColor;

Shape6.Brush.Color:=ColorPointIntersection;

Shape7.Brush.Color:=ColorUnEder;

end;

procedure TForm2.Shape1MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

if Form2.CD1.Execute then

begin

ColorIntersection:=Form2.CD1.Color;

Form2.Shape1.Brush.Color:=Form2.CD1.Color

end

end;

procedure TForm2.Shape2MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

if Form2.CD1.Execute then

begin

ColorEder:=Form2.CD1.Color;

Form2.Shape2.Brush.Color:=Form2.CD1.Color

end

end;

procedure TForm2.Shape3MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

var i,j:word;

begin

if Form2.CD1.Execute then

begin

ColorRebro:=Form2.CD1.Color;

Form2.Shape3.Brush.Color:=Form2.CD1.Color;

for i:=1 to 3 do

for j:=1 to M do

Scene[i].G[j].ColorRb:=ColorRebro;

end

end;

procedure TForm2.Shape4MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

if Form2.CD1.Execute then

begin

ColorNet:=Form2.CD1.Color;

Form2.Shape4.Brush.Color:=Form2.CD1.Color

end

end;

procedure TForm2.Shape5MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

if Form2.CD1.Execute then

begin

ActivColor:=Form2.CD1.Color;

Form2.Shape5.Brush.Color:=Form2.CD1.Color

end

end;

procedure TForm2.Shape6MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

if Form2.CD1.Execute then

begin

ColorPointIntersection:=Form2.CD1.Color;

Form2.Shape6.Brush.Color:=Form2.CD1.Color

end

end;

procedure TForm2.BitBtn1Click(Sender: TObject);

begin

Form2.Close

end;

procedure TForm2.CD1Close(Sender: TObject);

begin

Form1.Repaint;

end;

procedure TForm2.Shape7MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

if Form2.CD1.Execute then

begin

ColorUnEder:=Form2.CD1.Color;

Form2.Shape7.Brush.Color:=Form2.CD1.Color

end

end;

end.

unit Unit3;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, Buttons, ExtCtrls,Math;

type

TForm3 = class(TForm)

GroupBox1: TGroupBox;

ListBox1: TListBox;

Label1: TLabel;

Edit1: TEdit;

Label2: TLabel;

Edit2: TEdit;

Label3: TLabel;

Splitter1: TSplitter;

BitBtn1: TBitBtn;

procedure FormCreate(Sender: TObject);

procedure Edit2KeyPress(Sender: TObject; var Key: Char);

procedure Edit1KeyPress(Sender: TObject; var Key: Char);

procedure FormPaint(Sender: TObject);

procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

procedure BitBtn1Click(Sender: TObject);

private

{ Private declarations }

procedure PaintIntersection;

public

{ Public declarations }

end;

var

Form3: TForm3;

CxW,CyW,X0W,Y0W:integer;

MashW:real;

PInter:array of TPoint;

implementation

uses Unit1,Unit2;

procedure TForm3.PaintIntersection;

var i:integer;

Nor:Vector;

C1,S1,x:real;

FG:array[1..1000] of Point;

begin

CxW:=(Form3.Width+Form3.GroupBox1.Width) div 2;

CyW:=(Form3.Height) div 2;

for i:=1 to E[M+1,0] do

FG[i]:=V[N+i];

Nor:=Form1.Normal(FG[1],FG[2],FG[3]);

if (Nor.y<>0) and (Nor.z<>0) then

begin

C1:=Nor.z/sqrt(sqr(Nor.y)+sqr(Nor.z));

S1:=Nor.y/sqrt(sqr(Nor.y)+sqr(Nor.z));

end

else begin C1:=1; S1:=0 end;

for i:=1 to E[M+1,0] do

begin

x:=(FG[i].y*C1)-(FG[i].z*S1);

FG[i].z:=(FG[i].y*S1)+(FG[i].z*C1);

FG[i].y:=x;

end;

Nor:=Form1.Normal(FG[1],FG[2],FG[3]);

if (Nor.x<>0) and (Nor.z<>0) then

begin

C1:=Nor.z/sqrt(sqr(Nor.x)+sqr(Nor.z));

S1:=Nor.x/sqrt(sqr(Nor.x)+sqr(Nor.z));

end

else begin C1:=1; S1:=0 end;

for i:=1 to E[M+1,0] do

begin

FG[i].x:=(FG[i].x*C1)-(FG[i].z*S1);

end;

SetLength(PInter,E[M+1,0]);

for i:=1 to E[M+1,0] do

begin

PInter[i-1].X:=round(CxW+(FG[i].x*MashW));

PInter[i-1].Y:=round(CyW-(FG[i].y*MashW));

end;

Form3.Canvas.Brush.Color:=ColorIntersection;

Form3.Canvas.Pen.Color:=ColorRebro;

Form3.Canvas.Polygon(PInter);

Form3.Canvas.Font.Height:=8;

Form3.Canvas.Brush.Style:=bsClear;

Form3.Canvas.Pen.Color:=clBlack;

for i:=1 to E[M+1,0] do

Form3.Canvas.TextOut(PInter[i-1].X,PInter[i-1].Y,'S'+inttostr(i));

end;

{$R *.dfm}

procedure TForm3.FormCreate(Sender: TObject);

function Ploshad(A,B,C:Point):real;

var i:integer;

Al,Bl,Cl,p:real;

begin

Al:=sqrt(sqr(A.x-B.x)+sqr(A.y-B.y)+sqr(A.z-B.z));

Bl:=sqrt(sqr(B.x-c.x)+sqr(B.y-C.y)+sqr(B.z-C.z));

Cl:=sqrt(sqr(C.x-A.x)+sqr(C.y-A.y)+sqr(C.z-A.z));

p:=(Al+Bl+Cl)/2;

Ploshad:=sqrt(p*(p-Al)*(p-Bl)*(p-Cl));

end;

var i:integer;

S:real;

begin

Form3.Caption:='Просмотр сечения. ('+inttostr(E[M+1,0])+' угольник)';

for i:=1 to E[M+1,0] do

Form3.ListBox1.Items[i-1]:='S'+inttostr(i)+': '+floattostrf(V[E[M+1,i]].x,ffGeneral,3,5)+'; '+floattostrf(V[E[M+1,i]].y,ffGeneral,3,5)+'; '+floattostrf(V[E[M+1,i]].z,ffGeneral,3,5);

Form3.Edit2.Text:='('+floattostrf(A,ffGeneral,3,5)+')*X+('+floattostrf(B,ffGeneral,3,5)+')*Y+('+floattostrf(C,ffGeneral,3,5)+')*Z+('+floattostrf(D,ffGeneral,3,5)+')'+'=0';

CxW:=(Form3.Width+Form3.GroupBox1.Width) div 2;

CyW:=(Form3.Height) div 2;

MashW:=Scene[4].M.Mash;

S:=0;

for i:=1 to E[M+1,0]-2 do

S:=S+Ploshad(V[M+1],V[M+i+1],V[M+i+2]);

Form3.Edit1.Text:=floattostrf(S,ffGeneral,3,5)+' Ед.Кв.';

end;

procedure TForm3.Edit2KeyPress(Sender: TObject; var Key: Char);

begin

Key:=#0;

end;

procedure TForm3.Edit1KeyPress(Sender: TObject; var Key: Char);

begin

Key:=#0;

end;

procedure TForm3.FormPaint(Sender: TObject);

begin

PaintIntersection;

end;

procedure TForm3.FormMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

begin

if ssleft in shift then

begin

if MashW-(Y-Y0W)>0 then MashW:=MashW-(Y-Y0W) else ShowMessage('Масштаб: меньше нельзя!');

Form3.Repaint;

end;

X0W:=X; Y0W:=Y;

end;

procedure TForm3.BitBtn1Click(Sender: TObject);

begin

Form3.Close;

end;

end.


Список литературы

1.         Delphi 6. Справочное пособие. Архангельский А.Я. – М.: ЗАО «Издательство БИНОМ», 2001.

2.         Эффективная работа: 3ds max 4. Маров М. – СПб.: Питер, 2002.

3.         Геометрия. В 2-х ч. Ч. I. Учебное пособие для студентов физ.-мат. фак. пед. ин-тов. Атанасян Л.С., Базылев В.Т. – М.: Просвещение, 1986.


Информация о работе «Сечение многогранников»
Раздел: Математика
Количество знаков с пробелами: 64015
Количество таблиц: 3
Количество изображений: 8

Похожие работы

Скачать
15422
11
13

... встречи прямой (рёбер многогранника) с секущей плоскостью. (http://www.ssau.ru/books/gubanov/lection1.htm) Основной типовой задачей на эту тему в школьной программе является построение сечения, по трем, заданным на поверхности многогранника, точкам, принадлежащим секущей плоскости. Алгоритм построения такого сечения следующий: 1) Выбираем наиболее подходящую грань многогранника для ...

Скачать
31331
0
24

... задачи. Решение задач на построение сечений Работа по ознакомлению учащихся с проекционным чертежом может быть продолжена при обучении решению задач на построение сечений многогранников. Обучение решению задач на построение сечений можно проводить в следующем плане. Во-первых, первоначальное ознакомление учащихся с методами построения сечений следует проводить на метрически определенных ...

Скачать
94255
14
23

... подобраны опорные задачи, которые можно использовать на уроке при изучении данной темы. Таким образом, в данной работе были рассмотрены основные, общие моменты изучения многогранников в школьном курсе стереометрии. В следствие чего дальнейшие исследования могут проходить в направлении более детального изучения отдельных разделов данной темы, а также пропедевтического введения многогранников в ...

Скачать
88628
4
18

... имеют достаточно четкое и правильное представление из собственного жизненного опыта, а формулировки которых являются слишком громоздкими.   Выводы по § 1 1.      Основные цели изучения темы «Объемы многогранников» в курсе стереометрии – развитие пространственных представлений учащихся, освоение способов вычисления практически важных величин и дальнейшее развитие логического мышления учащихся. ...

0 комментариев


Наверх