use maria_linalg::{
Matrix,
Vector,
};
use super::PlottableElement;
#[derive(Clone, Copy, Debug)]
pub struct Element {
pub one: usize,
pub two: usize,
oneloc: Vector<2>,
twoloc: Vector<2>,
pub stiffness: Matrix<4>,
pub direction: Vector<2>,
pub length: f64,
}
impl Element {
pub fn zero() -> Self {
Self {
one: 0,
two: 0,
oneloc: Vector::zero(),
twoloc: Vector::zero(),
stiffness: Matrix::zero(),
direction: Vector::zero(),
length: 0.0,
}
}
pub fn new(
one: usize,
oneloc: Vector<2>,
two: usize,
twoloc: Vector<2>,
) -> Self {
let r = twoloc - oneloc;
let length = r.norm();
let direction = r.scale(1.0 / length);
let ex = Vector::new([1.0, 0.0]);
let ey = Vector::new([0.0, 1.0]);
let opposite = r.dot(ey);
let adjacent = r.dot(ex);
let hypotenuse = (opposite.powf(2.0) + adjacent.powf(2.0)).sqrt();
let c = adjacent / hypotenuse;
let s = opposite / hypotenuse;
let stiffness = Matrix::new([
[ c * c, c * s, - c * c, - c * s],
[ c * s, s * s, - c * s, - s * s],
[- c * c, - c * s, c * c, c * s],
[- c * s, - s * s, c * s, s * s],
]).scale(1.0 / length);
Self {
one,
two,
oneloc,
twoloc,
stiffness,
direction,
length,
}
}
pub fn to_plottable(
&self,
top: f64,
left: f64,
width: f64,
height: f64,
stress: f64,
maxstress: f64,
area: f64,
maxarea: f64,
) -> PlottableElement {
PlottableElement {
x1: ((self.oneloc[0] - left) / width) as f32,
x2: ((self.oneloc[1] - left) / width) as f32,
y1: ((height - self.twoloc[0] + top) / height) as f32,
y2: ((height - self.twoloc[1] + top) / height) as f32,
stress: (stress / maxstress) as f32,
thickness: (area / maxarea).sqrt() as f32,
}
}
}