Add project files.
This commit is contained in:
parent
94d3b0421f
commit
9797b3c6f5
5
Lab1/BMP File Format.url
Normal file
5
Lab1/BMP File Format.url
Normal file
@ -0,0 +1,5 @@
|
||||
[{000214A0-0000-0000-C000-000000000046}]
|
||||
Prop3=19,2
|
||||
[InternetShortcut]
|
||||
IDList=
|
||||
URL=http://www.ece.ualberta.ca/~elliott/ee552/studentAppNotes/2003_w/misc/bmp_file_format/bmp_file_format.htm
|
BIN
Lab1/BMP formatas.docx
Normal file
BIN
Lab1/BMP formatas.docx
Normal file
Binary file not shown.
359
Lab1/BMPImage.cs
Normal file
359
Lab1/BMPImage.cs
Normal file
@ -0,0 +1,359 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace Lab1
|
||||
{
|
||||
internal struct Color
|
||||
{
|
||||
public byte r = 0, g = 0, b = 0;
|
||||
|
||||
public Color(byte r, byte g, byte b)
|
||||
{
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
public Color(Color color)
|
||||
{
|
||||
this.r = color.r;
|
||||
this.g = color.g;
|
||||
this.b = color.b;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Color({r}, {g}, {b})";
|
||||
}
|
||||
}
|
||||
|
||||
internal class BMPImage
|
||||
{
|
||||
public uint width, height;
|
||||
public Color[] data;
|
||||
|
||||
public BMPImage(uint width, uint height)
|
||||
{
|
||||
Debug.Assert(width > 0, "Width must be at least 1");
|
||||
Debug.Assert(height > 0, "Height must be at least 1");
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
this.data = new Color[width * height];
|
||||
}
|
||||
|
||||
public void SetPixel(int x, int y, int r, int g, int b)
|
||||
{
|
||||
if (x < 0 || y < 0 || x >= width || y >= height) return;
|
||||
data[width * y + x].r = (byte)r;
|
||||
data[width * y + x].g = (byte)g;
|
||||
data[width * y + x].b = (byte)b;
|
||||
}
|
||||
|
||||
public Color GetPixel(int x, int y)
|
||||
{
|
||||
if (x < 0 || y < 0 || x >= width || y >= height) return new Color(0, 0, 0);
|
||||
return new Color(data[width * y + x]);
|
||||
}
|
||||
|
||||
public void SetPixel(int x, int y, Color color)
|
||||
{
|
||||
SetPixel(x, y, color.r, color.g, color.b);
|
||||
}
|
||||
|
||||
public void Fill(Color color)
|
||||
{
|
||||
Rectangle(0, 0, (int)width, (int)height, color);
|
||||
}
|
||||
|
||||
public void Rectangle(int x, int y, int width, int height, Color color)
|
||||
{
|
||||
for (int dy = 0; dy < height; dy++)
|
||||
{
|
||||
for (int dx = 0; dx < width; dx++)
|
||||
{
|
||||
SetPixel(x + dx, y + dy, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void swap(ref int a, ref int b)
|
||||
{
|
||||
int c = a;
|
||||
a = b;
|
||||
b = c;
|
||||
}
|
||||
|
||||
public void Line(int x1, int y1, int x2, int y2, Color color)
|
||||
{
|
||||
int dx = x2 - x1;
|
||||
int dy = y2 - y1;
|
||||
|
||||
if (dx == 0 && dy == 0)
|
||||
{
|
||||
SetPixel(x1, y1, color);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Math.Abs(dx) > Math.Abs(dy))
|
||||
{
|
||||
if (x1 > x2)
|
||||
{
|
||||
swap(ref x1, ref x2);
|
||||
swap(ref y1, ref y2);
|
||||
}
|
||||
|
||||
for (int x = x1; x <= x2; ++x)
|
||||
{
|
||||
int y = dy * (x - x1) / dx + y1;
|
||||
SetPixel(x, y, color);
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (y1 > y2)
|
||||
{
|
||||
swap(ref x1, ref x2);
|
||||
swap(ref y1, ref y2);
|
||||
}
|
||||
|
||||
for (int y = y1; y <= y2; ++y)
|
||||
{
|
||||
int x = dx * (y - y1) / dy + x1;
|
||||
SetPixel(x, y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void SortPointsByX(ref int x1, ref int y1, ref int x2, ref int y2, ref int x3, ref int y3)
|
||||
{
|
||||
if (x1 > x2)
|
||||
{
|
||||
swap(ref x1, ref x2);
|
||||
swap(ref y1, ref y2);
|
||||
}
|
||||
|
||||
if (x1 > x3)
|
||||
{
|
||||
swap(ref x1, ref x3);
|
||||
swap(ref y1, ref y3);
|
||||
}
|
||||
|
||||
if (x2 > x3)
|
||||
{
|
||||
swap(ref x2, ref x3);
|
||||
swap(ref y2, ref y3);
|
||||
}
|
||||
}
|
||||
|
||||
public void Triangle(int x1, int y1, int x2, int y2, int x3, int y3, Color color)
|
||||
{
|
||||
SortPointsByX(ref x1, ref y1, ref x2, ref y2, ref x3, ref y3);
|
||||
|
||||
if (x2 - x1 == 0) return;
|
||||
if (x3 - x1 == 0) return;
|
||||
if (x3 - x2 == 0) return;
|
||||
if (x3 - x1 == 0) return;
|
||||
|
||||
for (int x = x1; x <= x2; x++)
|
||||
{
|
||||
int yEdge1 = (y2 - y1) * (x - x1) / (x2 - x1) + y1;
|
||||
int yEdge2 = (y3 - y1) * (x - x1) / (x3 - x1) + y1;
|
||||
for (int y = Math.Min(yEdge1, yEdge2); y < Math.Max(yEdge1, yEdge2); y++)
|
||||
{
|
||||
SetPixel(x, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
for (int x = x2; x <= x3; x++)
|
||||
{
|
||||
int yEdge1 = (y3 - y2) * (x - x2) / (x3 - x2) + y2;
|
||||
int yEdge2 = (y3 - y1) * (x - x1) / (x3 - x1) + y1;
|
||||
for (int y = Math.Min(yEdge1, yEdge2); y < Math.Max(yEdge1, yEdge2); y++)
|
||||
{
|
||||
SetPixel(x, y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Circle(int x, int y, int radius, Color color)
|
||||
{
|
||||
for (int dy = -(int)radius; dy < radius; dy++)
|
||||
{
|
||||
for (int dx = -(int)radius; dx < radius; dx++)
|
||||
{
|
||||
if (dx*dx + dy*dy < radius*radius)
|
||||
{
|
||||
SetPixel(x + dx, y + dy, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteBytes(FileStream f, params byte[] bytes)
|
||||
{
|
||||
f.Write(bytes);
|
||||
}
|
||||
|
||||
private static void WriteUInt16(FileStream f, UInt16 number)
|
||||
{
|
||||
WriteBytes(f,
|
||||
(byte)((number >> 8 * 0) & 0xFF),
|
||||
(byte)((number >> 8 * 1) & 0xFF)
|
||||
);
|
||||
}
|
||||
private static void WriteUInt32(FileStream f, UInt32 number)
|
||||
{
|
||||
WriteBytes(f,
|
||||
(byte)((number >> 8 * 0) & 0xFF),
|
||||
(byte)((number >> 8 * 1) & 0xFF),
|
||||
(byte)((number >> 8 * 2) & 0xFF),
|
||||
(byte)((number >> 8 * 3) & 0xFF)
|
||||
);
|
||||
}
|
||||
|
||||
private static ushort DetermineBPP(ICollection<Color> colors)
|
||||
{
|
||||
int count = colors.Count;
|
||||
if (count <= 2)
|
||||
{
|
||||
return 1;
|
||||
} else if (count <= 16)
|
||||
{
|
||||
return 4;
|
||||
} else if (count <= 256)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
return 24;
|
||||
}
|
||||
|
||||
private static uint GetScanlineSize(uint width, uint bpp)
|
||||
{
|
||||
return ((width * bpp + 31) / 32 * 32) / 8u;
|
||||
}
|
||||
|
||||
private byte[] EncodePixelData(uint bpp, List<Color> usedColors)
|
||||
{
|
||||
uint scanline = GetScanlineSize(width, bpp);
|
||||
byte[] pixelData = new byte[height * scanline];
|
||||
if (bpp == 1)
|
||||
{
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
int idx = 0;
|
||||
for (int x = 0; x < width; x += 8)
|
||||
{
|
||||
byte pix1 = (byte)(usedColors.IndexOf(GetPixel(x + 0, y)) & 1);
|
||||
byte pix2 = (byte)(usedColors.IndexOf(GetPixel(x + 1, y)) & 1);
|
||||
byte pix3 = (byte)(usedColors.IndexOf(GetPixel(x + 2, y)) & 1);
|
||||
byte pix4 = (byte)(usedColors.IndexOf(GetPixel(x + 3, y)) & 1);
|
||||
byte pix5 = (byte)(usedColors.IndexOf(GetPixel(x + 4, y)) & 1);
|
||||
byte pix6 = (byte)(usedColors.IndexOf(GetPixel(x + 5, y)) & 1);
|
||||
byte pix7 = (byte)(usedColors.IndexOf(GetPixel(x + 6, y)) & 1);
|
||||
byte pix8 = (byte)(usedColors.IndexOf(GetPixel(x + 7, y)) & 1);
|
||||
pixelData[scanline * y + idx] = (byte)(pix1 << 7 | pix2 << 6 | pix3 << 5 | pix4 << 4 | pix5 << 3 | pix6 << 2 | pix7 << 1 | pix8 << 0);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bpp == 4)
|
||||
{
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
int idx = 0;
|
||||
for (int x = 0; x < width; x += 2)
|
||||
{
|
||||
byte pix1 = (byte)(usedColors.IndexOf(GetPixel(x + 0, y)) & 0xF);
|
||||
byte pix2 = (byte)(usedColors.IndexOf(GetPixel(x + 1, y)) & 0xF);
|
||||
pixelData[scanline * y + idx] = (byte)(pix1 << 4 | pix2 << 0);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bpp == 8)
|
||||
{
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
pixelData[scanline * y + x] = (byte)(usedColors.IndexOf(GetPixel(x, y)) & 0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bpp == 24)
|
||||
{
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
Color color = GetPixel(x, y);
|
||||
pixelData[scanline * y + 3 * x + 0] = color.b;
|
||||
pixelData[scanline * y + 3 * x + 1] = color.g;
|
||||
pixelData[scanline * y + 3 * x + 2] = color.r;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
return pixelData;
|
||||
}
|
||||
|
||||
public void Write(string filename)
|
||||
{
|
||||
List<Color> usedColors = new List<Color>();
|
||||
for (int i = 0; i < width*height; i++)
|
||||
{
|
||||
if (!usedColors.Contains(data[i]))
|
||||
{
|
||||
usedColors.Add(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
ushort bpp = DetermineBPP(usedColors);
|
||||
byte[] pixelData = EncodePixelData(bpp, usedColors);
|
||||
|
||||
using (FileStream f = new FileStream(filename, FileMode.Create, FileAccess.Write))
|
||||
{
|
||||
// Write header
|
||||
WriteBytes(f, 0x42, 0x4d); // signature
|
||||
WriteUInt32(f, 0); // file size
|
||||
WriteUInt32(f, 0); // reserved
|
||||
WriteUInt32(f, 0); // data offset
|
||||
|
||||
// Write info header
|
||||
WriteUInt32(f, 40); // info header size, always 40
|
||||
WriteUInt32(f, width); // width
|
||||
WriteUInt32(f, height); // height
|
||||
WriteUInt16(f, 1); // number of planes
|
||||
WriteUInt16(f, bpp); // bits per pixel
|
||||
WriteUInt32(f, 0); // compression
|
||||
WriteUInt32(f, 0); // size of compressed image
|
||||
WriteUInt32(f, 0); // x pixel per meter
|
||||
WriteUInt32(f, 0); // y pixel per meter
|
||||
WriteUInt32(f, 0); // colors used
|
||||
WriteUInt32(f, 0); // important colors, 0 = all
|
||||
|
||||
if (bpp <= 8)
|
||||
{
|
||||
foreach (Color color in usedColors)
|
||||
{
|
||||
WriteBytes(f, color.b, color.g, color.r, 0);
|
||||
}
|
||||
for (int i = 0; i < Math.Pow(2, bpp) - usedColors.Count; i++)
|
||||
{
|
||||
WriteBytes(f, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Write pixel data
|
||||
f.Write(pixelData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
8
Lab1/Lab1.csproj
Normal file
8
Lab1/Lab1.csproj
Normal file
@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
138
Lab1/Program.cs
Normal file
138
Lab1/Program.cs
Normal file
@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Lab1
|
||||
{
|
||||
class Program
|
||||
{
|
||||
// O(n^5)
|
||||
public static double T1(int[] n, int size)
|
||||
{
|
||||
if (size >= 1)
|
||||
{
|
||||
int sum = 0;
|
||||
for (int i = 0; i < Math.Pow(size, 5); i++)
|
||||
{
|
||||
sum += i;
|
||||
}
|
||||
return 2 * T1(n, size / 9) + sum;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static double T1(int[] n)
|
||||
{
|
||||
return T1(n, n.Length);
|
||||
}
|
||||
|
||||
// O(n)
|
||||
public static double T2(int[] n, int size)
|
||||
{
|
||||
if (size >= 1)
|
||||
{
|
||||
int sum = 0;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
sum += i;
|
||||
}
|
||||
return T2(n, size / 6) + T2(n, size / 7) + sum;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static double T2(int[] n)
|
||||
{
|
||||
return T2(n, n.Length);
|
||||
}
|
||||
|
||||
// O(n^2)
|
||||
public static double T3(int[] n, int size)
|
||||
{
|
||||
if (size >= 1)
|
||||
{
|
||||
int sum = 0;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
sum += i;
|
||||
}
|
||||
return T3(n, size - 8) + T3(n, size - 6) + sum;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static double T3(int[] n)
|
||||
{
|
||||
return T3(n, n.Length);
|
||||
}
|
||||
|
||||
// O(log4(n))
|
||||
public static void TrianglesRecursive(BMPImage image, int x, int y, uint width, uint height)
|
||||
{
|
||||
if (width <= 3 || height <= 3) return;
|
||||
|
||||
image.Triangle(
|
||||
x + (int)(width / 3 * 1 ), (y + (int)height / 3 * 2),
|
||||
x + (int)(width / 3 * 2 ), (y + (int)height / 3 * 2),
|
||||
x + (int)(width / 3 * 1.5), (y + (int)height / 3 * 1),
|
||||
new Color(0, 0, 0)
|
||||
);
|
||||
|
||||
TrianglesRecursive(
|
||||
image, x, y, width/3, height/3
|
||||
);
|
||||
TrianglesRecursive(
|
||||
image, x + (int)width/3*2, y, width / 3, height / 3
|
||||
);
|
||||
TrianglesRecursive(
|
||||
image, x, y + (int)height/3*2, width / 3, height / 3
|
||||
);
|
||||
TrianglesRecursive(
|
||||
image, x + (int)width / 3 * 2, y + (int)height / 3 * 2, width / 3, height / 3
|
||||
);
|
||||
}
|
||||
|
||||
public static void Triangles()
|
||||
{
|
||||
BMPImage image = new BMPImage(1000, 1000);
|
||||
image.Fill(new Color(255, 255, 255));
|
||||
TrianglesRecursive(image, 0, 0, image.width, image.height);
|
||||
image.Write("result.bmp");
|
||||
}
|
||||
|
||||
public static double TestFunc(Func<int[], double> T, uint n)
|
||||
{
|
||||
int[] data = new int[n];
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
data[i] = i;
|
||||
}
|
||||
|
||||
var before = DateTime.Now;
|
||||
T(data);
|
||||
var duration = DateTime.Now - before;
|
||||
return duration.TotalSeconds;
|
||||
}
|
||||
|
||||
static void Main()
|
||||
{
|
||||
// T1(10) => 0.0056552
|
||||
// T1(20) => 0.0699722
|
||||
// T1(40) => 2.1500858
|
||||
// T1(50) => 6.4564238
|
||||
|
||||
// T2(100) => 0.0039419
|
||||
// T2(1_000_000) => 0.0048064
|
||||
// T2(250_000_000) => 0.3011757
|
||||
// T2(500_000_000) => 0.6046134
|
||||
// T2(1_000_000_000) => 1.1902643
|
||||
|
||||
// T3(100) => 0.0041945
|
||||
// T3(150) => 0.0759872
|
||||
// T3(180) => 1.4428123
|
||||
// T3(190) => 3.9067703
|
||||
|
||||
//Triangles();
|
||||
}
|
||||
}
|
||||
}
|
34
Lab1/README.md
Normal file
34
Lab1/README.md
Normal file
@ -0,0 +1,34 @@
|
||||
# Lab1
|
||||
|
||||
## 1 užduotis
|
||||
Kiekvienai rekurentinei lygčiai (gautai atlikus užduoties pasirinkimo testą):
|
||||
|
||||
* Realizuoti metodą, kuris atitiktų pateiktos rekurentinės lygties sudėtingumą, t. y.
|
||||
programinio kodo rekursinių iškvietimų ir kiekvieno iškvietimo metu atliekamų veiksmų
|
||||
priklausomybę nuo duomenų. Metodas per parametrus turi priimti masyvą, kurio duomenų kiekis
|
||||
yra rekurentinės lygties kintamasis n (arba masyvą ir indeksų rėžius, kurie atitinkamai
|
||||
nurodo masyvo nagrinėjamų elementų indeksus atitinkamame iškvietime) (2 balai).
|
||||
|
||||
* Kiekvienam realizuotam metodui atlikti programinio kodo analizę, parodant jog jis atitinka
|
||||
pateiktą rekurentinę lygtį (1 balas).
|
||||
|
||||
* Išspręskite rekurentinę lygtį ir apskaičiuokite jos asimptotinį sudėtingumą (taikoma
|
||||
pagrindinė teorema, medžių ar kitas sprendimo metodas) (1 balas)
|
||||
|
||||
* Atlikti eksperimentinį tyrimą (našumo testus: vykdymo laiką ir veiksmų skaičių) ir patikrinkite
|
||||
ar apskaičiuotas metodo asimptotinis sudėtingumas atitinka eksperimentinius rezultatus (1 balas).
|
||||
|
||||
## 2 užduoties dalis
|
||||
Naudojant rekursiją ir nenaudojant grafinių bibliotekų sudaryti nurodytos struktūros
|
||||
BMP formato ( gautą atlikus užduoties pasirinkimo testą):
|
||||
|
||||
* Programos rezultatas BMP formato bylos demonstruojančios programos rekursijas. (3 balai)
|
||||
|
||||
* Eksperimentiškai nustatykite darbo laiko ir veiksmų skaičiaus priklausomybę nuo generuojamo
|
||||
paveikslėlio dydžio (taškų skaičiaus). Gautus rezultatus atvaizduokite grafikais.
|
||||
Grafiką turi sudaryti nemažiau kaip 5 taškai ir paveikslėlio taškų skaičius turi didėti
|
||||
proporcingai (kartais). (1 balas)
|
||||
|
||||
* Analitiškai įvertinkite procedūros, kuri generuoja paveikslėlį, veiksmų skaičių sudarydami
|
||||
rekurentinę lygtį ir ją išspręskite. Gautas rezultatas turi patvirtinti eksperimentinius
|
||||
rezultatus (našumo testus: vykdymo laiką ir veiksmų skaičių). (1 balas)
|
25
Labs.sln
Normal file
25
Labs.sln
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.1.32328.378
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lab1", "Lab1\Lab1.csproj", "{497767A1-722A-4F48-86E5-C2AE6E0B9C9A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{497767A1-722A-4F48-86E5-C2AE6E0B9C9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{497767A1-722A-4F48-86E5-C2AE6E0B9C9A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{497767A1-722A-4F48-86E5-C2AE6E0B9C9A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{497767A1-722A-4F48-86E5-C2AE6E0B9C9A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {E792B7A8-715B-485D-AB55-1DC957C988CF}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
Loading…
Reference in New Issue
Block a user