Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
2
Task/Death-Star/Zig/death-star-1.zig
Normal file
2
Task/Death-Star/Zig/death-star-1.zig
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
29
Task/Death-Star/Zig/death-star-2.zig
Normal file
29
Task/Death-Star/Zig/death-star-2.zig
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
pub fn main() !void {
|
||||
// buffer stdout --------------------------------------
|
||||
const stdout_file = std.io.getStdOut().writer();
|
||||
var bw = std.io.bufferedWriter(stdout_file);
|
||||
const stdout = bw.writer();
|
||||
|
||||
// allocator ------------------------------------------
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer {
|
||||
const ok = gpa.deinit();
|
||||
std.debug.assert(ok == .ok);
|
||||
}
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
// deathstar ------------------------------------------
|
||||
var dstar = try DeathStar(f32).init(allocator);
|
||||
defer dstar.deinit();
|
||||
|
||||
// print deathstar PGM to stdout ----------------------
|
||||
const comments = [_][]const u8{
|
||||
"Rosetta Code",
|
||||
"DeathStar",
|
||||
"https://rosettacode.org/wiki/Death_Star",
|
||||
};
|
||||
try dstar.print(stdout, comments[0..]);
|
||||
|
||||
// ----------------------------------------------------
|
||||
try bw.flush();
|
||||
}
|
||||
27
Task/Death-Star/Zig/death-star-3.zig
Normal file
27
Task/Death-Star/Zig/death-star-3.zig
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
fn Vector(comptime T: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
x: T,
|
||||
y: T,
|
||||
z: T,
|
||||
|
||||
pub fn init(x: T, y: T, z: T) Self {
|
||||
return Self{ .x = x, .y = y, .z = z };
|
||||
}
|
||||
pub fn zero() Self {
|
||||
return Self{ .x = 0.0, .y = 0.0, .z = 0.0 };
|
||||
}
|
||||
fn dot(a: *const Self, b: *const Self) T {
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
fn length(self: *const Self) T {
|
||||
return std.math.sqrt(self.dot(self));
|
||||
}
|
||||
pub fn normalize(self: *Self) void {
|
||||
const inv_length = 1 / self.length();
|
||||
self.*.x *= inv_length;
|
||||
self.*.y *= inv_length;
|
||||
self.*.z *= inv_length;
|
||||
}
|
||||
};
|
||||
}
|
||||
3
Task/Death-Star/Zig/death-star-4.zig
Normal file
3
Task/Death-Star/Zig/death-star-4.zig
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fn SphereHit(comptime T: type) type {
|
||||
return struct { z1: T, z2: T };
|
||||
}
|
||||
25
Task/Death-Star/Zig/death-star-5.zig
Normal file
25
Task/Death-Star/Zig/death-star-5.zig
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
fn Sphere(comptime T: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
cx: T,
|
||||
cy: T,
|
||||
cz: T,
|
||||
r: T,
|
||||
|
||||
pub fn init(cx: T, cy: T, cz: T, r: T) Self {
|
||||
return Self{ .cx = cx, .cy = cy, .cz = cz, .r = r };
|
||||
}
|
||||
/// Check if a ray (x,y, -inf)->(x, y, inf) hits a sphere.
|
||||
/// If so, return the intersecting z values. z1 is closer to the eye.
|
||||
pub fn hit(self: *const Self, xx: T, yy: T) ?SphereHit(T) {
|
||||
const x = xx - self.cx;
|
||||
const y = yy - self.cy;
|
||||
var zsq = self.r * self.r - x * x - y * y;
|
||||
if (zsq >= 0) {
|
||||
var zsqrt = std.math.sqrt(zsq);
|
||||
return .{ .z1 = self.cz - zsqrt, .z2 = self.cz + zsqrt };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
101
Task/Death-Star/Zig/death-star-6.zig
Normal file
101
Task/Death-Star/Zig/death-star-6.zig
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
fn DeathStar(comptime T: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
allocator: Allocator,
|
||||
w: usize,
|
||||
h: usize,
|
||||
img: ImageData(),
|
||||
|
||||
const Hit = enum { background, neg, pos };
|
||||
|
||||
pub fn init(allocator: Allocator) !Self {
|
||||
var dir = Vector(T).init(20, -40, 10);
|
||||
dir.normalize();
|
||||
// positive sphere and negative sphere
|
||||
const pos = Sphere(T).init(180, 240, 220, 120);
|
||||
const neg = Sphere(T).init(60, 150, 100, 100);
|
||||
|
||||
const k: T = 1.5;
|
||||
const amb: T = 0.2;
|
||||
|
||||
var w: usize = @intFromFloat(pos.r * 4);
|
||||
var h: usize = @intFromFloat(pos.r * 3);
|
||||
var img = try ImageData().init(allocator, "deathStar", w, h);
|
||||
|
||||
var vec = Vector(T).zero();
|
||||
|
||||
const start_y: usize = @intFromFloat(pos.cy - pos.r);
|
||||
const end_y: usize = @intFromFloat(pos.cy + pos.r);
|
||||
const start_x: usize = @intFromFloat(pos.cx - pos.r);
|
||||
const end_x: usize = @intFromFloat(pos.cx + pos.r);
|
||||
|
||||
for (start_y..end_y + 1) |j| {
|
||||
for (start_x..end_x + 1) |i| {
|
||||
const x: T = @floatFromInt(i);
|
||||
const y: T = @floatFromInt(j);
|
||||
|
||||
const result_pos = pos.hit(x, y);
|
||||
// ray lands in blank space, show bg
|
||||
if (result_pos == null)
|
||||
continue;
|
||||
|
||||
const zb1 = result_pos.?.z1;
|
||||
const zb2 = result_pos.?.z2;
|
||||
|
||||
const result_neg = neg.hit(x, y);
|
||||
|
||||
switch (calcHit(result_neg, zb1, zb2)) {
|
||||
.background => continue,
|
||||
.neg => {
|
||||
vec.x = neg.cx - x;
|
||||
vec.y = neg.cy - y;
|
||||
vec.z = neg.cz - result_neg.?.z2; // zs2
|
||||
},
|
||||
.pos => {
|
||||
vec.x = x - pos.cx;
|
||||
vec.y = y - pos.cy;
|
||||
vec.z = zb1 - pos.cz;
|
||||
},
|
||||
}
|
||||
vec.normalize();
|
||||
var s = dir.dot(&vec);
|
||||
if (s < 0) s = 0;
|
||||
const lum = 255 * (std.math.pow(T, s, k) + amb) / (1 + amb);
|
||||
const lumi: u8 = @intFromFloat(std.math.clamp(lum, 0, 255));
|
||||
img.pset(i, j, Gray{ .w = lumi });
|
||||
}
|
||||
}
|
||||
return Self{ .allocator = allocator, .w = w, .h = h, .img = img };
|
||||
}
|
||||
pub fn deinit(self: *Self) void {
|
||||
self.img.deinit();
|
||||
}
|
||||
pub fn print(self: *Self, writer: anytype, optional_comments: ?[]const []const u8) !void {
|
||||
try self.img.print(writer, optional_comments);
|
||||
}
|
||||
/// Ray has hit the positive sphere.
|
||||
/// How does it intersect the negative sphere ?
|
||||
fn calcHit(neg_hit: ?SphereHit(T), zb1: T, zb2: T) Hit {
|
||||
if (neg_hit) |result| {
|
||||
const zs1 = result.z1;
|
||||
const zs2 = result.z2;
|
||||
if (zs1 > zb1) {
|
||||
// ray hits both, but pos front surface is closer
|
||||
return Hit.pos;
|
||||
} else if (zs2 > zb2) {
|
||||
// pos sphere surface is inside neg sphere, show bg
|
||||
return Hit.background;
|
||||
} else if (zs2 > zb1) {
|
||||
// back surface on neg sphere is inside pos sphere,
|
||||
// the only place where neg sphere surface will be shown
|
||||
return Hit.neg;
|
||||
} else {
|
||||
return Hit.pos;
|
||||
}
|
||||
} else {
|
||||
// ray hits pos sphere but not neg, draw pos sphere surface
|
||||
return Hit.pos;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
4
Task/Death-Star/Zig/death-star-7.zig
Normal file
4
Task/Death-Star/Zig/death-star-7.zig
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
const Gray = struct {
|
||||
w: u8,
|
||||
const black = Gray{ .w = 0 };
|
||||
};
|
||||
39
Task/Death-Star/Zig/death-star-8.zig
Normal file
39
Task/Death-Star/Zig/death-star-8.zig
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
fn ImageData() type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
allocator: Allocator,
|
||||
name: []const u8,
|
||||
w: usize,
|
||||
h: usize,
|
||||
image: []Gray,
|
||||
|
||||
pub fn init(allocator: Allocator, name: []const u8, w: usize, h: usize) !Self {
|
||||
const image = try allocator.alloc(Gray, h * w);
|
||||
// black background fill
|
||||
for (image) |*pixel| pixel.* = Gray.black;
|
||||
return Self{ .allocator = allocator, .image = image, .name = name, .w = w, .h = h };
|
||||
}
|
||||
pub fn deinit(self: *Self) void {
|
||||
self.allocator.free(self.image);
|
||||
}
|
||||
pub fn pset(self: *Self, x: usize, y: usize, gray: Gray) void {
|
||||
self.image[x * self.w + y] = gray;
|
||||
}
|
||||
/// Write PGM P2 ASCII to 'writer'
|
||||
pub fn print(self: *const Self, writer: anytype, optional_comments: ?[]const []const u8) !void {
|
||||
_ = try writer.print("P2\n", .{});
|
||||
|
||||
if (optional_comments) |lines| {
|
||||
for (lines) |line|
|
||||
_ = try writer.print("# {s}\n", .{line});
|
||||
}
|
||||
|
||||
_ = try writer.print("{d} {d}\n{d}\n", .{ self.w, self.h, 255 });
|
||||
|
||||
for (self.image, 0..) |pixel, i| {
|
||||
const sep = if (i % self.w == self.w - 1) "\n" else " ";
|
||||
_ = try writer.print("{d}{s}", .{ pixel.w, sep });
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue