Skip to content

Instantly share code, notes, and snippets.

@keisukefukuda
Created September 3, 2019 08:39
Show Gist options
  • Save keisukefukuda/479a03dd716cb2a8d165b6d531cc39fe to your computer and use it in GitHub Desktop.
Save keisukefukuda/479a03dd716cb2a8d165b6d531cc39fe to your computer and use it in GitHub Desktop.
use std::ops;
#[derive(Debug,Copy,Clone)]
struct Vec3 {
e: [f32; 3]
}
#[allow(dead_code)]
impl Vec3 {
pub fn new(e1: f32, e2: f32, e3: f32) -> Vec3 {
Vec3 { e: [e1, e2, e3] }
}
pub fn x(&self) -> f32 { self.e[0] }
pub fn y(&self) -> f32 { self.e[1] }
pub fn z(&self) -> f32 { self.e[2] }
pub fn r(&self) -> f32 { self.e[0] }
pub fn g(&self) -> f32 { self.e[1] }
pub fn b(&self) -> f32 { self.e[2] }
pub fn length(&self) -> f32 { (self.e[0] * self.e[0] + self.e[1] * self.e[1] + self.e[2] * self.e[2]).sqrt() }
pub fn squared_length(&self) -> f32 { self.e[0] * self.e[0] + self.e[1] * self.e[1] + self.e[2] * self.e[2] }
pub fn make_unit_vector(&mut self) {
let k = 1.0 / self.length();
*self = Vec3 { e: [self.e[0] * k, self.e[1] * k, self.e[2] * k]}
}
}
fn dot(a: &Vec3, b: &Vec3) -> f32 {
a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
}
fn unit_vector(vec: &Vec3) -> Vec3 {
vec / vec.length()
}
impl<'a> ops::Add for &'a Vec3 {
type Output = Vec3;
fn add(self, _rhs: &Vec3) -> Vec3 {
Vec3::new(self.e[0] + _rhs.e[0], self.e[1] + _rhs.e[1], self.e[2] + _rhs.e[2])
}
}
impl<'a> ops::AddAssign<&'a Vec3> for Vec3 {
fn add_assign(&mut self, rhs: &'a Vec3) {
*self = Vec3 { e: [self.e[0] + rhs.e[0], self.e[1] + rhs.e[1], self.e[2] + rhs.e[2]] };
}
}
impl<'a> ops::Sub for &'a Vec3 {
type Output = Vec3;
fn sub(self, _rhs: &'a Vec3) -> Vec3 {
Vec3::new(self.e[0] - _rhs.e[0], self.e[1] - _rhs.e[1], self.e[2] - _rhs.e[2])
}
}
impl<'a> ops::Mul for &'a Vec3 {
type Output = Vec3;
fn mul(self, _rhs: &'a Vec3) -> Vec3 {
Vec3::new(self.e[0] * _rhs.e[0], self.e[1] * _rhs.e[1], self.e[2] * _rhs.e[2])
}
}
impl ops::Mul<f32> for Vec3 {
type Output = Vec3;
fn mul(self, t: f32) -> Vec3 {
Vec3::new(self.e[0] * t, self.e[1] * t, self.e[2] * t)
}
}
impl<'a> ops::MulAssign<&'a Vec3> for Vec3 {
fn mul_assign(&mut self, rhs: &'a Vec3) {
*self = Vec3 { e: [self.e[0] * rhs.e[0], self.e[1] * rhs.e[1], self.e[2] * rhs.e[2]] };
}
}
impl ops::MulAssign<f32> for Vec3 {
fn mul_assign(&mut self, v: f32) {
*self = Vec3 { e: [self.e[0] * v, self.e[1] * v, self.e[2] * v] };
}
}
impl<'a> ops::Div<f32> for &'a Vec3 {
type Output = Vec3;
fn div(self, v: f32) -> Vec3 {
Vec3::new(self.e[0] / v, self.e[1] / v, self.e[2] / v)
}
}
impl ops::Index<usize> for Vec3 {
type Output = f32;
fn index<'a>(&'a self, idx: usize) -> &'a f32 {
&self.e[idx]
}
}
struct Ray {
a: Vec3,
b: Vec3,
}
impl Ray {
pub fn new(t: &Vec3, s: &Vec3) -> Ray {
Ray { a: Vec3::new(t[0], t[1], t[2]), b: Vec3::new(s[0], s[1], s[2]) }
}
pub fn origin(&self) -> Vec3 {
self.a.clone()
}
pub fn direction(&self) -> Vec3 {
self.b.clone()
}
pub fn point_at_parameter(&self, t: f32) -> Vec3 {
&self.a + &(self.b * t)
}
}
fn main() {
let nx: i32 = 200;
let ny: i32 = 100;
println!("P3");
println!("{} {} 255", nx, ny);
for j in (0..ny).rev() {
for i in 0..nx {
let x = (i as f32) / (nx as f32);
let y = (j as f32) / (ny as f32);
let z = 0.2;
let col = Vec3::new(x, y, z);
let ir = (255.99 * col[0]) as i32;
let ig = (255.99 * col[1]) as i32;
let ib = (255.99 * col[2]) as i32;
println!("{} {} {}", ir, ig, ib);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment