use ellip::ellipf;
use ellip_plot_graph::*;
use plotly::{
Layout, Plot, Surface,
common::{ColorScale, ColorScalePalette},
layout::{Annotation, AspectRatio, Axis, Camera, CameraCenter, Eye, LayoutScene},
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let n_points_m = 50;
let n_points_s2p = 50;
let range_m = [-1.0, 1.0];
let range_s2p = [0.0, 0.45];
let mut m: Vec<f64> = (0..n_points_m)
.map(|i| range_m[0] + i as f64 * (range_m[1] - range_m[0]) / (n_points_m - 1) as f64)
.collect();
let mut s2p: Vec<f64> = (0..n_points_s2p)
.map(|i| {
range_s2p[0] + i as f64 * (range_s2p[1] - range_s2p[0]) / (n_points_s2p - 1) as f64
})
.collect();
let n_points_dense = 500;
m.extend(
(0..n_points_dense)
.map(|i| 1.0 + i as f64 * (2.0 - 1.0) / (n_points_dense - 1) as f64)
.collect::<Vec<f64>>(),
);
s2p.extend(
(0..n_points_dense)
.map(|i| 0.45 + i as f64 * (1.0 - 0.45) / (n_points_dense - 1) as f64)
.collect::<Vec<f64>>(),
);
let ellipf_values: Vec<Vec<f64>> = s2p
.iter()
.map(|&s2pi| {
m.iter()
.map(|&mj| {
let phi = s2pi.sqrt().asin();
match ellipf(phi, mj) {
Ok(ans) => ans,
Err(_) => f64::NAN,
}
})
.collect()
})
.collect();
let trace = Surface::new(ellipf_values)
.x(m)
.y(s2p)
.name("F(φ,m)")
.color_scale(ColorScale::Palette(ColorScalePalette::Viridis))
.cmin(0.0)
.cmax(3.5);
let mut plot = Plot::new();
plot.add_trace(trace);
plot.set_layout(
Layout::new()
.title("Incomplete Elliptic Integral of the First Kind (F)")
.width(800)
.height(600)
.scene(
LayoutScene::new()
.x_axis(Axis::new().title("m").show_line(true))
.y_axis(
Axis::new()
.title("sin²φ")
.show_line(true)
)
.z_axis(
Axis::new()
.title("F(φ,m)")
.show_line(true)
.range(vec![0.0, 3.5]),
)
.aspect_ratio(AspectRatio::new().x(1.0).y(1.0))
.camera(
Camera::new().center(
CameraCenter::from((-0.041131071416140454, -0.08695975070301684, -0.19929655677619))
)
.eye(Eye::from((1.1978498070818442, -1.3810218675157693, 0.6951800446329962)))
)
)
.legend(
plotly::layout::Legend::new()
.x(1.0)
.x_anchor(plotly::common::Anchor::Right)
)
.annotations(vec![Annotation::new()
.text(format!(
"Generated using <a href=\"https://docs.rs/ellip/latest/ellip/legendre/fn.ellipf.html\" target=\"_blank\">ellipf</a> from <a href=\"https://crates.io/crates/ellip\" target=\"_blank\">ellip</a> v{}",
ellip_version()
))
.x_ref("paper")
.y_ref("paper")
.y(-0.15)
.x(1.08)
.show_arrow(false)]),
);
make_html!(plot, "ellipf_3d.html");
write_svg!(plot, "ellipf_3d.svg", 800, 600, 1.0);
Ok(())
}