Fixed mandelbrot
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
use core::{
|
use core::{
|
||||||
arch::asm,
|
arch::asm,
|
||||||
ops::{Add, Mul},
|
ops::{Add, Mul, Sub},
|
||||||
};
|
};
|
||||||
|
|
||||||
use fpga_lib::{
|
use fpga_lib::{
|
||||||
@@ -18,11 +18,72 @@ pub const ITERATIONS: usize = 100;
|
|||||||
pub const ASPECT_RATIO: f32 = WIDTH as f32 / HEIGHT as f32;
|
pub const ASPECT_RATIO: f32 = WIDTH as f32 / HEIGHT as f32;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
struct Complex(Float, Float);
|
struct Complex(Q3x29, Q3x29);
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
struct Q3x29(i32);
|
||||||
|
|
||||||
|
impl From<f32> for Q3x29
|
||||||
|
{
|
||||||
|
fn from(x: f32) -> Q3x29
|
||||||
|
{
|
||||||
|
const SCALE: f32 = 16.0;
|
||||||
|
const MAX_Q28_4: f32 = (u32::MAX as f32) / SCALE;
|
||||||
|
|
||||||
|
let clamped = x.clamp(0.0, MAX_Q28_4);
|
||||||
|
let scaled = clamped * SCALE;
|
||||||
|
|
||||||
|
Q3x29(scaled as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<f64> for Q3x29
|
||||||
|
{
|
||||||
|
fn from(x: f64) -> Q3x29
|
||||||
|
{
|
||||||
|
const SCALE: f64 = 16.0;
|
||||||
|
const MAX_Q28_4: f64 = (u32::MAX as f64) / SCALE;
|
||||||
|
|
||||||
|
let clamped = x.clamp(0.0, MAX_Q28_4);
|
||||||
|
let scaled = clamped * SCALE;
|
||||||
|
|
||||||
|
Q3x29(scaled as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add for Q3x29
|
||||||
|
{
|
||||||
|
type Output = Q3x29;
|
||||||
|
|
||||||
|
fn add(self, rhs: Self) -> Self::Output
|
||||||
|
{
|
||||||
|
Q3x29(self.0 + rhs.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub for Q3x29
|
||||||
|
{
|
||||||
|
type Output = Q3x29;
|
||||||
|
|
||||||
|
fn sub(self, rhs: Self) -> Self::Output
|
||||||
|
{
|
||||||
|
Q3x29(self.0 - rhs.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul for Q3x29
|
||||||
|
{
|
||||||
|
type Output = Q3x29;
|
||||||
|
|
||||||
|
fn mul(self, rhs: Self) -> Self::Output
|
||||||
|
{
|
||||||
|
let prod: i64 = self.0 as i64 * rhs.0 as i64;
|
||||||
|
Q3x29(((prod >> 28) & 0xFFFFFFFF) as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
impl Complex
|
impl Complex
|
||||||
{
|
{
|
||||||
pub fn sq_mag(&self) -> Float
|
pub fn sq_mag(&self) -> Q3x29
|
||||||
{
|
{
|
||||||
self.0 * self.0 + self.1 * self.1
|
self.0 * self.0 + self.1 * self.1
|
||||||
}
|
}
|
||||||
@@ -63,49 +124,42 @@ pub extern "C" fn main() -> !
|
|||||||
for i in 0..(ITERATIONS - 1)
|
for i in 0..(ITERATIONS - 1)
|
||||||
{
|
{
|
||||||
let val = ((i as Float / ITERATIONS as Float) * 255.) as u8;
|
let val = ((i as Float / ITERATIONS as Float) * 255.) as u8;
|
||||||
tab[i] = Color::from_rgb(val, val, val);
|
//tab[i] = Color::from_rgb(val, val, val);
|
||||||
|
tab[i] = Color(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
tab
|
tab
|
||||||
};
|
};
|
||||||
|
|
||||||
let width = 2.;
|
let zoom_int = 1;
|
||||||
|
let zoom = Q3x29::from(1. / zoom_int as f32);
|
||||||
for x in 0..WIDTH
|
for x in 0..WIDTH
|
||||||
{
|
{
|
||||||
for y in 0..HEIGHT
|
for y in 0..HEIGHT
|
||||||
{
|
{
|
||||||
|
// -0.761574,-0.0847596)
|
||||||
let pos = Complex(
|
let pos = Complex(
|
||||||
map(
|
Q3x29((x as i32 - WIDTH as i32 / 2) * (0x1FFFFFFF / WIDTH as i32)) * zoom
|
||||||
x as Float,
|
- Q3x29::from(0.761574),
|
||||||
0.,
|
Q3x29((y as i32 - HEIGHT as i32 / 2) * (0x1FFFFFFF / WIDTH as i32)) * zoom
|
||||||
WIDTH as Float,
|
- Q3x29::from(0.0847596),
|
||||||
-width * ASPECT_RATIO * 0.5,
|
|
||||||
width * ASPECT_RATIO * 0.5,
|
|
||||||
) - 0.5,
|
|
||||||
map(y as Float, 0., HEIGHT as Float, -width * 0.5, width * 0.5),
|
|
||||||
);
|
);
|
||||||
let mut acc = pos;
|
let mut acc = pos;
|
||||||
let mut iter = 0;
|
let mut iter = 0;
|
||||||
|
|
||||||
// Optimisations
|
|
||||||
let p = ((pos.0 - 0.25) * (pos.0 - 0.25)) + pos.1 * pos.1;
|
|
||||||
if (pos.0 < libm::sqrtf(p) - 2. * p + 0.25)
|
|
||||||
|| (pos.0 + 1.) * (pos.0 + 1.) + pos.1 * pos.1 < 1. / 16.
|
|
||||||
{
|
|
||||||
iter = ITERATIONS - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for i in 0..ITERATIONS
|
for i in 0..ITERATIONS
|
||||||
{
|
{
|
||||||
acc = acc * acc + pos;
|
//acc = acc * acc + pos;
|
||||||
if acc.sq_mag() > 1.
|
acc = Complex(
|
||||||
|
pos.0 + acc.0 * acc.0 - acc.1 * acc.1,
|
||||||
|
pos.1 + Q3x29::from(2.) * acc.1 * acc.0,
|
||||||
|
);
|
||||||
|
if acc.sq_mag().0 > Q3x29::from(3.8).0
|
||||||
{
|
{
|
||||||
iter = i;
|
iter = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
VGA::write_pixel_unsafe(x as u16, y as u16, color_lut[iter]);
|
VGA::write_pixel_unsafe(x as u16, y as u16, color_lut[iter]);
|
||||||
|
|||||||
Reference in New Issue
Block a user