Skip to content

Instantly share code, notes, and snippets.

@ironon
Created March 13, 2025 01:48
Show Gist options
  • Save ironon/e31b99e1a4ed9cf50015cd4502bf9694 to your computer and use it in GitHub Desktop.
Save ironon/e31b99e1a4ed9cf50015cd4502bf9694 to your computer and use it in GitHub Desktop.
Basic 3d Render in Rust by David Macpherson
// i was bored on a plane ride and didn't know what to do so i tried my best to make a 3d renderer
// (i had no knowledge of how 3d renders worked, just tried to use my linear algebra skills to derive it out)
use std::{thread, time};
fn paraboloid(x: f32, y: f32) -> f32{
(x*x) + (y*y)
}
fn parabola(t: f32) -> Vec<f32> {
vec![0.0, t, t*t]
}
fn y_axis(t: f32) -> Vec<f32>{
return vec![0.0, t, 0.0]
}
fn z_axis(t: f32) -> Vec<f32>{
return vec![0.0, 0.0, t]
}
fn x_axis(t: f32) -> Vec<f32>{
return vec![t, 0.0, 0.0]
}
pub fn dot(v1: &Vec<f32>, v2: &Vec<f32>) -> f32 {
*v1.get(0).unwrap()**v2.get(0).unwrap() + *v1.get(1).unwrap()**v2.get(1).unwrap() + *v1.get(2).unwrap()**v2.get(2).unwrap()
}
fn map(position: Vec<f32>, ihat: &Vec<f32>, jhat: &Vec<f32>) -> Vec<f32> {
return vec![dot(&position, ihat), dot(&position, jhat)]
}
fn calculateForAngle(angle: &f32) {
let ihat = vec![f32::cos(*angle), f32::sin(*angle), 0.0];
let jhat: Vec<f32> = vec![0.0, 0.5, f32::sqrt(3.0)/2.0];
let points: Vec<Vec<f32>> = vec![vec![1.0,1.0,1.0],vec![-1.0,2.0,3.0]];
let mut new_points: Vec<Vec<f32>> = Vec::new();
for point in points {
// new_points.push(map(point, &ihat, &jhat));
}
let mut c = -35.0;
let cMax = 35.0;
while (c < cMax) {
c += 0.2;
new_points.push(map(y_axis(c), &ihat, &jhat));
new_points.push(map(x_axis(c), &ihat, &jhat));
new_points.push(map(z_axis(c), &ihat, &jhat));
new_points.push(map(parabola(c), &ihat, &jhat));
}
display_points(new_points);
}
pub fn basic_renderer() {
let mut angle: f32 = 0.0;
let t = time::Duration::from_millis(200);
let mut counter = 0;
let counterMax = 45;
while counter < counterMax {
counter += 1;
calculateForAngle(&angle);
angle = angle + 0.4;
thread::sleep(t);
}
}
fn display_points(new_points: Vec<Vec<f32>>) {
let x_width = 10.0;
let y_width = 10.0;
let mut y_counter = -y_width;
let mut final_string = String::new();
while y_counter < y_width {
let mut x_counter = -x_width;
while x_counter < x_width {
let mut pushed = false;
for point in new_points.iter() {
if x_counter == f32::round(*point.get(0).unwrap()) && y_counter == f32::floor(*point.get(1).unwrap()) {
final_string.push_str("*");
pushed = true;
break;
} else if x_counter == 0.0 && y_counter == 0.0 {
final_string.push_str("X");
pushed = true;
break;
}
}
if !pushed {
final_string.push_str(" ")
}
x_counter = x_counter + 1.0
}
final_string.push_str("\n");
y_counter = y_counter + 1.0
}
println!("{:}", final_string);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment