use std::f64::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_4};
use ellip::el3;
use ellip_plot_graph::*;
use plotly::{
Layout, Plot, Scatter,
color::NamedColor,
common::{Anchor, Line, Mode},
layout::{Annotation, Axis, Legend},
};
macro_rules! get_trace {
($x: expr, $kc: expr, $p: expr, $name: expr) => {{
let value = $kc
.iter()
.map(|&kci| match el3($x, kci, $p) {
Ok(ans) => ans,
Err(_) => f64::NAN,
})
.collect();
Scatter::new($kc.clone(), value)
.mode(Mode::Lines)
.name($name)
}};
($x: expr, $kc: expr, $p: expr, $name: expr, $line_color: expr) => {
get_trace!($x, $kc, $p, $name).line(Line::new().color($line_color))
};
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let n_points = 100;
let range_kc = [-3, 3];
let mut kc: Vec<f64> = [
(range_kc[0] * n_points..=range_kc[1] * n_points)
.map(|x| x as f64 / n_points as f64)
.collect(),
(-5..5)
.map(|x| x as f64 / 500.0)
.skip(1)
.collect::<Vec<f64>>(),
]
.concat();
kc.sort_by(|a, b| a.partial_cmp(b).unwrap());
let mut plot = Plot::new();
plot.add_traces(vec![
get_trace!(
FRAC_PI_2.tan(),
&kc,
2.0,
"x=tan(π/2), p=2",
NamedColor::Red
)
.legend_group("p=2")
.legend_group_title("p=2"),
get_trace!(FRAC_PI_3.tan(), &kc, 2.0, "x=tan(π/3), p=2").legend_group("p=2"),
get_trace!(FRAC_PI_4.tan(), &kc, 2.0, "x=tan(π/4), p=2").legend_group("p=2"),
]);
let n_points_neg = 35;
let range_kc_neg_p = [-1, 1];
let mut kc_neg_p: Vec<f64> = [
(range_kc_neg_p[0] * n_points_neg..=range_kc_neg_p[1] * n_points_neg)
.map(|x| x as f64 / n_points_neg as f64)
.collect(),
(-5..5)
.map(|x| x as f64 / 500.0)
.skip(1)
.collect::<Vec<f64>>(),
]
.concat();
kc_neg_p.sort_by(|a, b| a.partial_cmp(b).unwrap());
plot.add_traces(vec![
get_trace!(
FRAC_PI_4.tan(),
&kc_neg_p,
-2.0,
"x=tan(π/4), p=-2",
NamedColor::Purple
)
.legend_group("p=-2")
.legend_group_title("p=-2"),
get_trace!(
FRAC_PI_3.tan(),
&kc_neg_p,
-2.0,
"x=tan(π/3), p=-2",
NamedColor::DarkViolet
)
.legend_group("p=-2"),
get_trace!(
FRAC_PI_2.tan(),
&kc_neg_p,
-2.0,
"x=tan(π/2), p=-2",
NamedColor::Blue
)
.legend_group("p=-2"),
]);
plot.set_layout(
Layout::new()
.title("Bulirsch's Incomplete Elliptic Integral of the Third Kind (el3)")
.x_axis(Axis::new().title("kc").show_line(true))
.y_axis(
Axis::new()
.title("el3(x,kc,p)")
.show_line(true)
.range(vec![-5.0, 5.0]),
).legend(Legend::new().y_anchor(Anchor::Middle).y(0.5))
.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/bulirsch/fn.el3.html\" target=\"_blank\">el3</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, "el3.html");
write_svg!(plot, "el3.svg", 1000, 600, 1.0);
Ok(())
}