1
0

Add project files.

This commit is contained in:
Rokas Puzonas 2023-02-11 14:37:41 +02:00
parent 94d3b0421f
commit 9797b3c6f5
7 changed files with 569 additions and 0 deletions

5
Lab1/BMP File Format.url Normal file
View 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

Binary file not shown.

359
Lab1/BMPImage.cs Normal file
View 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
View 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
View 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
View 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
View 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