-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
109 lines (92 loc) · 5.05 KB
/
Copy pathProgram.cs
File metadata and controls
109 lines (92 loc) · 5.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace rt
{
public static class Program
{
public static void Main(string[] args)
{
// Cleanup
const string frames = "frames";
if (Directory.Exists(frames))
{
var d = new DirectoryInfo(frames);
foreach (var file in d.EnumerateFiles("*.png")) {
file.Delete();
}
}
Directory.CreateDirectory(frames);
// Scene
var geometries = new Geometry[]
{
new Ellipsoid(new Vector( 0.0, -25.0, 100.0), new Vector(1.0, 1.0, 1.0), 5.0, Color.WHITE),
new Ellipsoid(new Vector( 15.0, -25.0, 100.0), new Vector(2.0, 0.5, 0.5), 5.0, Color.RED),
new Ellipsoid(new Vector( 35.0, -25.0, 100.0), new Vector(2.0, 0.5, 0.5), 5.0, Color.RED),
new Ellipsoid(new Vector( 55.0, -25.0, 100.0), new Vector(2.0, 0.5, 0.5), 5.0, Color.RED),
new Ellipsoid(new Vector( 0.0, -10.0, 100.0), new Vector(0.5, 2.0, 0.5), 5.0, Color.GREEN),
new Ellipsoid(new Vector( 0.0, 10.0, 100.0), new Vector(0.5, 2.0, 0.5), 5.0, Color.GREEN),
new Ellipsoid(new Vector( 0.0, 30.0, 100.0), new Vector(0.5, 2.0, 0.5), 5.0, Color.GREEN),
new Ellipsoid(new Vector( 0.0, -25.0, 115.0), new Vector(0.5, 0.5, 2.0), 5.0, Color.BLUE),
new Ellipsoid(new Vector( 0.0, -25.0, 135.0), new Vector(0.5, 0.5, 2.0), 5.0, Color.BLUE),
new Ellipsoid(new Vector( 0.0, -25.0, 155.0), new Vector(0.5, 0.5, 2.0), 5.0, Color.BLUE),
new Ellipsoid(new Vector( 35.0, 10.0, 100.0), new Vector(5.0, 5.0, 0.5), 5.0, Color.YELLOW),
new Ellipsoid(new Vector( 0.0, 10.0, 135.0), new Vector(0.5, 5.0, 5.0), 5.0, Color.CYAN),
new Ellipsoid(new Vector( 35.0, -25.0, 135.0), new Vector(5.0, 0.5, 5.0), 5.0, Color.MAGENTA),
new Sphere( new Vector(-25.0, -50.0, 75.0), 25.0, Color.ORANGE),
new CtScan("ctscan/walnut.dat", "ctscan/walnut.raw", new Vector(-5.0, -20.0, 105.0), 0.2,
new ColorMap()
.Add(1, 1, new Color(0.36, 0.26, 0.16, 0.1))
.Add(2, 2, new Color(0.87, 0.72, 0.52, 0.8))
),
};
var lights = new []
{
new Light(new Vector( 65.0, 40.0, 90.0), new Color(0.8, 0.8, 0.8, 1.0), new Color(0.8, 0.8, 0.8, 1.0), new Color(0.8, 0.8, 0.8, 1.0), 1.0),
new Light(new Vector(-10.0, 40.0, 165.0), new Color(0.8, 0.8, 0.8, 1.0), new Color(0.8, 0.8, 0.8, 1.0), new Color(0.8, 0.8, 0.8, 1.0), 1.0),
new Light(new Vector( 65.0, -35.0, 165.0), new Color(0.8, 0.8, 0.8, 1.0), new Color(0.8, 0.8, 0.8, 1.0), new Color(0.8, 0.8, 0.8, 1.0), 1.0),
new Light(new Vector( 65.0, 40.0, 165.0), new Color(0.8, 0.8, 0.8, 1.0), new Color(0.8, 0.8, 0.8, 1.0), new Color(0.8, 0.8, 0.8, 1.0), 1.0)
};
const int width = 800;
const int height = 600;
// Go around an approximate middle of the scene and generate frames
var middle = new Vector(0.0, -5.0, 100.0);
var up = new Vector(0, -1, 0).Normalize();
var first = new Vector(0, 0, 1).Normalize();
const double dist = 95.0;
const int n = 90;
const double step = 360.0 / n;
var tasks = new Task[n];
for (var i = 0; i < n; i++)
{
var ind = new[]{i};
tasks[i] = Task.Run(() =>
{
var k = ind[0];
var a = (step * k) * Math.PI / 180.0;
var ellipsoidRotation = Quaternion.FromAxisAngle(a, new Vector(1, 1, 1).Normalize());
var ca = Math.Cos(a);
var sa = Math.Sin(a);
var dir = first * ca + (up ^ first) * sa + up * (up * first) * (1.0 - ca);
var camera = new Camera(
middle - dir * dist,
dir,
up,
65.0,
160.0,
120.0,
0.0,
1000.0
);
var rotatedGeometries = geometries.Select(g => g is not Ellipsoid e ? g : new Ellipsoid(e) {Rotation = ellipsoidRotation}).ToArray();
var filename = frames+"/" + $"{k + 1:000}" + ".png";
var rt = new RayTracer(rotatedGeometries, lights);
rt.Render(camera, width, height, filename);
Console.WriteLine($"Frame {k+1}/{n} completed");
});
}
Task.WaitAll(tasks);
}
}
}