Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

polar/cartesian poitns and mars function #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
@@ -2,11 +2,26 @@ use {
argh::FromArgs,
conjure::{event_loop, lang, shape::CsgFunc},
log::info,
nalgebra::DMatrix,
notify::{watcher, RecursiveMode, Watcher},
std::{path::PathBuf, sync::mpsc::channel, sync::Arc, time::Duration},
winit::{event_loop::EventLoop, platform::unix::WindowBuilderExtUnix, window::WindowBuilder},
};

mod camera;
mod dual_contour;
mod event_loop;
mod lang;
mod model;
mod octree;
mod render_state;
mod shape;
mod texture;
mod types;
mod util;

mod mars;

#[derive(FromArgs)]
/// Conjure shapes.
pub struct Arguments {
@@ -31,7 +46,11 @@ fn eval_ast(input: PathBuf) -> Result<conjure::lang::Ty, Box<dyn std::error::Err
// Parse
let tokens = lang::Reader::read_str(&contents)?;
let env = lang::Env::new();
let core_ns = lang::Namespace::new();
let mut core_ns = lang::Namespace::new();

core_ns.add_function("mars", |_li| Ok(crate::lang::Ty::CsgFunc(mars::mars_func())));

// Add namespace to environment
for (sym, func) in core_ns.into_iter() {
env.register_sym(sym, func);
}
@@ -42,6 +61,15 @@ fn eval_ast(input: PathBuf) -> Result<conjure::lang::Ty, Box<dyn std::error::Err
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
let latlng = mars::Polar::new(-10.0, 359.0, 30.0);
dbg!(&latlng);
let xyz: mars::Cartesian = latlng.into();
dbg!(&xyz);
let nlatlng: mars::Polar = xyz.into();
dbg!(&nlatlng);

return Ok(());

env_logger::init();
info!("starting up");

100 changes: 100 additions & 0 deletions src/mars.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use {
crate::{lang::Ty, CsgFunc},
nalgebra::DMatrix,
std::f32::consts::PI,
};

const PIXELS_PER_DEGREE: usize = 16;
const DEGREE_PER_POINT: f32 = 1.0 / PIXELS_PER_DEGREE as f32; // 0.0625 degrees
const LINES: usize = 2880;
const LINE_SAMPLES: usize = 5760;

#[derive(Debug)]
pub struct Polar {
latitude: f32,
longitude: f32,
height: f32,
}

#[derive(Debug)]
pub struct Cartesian {
x: f32,
y: f32,
z: f32,
}

impl Cartesian {
pub fn new(x: f32, y: f32, z: f32) -> Self {
Cartesian { x, y, z }
}
}

impl Polar {
pub fn new(latitude: f32, longitude: f32, height: f32) -> Self {
// Safety checks to ensure our coordinate system is set up properly.
// The standard trigonometry functions assume radians.
assert!(latitude >= -90.0);
assert!(latitude <= 90.0);
assert!(longitude >= 0.0);
assert!(longitude <= 360.0);
Polar { latitude, longitude, height }
}
}

impl From<Cartesian> for Polar {
fn from(coord: Cartesian) -> Polar {
let r = ((coord.x * coord.x) + (coord.y * coord.y) + (coord.z * coord.z)).sqrt();
let phi = (coord.z / r).acos();
let mut theta: f32 = (coord.y / coord.x).atan();
if coord.x < 0.0 && coord.y >= 0.0 && theta == 0.0 {
theta = PI;
} else if coord.x < 0.0 && coord.y < 0.0 && theta.signum() > 0.0 {
theta += PI;
} else if coord.x > 0.0 && coord.y < 0.0 && theta.signum() < 0.0 {
theta += 2.0 * PI;
} else if coord.x < 0.0 && coord.y > 0.0 && theta.signum() < 0.0 {
theta += PI;
}
Polar::new(phi.to_degrees() - 90.0, theta.to_degrees(), r)
}
}

impl From<Polar> for Cartesian {
fn from(coord: Polar) -> Cartesian {
let phi = (coord.latitude + 90.0).to_radians();
//let phi = (coord.latitude).to_radians();
let theta = coord.longitude.to_radians();
let h = coord.height; // + MARS_RADIUS as f64;

let x = h * theta.cos() * phi.sin();
let y = h * theta.sin() * phi.sin();
let z = h * phi.cos();
Cartesian { x, y, z }
}
}

type TerrainData = DMatrix<i16>;
pub fn mars_func() -> CsgFunc {
// Read the file directly into a buffer.
let fin = std::fs::read("megt90n000eb.img").unwrap();

// Read the file two bytes at a time, converting the big endian values into host endian.
let raw_data: Vec<i16> =
fin.chunks_exact(2).into_iter().map(|x| i16::from_be_bytes([x[0], x[1]])).collect();

let mars_data: TerrainData = TerrainData::from_row_slice(LINES, LINE_SAMPLES, &raw_data);
CsgFunc::new(Box::new(move |x: f32, y: f32, z: f32| {
let latlng: Polar = Cartesian::new(x, y, z).into();
0.0
//let r = ((x * x) + (y * y) + (z * z)).sqrt();
//let theta = y.atan2(x);
//let phi = (z / r).acos();
//let radius = 33960.0;
//let lng_idx = (theta / DEGREE_PER_POINT) as usize;
//let lat_idx = (phi / DEGREE_PER_POINT) as usize;
//let r: f32 =
// (((0.0 - z) * (0.0 - z)) + ((0.0 - x) * (0.0 - x)) + ((0.0 - y) * (0.0 - y))).sqrt();
//let m = mars_data[(LINES - lat_idx - 1, lng_idx)] as f32;
//r - ((m * 2.0) + radius)
}))
}