From 6d7c43c85f8852ed3b3fa9cefc742bc87e941842 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Wed, 17 Dec 2025 12:12:16 +0100 Subject: =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20=D1=82?= =?UTF-8?q?=D1=80=D0=B5=D1=82=D1=8C=D1=8E=20=D0=B3=D0=BB=D0=B0=D0=B2=D1=83?= =?UTF-8?q?=20=D0=B7=D0=B0=D0=BD=D0=B8=D0=BC=D0=B0=D1=82=D0=B5=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0?= =?UTF-8?q?=D0=BC=D0=BC=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../3/5_ideal_gas/geometry.pas" | 344 +++++++++++++++++++++ .../3/5_ideal_gas/graphics_3d.lpi" | 90 ++++++ .../3/5_ideal_gas/graphics_3d.lpr" | 29 ++ .../3/5_ideal_gas/graphics_3d.lps" | 179 +++++++++++ .../3/5_ideal_gas/octahedron.lfm" | 54 ++++ .../3/5_ideal_gas/octahedron.pas" | 129 ++++++++ 6 files changed, 825 insertions(+) create mode 100644 "\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/geometry.pas" create mode 100644 "\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/graphics_3d.lpi" create mode 100644 "\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/graphics_3d.lpr" create mode 100644 "\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/graphics_3d.lps" create mode 100644 "\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/octahedron.lfm" create mode 100644 "\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/octahedron.pas" (limited to 'Занимательное программирование/3/5_ideal_gas') diff --git "a/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/geometry.pas" "b/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/geometry.pas" new file mode 100644 index 0000000..cbbff5d --- /dev/null +++ "b/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/geometry.pas" @@ -0,0 +1,344 @@ +unit Geometry; + +{$mode ObjFPC}{$H+} + +interface + +uses + Classes, SysUtils; + +type + { Вершины } + Vertex = record + x, y, z: Real; { Координаты вершины } + end; + { Ребра } + Edge = record + src, dest: Integer; { Индексы соединяемых вершин } + end; + + Object3D = class + public + vertices: array of Vertex; { вершины } + edges: array of Edge; { ребра } + xc, yc, zc: Real; { координаты центра объекта } + vx, vy, vz: Real; { значения составляющих его скорости } + xa, ya, za: Real; { скорость вращения вокруг оси } + + constructor Create(var center, velocity, axis: Vertex); + + procedure MoveCenter(); + end; + + Matrix = array[1..4, 1..4] of Real; { матрица 4x4 } + Column = array[1..4] of Real; { столбец } + +function CopyObject3D(Shape: Object3D): Object3D; + +{ умножение матрицы на матрицу } +function MMMult(lhs, rhs: Matrix): Matrix; +{ умножение матрицы на столбец } +function MCMult(lhs: Matrix; rhs: Column): Column; +{ матрица поворота модели } +function RotateMatrix(xa, ya, za: Real): Matrix; +function MoveMatrix(tx, ty, tz: Real): Matrix; +function ResizeMatrix(sx, sy, sz: Real): Matrix; +procedure RotateShape(Shape: Object3D); +procedure MoveShape(Shape: Object3D; Width, Height: Real); +procedure ResizeShape(var Shape: Object3D; sx, sy, sz: Real); + +implementation + +constructor Object3D.Create(var center, velocity, axis: Vertex); +const + size = 10; + cubeVertices: array of Vertex = ( + (x: -size; y: -size; z: -size), + (x: -size; y: size; z: -size), + (x: size; y: size; z: -size), + (x: size; y: -size; z: -size), + (x: -size; y: -size; z: size), + (x: -size; y: size; z: size), + (x: size; y: size; z: size), + (x: size; y: -size; z: size) + ); + cubeEdges: array of Edge = ( + (src: 0; dest: 1), + (src: 1; dest: 2), + (src: 2; dest: 3), + (src: 3; dest: 0), + (src: 4; dest: 5), + (src: 5; dest: 6), + (src: 6; dest: 7), + (src: 7; dest: 4), + (src: 0; dest: 4), + (src: 1; dest: 5), + (src: 2; dest: 6), + (src: 3; dest: 7) + ); +begin + vertices := cubeVertices; + edges := cubeEdges; + xc := center.x; + yc := center.y; + zc := center.z; + vx := velocity.x; + vy := velocity.y; + vz := velocity.z; + xa := axis.x; + ya := axis.y; + za := axis.z +end; + +procedure Object3D.MoveCenter(); +begin + xc := xc + Vx; + yc := yc + Vy; + zc := zc + Vz +end; + +function CopyObject3D(Shape: Object3D): Object3D; +begin + CopyObject3D.vertices := Copy(Shape.vertices, 0); + CopyObject3D.edges := Copy(Shape.edges, 0); + + CopyObject3D.xc := Shape.xc; + CopyObject3D.yc := Shape.yc; + CopyObject3D.zc := Shape.zc +end; + +function MMMult(lhs, rhs: Matrix): Matrix; +var + i, j, k: Integer; + r: Matrix; + s: Real; +begin + for i := 1 to 4 do + for j := 1 to 4 do + begin + s := 0; + for k := 1 to 4 do + s := s + lhs[i, k] * rhs[k, j]; + r[i, j] := s; + end; + MMMult := r; +end; + +function MCMult(lhs: Matrix; rhs: Column): Column; +var + k, i: Integer; + s: Real; + r: Column; +begin + for i := 1 to 4 do { аналогично MMMult } + begin + s := 0; + + for k := 1 to 4 do + s := s + lhs[i, k] * rhs[k]; + r[i] := s; + end; + + MCMult := r; +end; + +function RotateMatrix(xa, ya, za: Real): Matrix; +var + xr, yr, zr: Matrix; +begin + { матрица поворота вокруг оси Ox } + xr[1, 1] := 1; + xr[1, 2] := 0; + xr[1, 3] := 0; + xr[1, 4] := 0; + + xr[2, 1] := 0; + xr[2, 2] := Cos(xa); + xr[2, 3] := -Sin(xa); + xr[2, 4] := 0; + + xr[3, 1] := 0; + xr[3, 2] := Sin(xa); + xr[3, 3] := Cos(xa); + xr[3, 4] := 0; + + xr[4, 1] := 0; + xr[4, 2] := 0; + xr[4, 3] := 0; + xr[4, 4] := 1; + + { матрица поворота вокруг оси Oy } + yr[1, 1] := Cos(ya); + yr[1, 2] := 0; + yr[1, 3] := Sin(ya); + yr[1, 4] := 0; + + yr[2, 1] := 0; + yr[2, 2] := 1; + yr[2, 3] := 0; + yr[2, 4] := 0; + + yr[3, 1] := -Sin(ya); + yr[3, 2] := 0; + yr[3, 3] := Cos(ya); + yr[3, 4] := 0; + + yr[4, 1] := 0; + yr[4, 2] := 0; + yr[4, 3] := 0; + yr[4, 4] := 1; + + { матрица поворота вокруг оси Oz } + zr[1, 1] := Cos(za); + zr[1, 2] := -Sin(za); + zr[1, 3] := 0; + zr[1, 4] := 0; + + zr[2, 1] := Sin(za); + zr[2, 2] := Cos(za); + zr[2, 3] := 0; + zr[2, 4] := 0; + + zr[3, 1] := 0; + zr[3, 2] := 0; + zr[3, 3] := 1; + zr[3, 4] := 0; + + zr[4, 1] := 0; + zr[4, 2] := 0; + zr[4, 3] := 0; + zr[4, 4] := 1; + + RotateMatrix := MMMult(MMMult(xr, yr), zr) +end; + +function MoveMatrix(tx, ty, tz: Real): Matrix; +begin + MoveMatrix[1, 1] := 1; + MoveMatrix[1, 2] := 0; + MoveMatrix[1, 3] := 0; + MoveMatrix[1, 4] := tx; + + MoveMatrix[2, 1] := 0; + MoveMatrix[2, 2] := 1; + MoveMatrix[2, 3] := 0; + MoveMatrix[2, 4] := ty; + + MoveMatrix[3, 1] := 0; + MoveMatrix[3, 2] := 0; + MoveMatrix[3, 3] := 1; + MoveMatrix[3, 4] := tz; + + MoveMatrix[4, 1] := 0; + MoveMatrix[4, 2] := 0; + MoveMatrix[4, 3] := 0; + MoveMatrix[4, 4] := 1 +end; + +function ResizeMatrix(sx, sy, sz: Real): Matrix; +begin + ResizeMatrix[1, 1] := sx; + ResizeMatrix[1, 2] := 0; + ResizeMatrix[1, 3] := 0; + ResizeMatrix[1, 4] := 0; + + ResizeMatrix[2, 1] := 0; + ResizeMatrix[2, 2] := sy; + ResizeMatrix[2, 3] := 0; + ResizeMatrix[2, 4] := 0; + + ResizeMatrix[3, 1] := 0; + ResizeMatrix[3, 2] := 0; + ResizeMatrix[3, 3] := sz; + ResizeMatrix[3, 4] := 0; + + ResizeMatrix[4, 1] := 0; + ResizeMatrix[4, 2] := 0; + ResizeMatrix[4, 3] := 0; + ResizeMatrix[4, 4] := 1 +end; + +procedure RotateShape(Shape: Object3D); +var + rm: Matrix; + i: Integer; + c: Column; +begin + rm := RotateMatrix(Shape.xa, Shape.ya, Shape.za); { сгенерировать матрицу вращения } + c[4] := 1; { последний элемент столбца всегда равен единице } + + for i := 0 to High(Shape.vertices) do { цикл по всем вершинам } + begin { High(a) возвращает верхний индекс массива a } + c[1] := Shape.vertices[i].x; { инициализация столбца } + c[2] := Shape.vertices[i].y; + c[3] := Shape.vertices[i].z; + + c := MCMult(rm, c); { вызов преобразования } + + Shape.vertices[i].x := c[1]; { внесение изменений в модель } + Shape.vertices[i].y := c[2]; { в соответствии с полученным } + Shape.vertices[i].z := c[3] { результатом преобразования } + end +end; + +procedure MoveShape(Shape: Object3D; Width, Height: Real); +begin + if Shape.xc > Width then + begin + Shape.xc := Width; + Shape.Vx := -Shape.Vx + end; + if Shape.xc < -Width then + begin + Shape.xc := -Width; + Shape.Vx := -Shape.Vx + end; + + if Shape.yc > Height then + begin + Shape.yc := Height; + Shape.Vy := -Shape.Vy + end; + if Shape.yc < -Height then + begin + Shape.yc := -Height; + Shape.Vy := -Shape.Vy + end; + + if Shape.zc > 500 then + begin + Shape.zc := 500; + Shape.Vz := -Shape.Vz + end; + if Shape.zc < 200 then + begin + Shape.zc := 200; + Shape.Vz := -Shape.Vz + end; +end; + +procedure ResizeShape(var Shape: Object3D; sx, sy, sz: Real); +var + mm: Matrix; + i: Integer; + c: Column; +begin + mm := ResizeMatrix(sx, sy, sz); + c[4] := 1; + + for i := 0 to High(Shape.vertices) do + begin + c[1] := Shape.vertices[i].x; + c[2] := Shape.vertices[i].y; + c[3] := Shape.vertices[i].z; + + c := MCMult(mm, c); + + Shape.vertices[i].x := c[1]; + Shape.vertices[i].y := c[2]; + Shape.vertices[i].z := c[3] + end +end; + +end. + diff --git "a/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/graphics_3d.lpi" "b/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/graphics_3d.lpi" new file mode 100644 index 0000000..67fa0db --- /dev/null +++ "b/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/graphics_3d.lpi" @@ -0,0 +1,90 @@ + + + + + + + + + <Scaled Value="True"/> + <ResourceType Value="res"/> + <UseXPManifest Value="True"/> + <XPManifest> + <DpiAware Value="True"/> + </XPManifest> + <Icon Value="0"/> + </General> + <BuildModes> + <Item Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + </RunParams> + <RequiredPackages> + <Item> + <PackageName Value="LCL"/> + </Item> + </RequiredPackages> + <Units> + <Unit> + <Filename Value="graphics_3d.lpr"/> + <IsPartOfProject Value="True"/> + </Unit> + <Unit> + <Filename Value="octahedron.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="Form1"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="Octahedron"/> + </Unit> + <Unit> + <Filename Value="geometry.pas"/> + <IsPartOfProject Value="True"/> + <UnitName Value="Geometry"/> + </Unit> + <Unit> + <Filename Value="octahedron.txt"/> + <IsPartOfProject Value="True"/> + </Unit> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="graphics_3d"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf3"/> + </Debugging> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions> + <Item> + <Name Value="EAbort"/> + </Item> + <Item> + <Name Value="ECodetoolError"/> + </Item> + <Item> + <Name Value="EFOpenError"/> + </Item> + </Exceptions> + </Debugging> +</CONFIG> diff --git "a/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/graphics_3d.lpr" "b/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/graphics_3d.lpr" new file mode 100644 index 0000000..3778580 --- /dev/null +++ "b/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/graphics_3d.lpr" @@ -0,0 +1,29 @@ +program graphics_3d; + +{$mode objfpc}{$H+} + +uses + {$IFDEF UNIX} + cthreads, + {$ENDIF} + {$IFDEF HASAMIGA} + athreads, + {$ENDIF} + Interfaces, // this includes the LCL widgetset + Forms, Octahedron, geometry + { you can add units after this }; + +{$R *.res} + +begin + Randomize; + RequireDerivedFormResource:=True; + Application.Scaled:=True; + {$PUSH}{$WARN 5044 OFF} + Application.MainFormOnTaskbar:=True; + {$POP} + Application.Initialize; + Application.CreateForm(TForm1, Form1); + Application.Run; +end. + diff --git "a/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/graphics_3d.lps" "b/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/graphics_3d.lps" new file mode 100644 index 0000000..d227996 --- /dev/null +++ "b/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/graphics_3d.lps" @@ -0,0 +1,179 @@ +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectSession> + <PathDelim Value="\"/> + <Version Value="12"/> + <BuildModes Active="Default"/> + <Units> + <Unit> + <Filename Value="graphics_3d.lpr"/> + <IsPartOfProject Value="True"/> + <EditorIndex Value="1"/> + <CursorPos X="20"/> + <UsageCount Value="58"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="octahedron.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="Form1"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="Octahedron"/> + <IsVisibleTab Value="True"/> + <TopLine Value="13"/> + <CursorPos X="23" Y="21"/> + <UsageCount Value="58"/> + <Bookmarks Count="1"> + <Item0 X="17" Y="48" Left="1" Top="79" ID="3"/> + </Bookmarks> + <Loaded Value="True"/> + <LoadedDesigner Value="True"/> + </Unit> + <Unit> + <Filename Value="geometry.pas"/> + <IsPartOfProject Value="True"/> + <UnitName Value="Geometry"/> + <EditorIndex Value="2"/> + <TopLine Value="50"/> + <CursorPos X="29" Y="52"/> + <UsageCount Value="58"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="octahedron.txt"/> + <IsPartOfProject Value="True"/> + <EditorIndex Value="-1"/> + <CursorPos X="15" Y="13"/> + <UsageCount Value="58"/> + <DefaultSyntaxHighlighter Value="Text"/> + </Unit> + </Units> + <JumpHistory HistoryIndex="29"> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="81" Column="24" TopLine="56"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="96" Column="10" TopLine="72"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="103" Column="22" TopLine="79"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="106" Column="24" TopLine="81"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="107" Column="22" TopLine="83"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="112" Column="12" TopLine="88"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="15" Column="11" TopLine="8"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="81" Column="24" TopLine="56"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="87" Column="19" TopLine="76"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="98" Column="11" TopLine="76"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="106" Column="21" TopLine="82"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="108" Column="23" TopLine="84"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="110" Column="21" TopLine="86"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="115" Column="11" TopLine="91"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="81" Column="24" TopLine="65"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="98" Column="11" TopLine="74"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="108" Column="22" TopLine="89"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="110" Column="27" TopLine="89"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="112" Column="25" TopLine="89"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="117" Column="15" TopLine="93"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="81" Column="26" TopLine="65"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="98" Column="13" TopLine="74"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="108" Column="25" TopLine="84"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="110" Column="27" TopLine="86"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="112" Column="25" TopLine="88"/> + </Position> + <Position> + <Filename Value="octahedron.pas"/> + <Caret Line="117" Column="15" TopLine="93"/> + </Position> + <Position> + <Filename Value="geometry.pas"/> + <Caret Line="14" Column="11"/> + </Position> + <Position> + <Filename Value="geometry.pas"/> + <Caret Line="49" Column="26" TopLine="33"/> + </Position> + <Position> + <Filename Value="geometry.pas"/> + <Caret Line="103" Column="34" TopLine="90"/> + </Position> + <Position> + <Filename Value="geometry.pas"/> + <Caret Line="28" Column="24" TopLine="11"/> + </Position> + </JumpHistory> + <RunParams> + <FormatVersion Value="2"/> + <Modes ActiveMode=""/> + </RunParams> + </ProjectSession> +</CONFIG> diff --git "a/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/octahedron.lfm" "b/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/octahedron.lfm" new file mode 100644 index 0000000..8db0965 --- /dev/null +++ "b/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/octahedron.lfm" @@ -0,0 +1,54 @@ +object Form1: TForm1 + Left = 352 + Height = 673 + Top = 32 + Width = 600 + Caption = 'Form1' + ClientHeight = 673 + ClientWidth = 600 + DesignTimePPI = 120 + LCLVersion = '4.2.0.0' + object BackScreen: TImage + AnchorSideLeft.Control = Owner + AnchorSideTop.Control = Owner + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = StartStopBtn + Left = 0 + Height = 600 + Top = 0 + Width = 600 + Anchors = [akTop, akLeft, akRight, akBottom] + BorderSpacing.Bottom = 15 + end + object Screen: TPaintBox + AnchorSideLeft.Control = Owner + AnchorSideTop.Control = Owner + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = StartStopBtn + Left = 0 + Height = 600 + Top = 0 + Width = 600 + Anchors = [akTop, akLeft, akRight, akBottom] + BorderSpacing.Bottom = 15 + end + object StartStopBtn: TButton + AnchorSideLeft.Control = Owner + AnchorSideLeft.Side = asrCenter + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrCenter + AnchorSideBottom.Control = Owner + AnchorSideBottom.Side = asrBottom + Left = 241 + Height = 48 + Top = 615 + Width = 118 + Anchors = [akLeft, akBottom] + BorderSpacing.Bottom = 10 + Caption = 'Пуск' + TabOrder = 0 + OnClick = StartStopBtnClick + end +end diff --git "a/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/octahedron.pas" "b/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/octahedron.pas" new file mode 100644 index 0000000..31fe970 --- /dev/null +++ "b/\320\227\320\260\320\275\320\270\320\274\320\260\321\202\320\265\320\273\321\214\320\275\320\276\320\265 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/3/5_ideal_gas/octahedron.pas" @@ -0,0 +1,129 @@ +unit Octahedron; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, + Geometry; + +type + + { TForm1 } + + TForm1 = class(TForm) + BackScreen: TImage; + StartStopBtn: TButton; + Screen: TPaintBox; + procedure StartStopBtnClick(Sender: TObject); + private + Model: array[1..10] of Object3D; { трехмерный объект } + public + + end; + +var + Form1: TForm1; + IsRunning: Boolean = false; + +implementation + +{$R *.lfm} + +procedure ShowShape(Shape: Object3D); { нарисовать объект } +var + i, Xs, Ys: Integer; + x, y, z: Real; +const + N = 300; { "глубина" экрана } +begin + for i := 0 to High(Shape.edges) do { цикл по всем ребрам } + begin { координаты первой точки ребра } + x := Shape.vertices[Shape.edges[i].src].x + Shape.xc; + y := Shape.vertices[Shape.edges[i].src].y + Shape.yc; + z := Shape.vertices[Shape.edges[i].src].z + Shape.zc; + if Abs(z) < 0.01 then z := 0.01; { избегаем деления на нуль } + { вычисляем экранные координаты } + Xs := Round(Form1.Screen.Width div 2 + N * x / z); + Ys := Round(Form1.Screen.Height div 2 + N * y / z); + + Form1.BackScreen.Canvas.MoveTo(Xs, Ys); + { координаты второй точки зрения } + x := Shape.vertices[Shape.edges[i].dest].x + Shape.xc; + y := Shape.vertices[Shape.edges[i].dest].y + Shape.yc; + z := Shape.vertices[Shape.edges[i].dest].z + Shape.zc; + if Abs(z) < 0.01 then z := 0.01; { избегаем деления на нуль } + { и ее экранные координаты } + Xs := Round(Form1.Screen.Width div 2 + N * x / z); + Ys := Round(Form1.Screen.Height div 2 + N * y / z); + + Form1.BackScreen.Canvas.LineTo(Xs, Ys); { рисуем ребро } + end; +end; + +{ TForm1 } + +procedure TForm1.StartStopBtnClick(Sender: TObject); { главная процедура } +var + oldtime: TDateTime; + pause: Integer; + center, velocity, axis: Vertex; + i: Integer; +const + MSecsPerFrame = 25; { скорость работы (кадров в секунду) } +begin + if IsRunning then + begin + IsRunning := false; + StartStopBtn.Caption := 'Пуск'; + for i := 1 to Length(Model) do + FreeAndNil(Model[i]); + Exit; + end; + StartStopBtn.Caption := 'Стоп'; + IsRunning := true; + + for i := 1 to Length(Model) do + begin + axis.x := Random(10) / 100; { скорость вращения вокруг оси Ox } + axis.y := Random(10) / 100; { скорость вращения вокруг оси Oy } + axis.z := Random(10) / 100; { скорость вращения вокруг оси Oz } + velocity.x := 10 - Random(20); { и составляющие } + velocity.y := 15 - Random(30); { скорости } + velocity.z := 20 - Random(40); + center.x := (Screen.Width div 2) - Random(Screen.Width); { начальное положение } + center.y := (Screen.Width div 2) - Random(Screen.Width); { начальное положение } + center.z := Random(300) + 200; + Model[i] := Object3D.Create(center, velocity, axis) { загрузить объект } + end; + + while IsRunning do + begin + oldtime := Now; + BackScreen.Canvas.FillRect(Rect(0, 0, Screen.Width, Screen.Height)); + + for i := 1 to Length(Model) do + begin + { отразить от стена (3D-аналог "молекулы в закрытом сосуде") } + MoveShape(Model[i], BackScreen.Width div 2, BackScreen.Height div 2); + + RotateShape(Model[i]); { поворот модели } + ShowShape(Model[i]); { очистить экран и нарисовать объект } + Model[i].MoveCenter() + end; + { отобразить объект на основном экране } + Screen.Canvas.CopyRect(Rect(0, 0, Screen.Width, Screen.Height), + BackScreen.Canvas, Rect(0, 0, Screen.Width, Screen.Height)); + + + Application.ProcessMessages; + pause := Round(MSecsPerFrame - (Now - oldtime) * MSecsPerDay); + if pause > 0 then Sleep(pause); { задержка } + + if Application.Terminated then Exit; + end; +end; + +end. + -- cgit v1.2.3