use std::ops::Range;
pub fn split_by_radius(x: f32, y: f32, w: f32, h: f32, radius: f32, segment: Option<usize>) -> (Vec<f32>, Vec<u16>) {
let points: Vec<f32>;
let mut indices: Vec<u16> = Vec::new();
let point_len: usize = 2;
match segment {
Some(lv) => {
points = split_by_radius_with_level(x, y, w, h, radius, scale_level(lv as u16));
},
None => {
points = split_by_radius_0(x, y, w, h, radius);
},
}
let mut index = 0;
let count = points.len() / point_len;
while index < count {
indices.push(index as u16);
index = index + 1;
}
(points, indices)
}
pub fn split_by_radius_border(x: f32, y: f32, w: f32, h: f32, radius: f32, border: f32, segment: Option<usize>) -> (Vec<f32>, Vec<u16>) {
match segment {
Some(lv) => {
split_by_radius_border_with_level(x, y, w, h, radius, border, scale_level(lv as u16))
},
None => {
split_by_radius_border_0(x, y, w, h, radius, border)
},
}
}
pub fn split_by_lg(result: &mut PolygonIndices, positions: &mut Vec<f32>, attrs: &mut [Attribute], indices: &[u16], lg_pos: &[f32], start: (f32, f32), end: (f32, f32)) -> PolygonSlice {
let index_start = result.indices.len();
let count_start = result.counts.len();
split_by_lg_0(result, positions, attrs, indices, lg_pos, start, end);
PolygonSlice {
start: index_start,
range: count_start..result.counts.len(),
}
}
pub fn split_mult_by_lg(result: &mut PolygonIndices, positions: &mut Vec<f32>, attrs: &mut [Attribute], indices: &PolygonIndices, indices_slice: PolygonSlice, lg_pos: &[f32], start: (f32, f32), end: (f32, f32)) {
let a: &[usize] = &indices.counts[indices_slice.range];
let mut index_start = indices_slice.start;
for i in a.iter() {
split_by_lg(result, positions, attrs, &indices.indices[index_start..index_start + *i], lg_pos, start, end);
index_start += *i;
}
}
pub fn interp_by_lg(positions: &[f32], indices: &[u16], attrs: &mut [&mut Vec<f32>], lg_attrs: &Vec<LgCfg>, lg_pos: &[f32], start: (f32, f32), end: (f32, f32)) {
interp_by_lg_0(positions, indices, attrs, lg_attrs, lg_pos, start, end);
}
pub fn interp_mult_by_lg(positions: &[f32], indices: &PolygonIndices, indices_slice: PolygonSlice, attrs: &mut [&mut Vec<f32>], lg_attrs: Vec<LgCfg>, lg_pos: &[f32], start: (f32, f32), end: (f32, f32)) {
let a: &[usize] = &indices.counts[indices_slice.range];
let mut index_start = indices_slice.start;
for i in a.iter() {
interp_by_lg(positions, &indices.indices[index_start..index_start + *i], attrs, &lg_attrs, lg_pos, start, end);
index_start += *i;
}
}
pub fn to_triangle(indices: &[u16], out_indices: &mut Vec<u16>) {
to_triangle_0(indices, out_indices)
}
pub fn mult_to_triangle(indices: &PolygonIndices, out_indices: &mut Vec<u16>){
let a: &[usize] = &indices.counts;
let mut index_start = 0;
for i in a.iter() {
to_triangle(&indices.indices[index_start..index_start + *i], out_indices);
index_start += *i;
}
}
pub fn find_lg_endp(polygon: &[f32], angle: f32) -> ((f32, f32), (f32, f32)) {
let direct_vec2 = get_direction_vector(angle);
let mut point_dot: Vec<f32> = Vec::new();
let point_len: usize = 2;
let count = polygon.len() / point_len;
let mut index: usize = 0;
let mut min_dot = std::f32::MAX;
let mut max_dot = std::f32::MIN;
let mut min_index = 0;
while index < count {
let x = polygon[index * point_len];
let y = polygon[index * point_len + 1];
let dot = get_dot(x, y, direct_vec2[0], direct_vec2[1]);
if dot < min_dot {
min_dot = dot;
min_index = index;
}
if max_dot < dot {
max_dot = dot;
}
point_dot.push(dot);
index = index + 1;
}
let total_dot = max_dot - min_dot;
let start_point = (float_clip(polygon[min_index * 2]) , float_clip(polygon[min_index * 2 + 1]));
let end_point = (float_clip(start_point.0 + total_dot * direct_vec2[0]) , float_clip(start_point.1 + total_dot * direct_vec2[1]));
(start_point, end_point)
}
pub fn split_by_radius_border_with_level(x: f32, y: f32, w: f32, h: f32, radius: f32, border: f32, level: u16) -> (Vec<f32>, Vec<u16>) {
let mut result: Vec<f32> = Vec::new();
let mut result2: Vec<f32> = Vec::new();
let mut result_indices: Vec<u16> = Vec::new();
let mut check_list: Vec<(f32,f32,u8)> = Vec::new();
check_list.push((x + radius, y - radius, 2));
check_list.push((x + radius, y - h + radius, 3));
check_list.push((x + w - radius, y - h + radius, 4));
check_list.push((x + w - radius, y - radius, 1));
let point_len: usize = 2;
for data in check_list {
let (_x,_y,a) = data;
let res = get_one_quarter_arc_with_level(_x, _y, radius, a, level);
let mut index = 0;
for v in res {
if index % point_len == 1 {
result.push(y + y - v);
} else {
result.push(v);
}
index = index + 1;
}
let res = get_one_quarter_arc_with_level(_x, _y, radius - border, a, level);
index = 0;
for v in res {
if index % point_len == 1 {
result2.push(y + y - v);
} else {
result2.push(v);
}
index = index + 1;
}
}
let count = result.len() / point_len;
let mut temp_index: usize = 0;
while temp_index < count - 1 {
let mut indices = Vec::new();
to_triangle_0(&[
(temp_index) as u16,
(temp_index + 1) as u16,
(count + temp_index + 1) as u16,
(count + temp_index) as u16
], &mut indices);
result_indices.extend_from_slice(&indices);
temp_index = temp_index + 1;
}
let mut indices = Vec::new();
to_triangle_0(&[
(count - 1) as u16,
(0) as u16,
(count + 0) as u16,
(count + count - 1) as u16
], &mut indices);
result_indices.extend_from_slice(&indices);
result.extend_from_slice(&result2);
(result, result_indices)
}
pub fn split_by_radius_border_0(x: f32, y: f32, w: f32, h: f32, radius: f32, border: f32) -> (Vec<f32>, Vec<u16>) {
let mut result: Vec<f32> = Vec::new();
let mut result2: Vec<f32> = Vec::new();
let mut result_indices: Vec<u16> = Vec::new();
let mut check_list: Vec<(f32,f32,u8)> = Vec::new();
check_list.push((x + radius, y - radius, 2));
check_list.push((x + radius, y - h + radius, 3));
check_list.push((x + w - radius, y - h + radius, 4));
check_list.push((x + w - radius, y - radius, 1));
let point_len: usize = 2;
for data in check_list {
let (_x,_y,a) = data;
let res = get_one_quarter_arc(_x, _y, radius, a);
let level = res.len() / point_len - 1;
let mut index = 0;
for v in res {
if index % point_len == 1 {
result.push(y + y - v);
} else {
result.push(v);
}
index = index + 1;
}
let res = get_one_quarter_arc_with_level(_x, _y, radius - border, a, level as u16);
index = 0;
for v in res {
if index % point_len == 1 {
result2.push(y + y - v);
} else {
result2.push(v);
}
index = index + 1;
}
}
let count = result.len() / point_len;
let mut temp_index: usize = 0;
while temp_index < count - 1 {
let mut indices: Vec<u16> = Vec::new();
to_triangle_0(&[
(temp_index) as u16,
(temp_index + 1) as u16,
(count + temp_index + 1) as u16,
(count + temp_index) as u16
], &mut indices);
result_indices.extend_from_slice(&indices);
temp_index = temp_index + 1;
}
let mut indices: Vec<u16> = Vec::new();
to_triangle_0(&[
(count - 1) as u16,
(0) as u16,
(count + 0) as u16,
(count + count - 1) as u16
], &mut indices);
result_indices.extend_from_slice(&indices);
result.extend_from_slice(&result2);
(result, result_indices)
}
pub fn split_by_radius_0(x: f32, y: f32, w: f32, h: f32, radius: f32) -> Point2DVec {
get_rounded_rect(x, y, w, h, radius)
}
pub fn split_by_radius_with_level(x: f32, y: f32, w: f32, h: f32, radius: f32, level: u16) -> Point2DVec {
get_rounded_rect_with_level(x, y, w, h, radius, level)
}
pub type Point3D = (f32, f32, f32);
pub type Point2D = (f32, f32);
#[derive(Debug, Default, Clone)]
pub struct PolygonIndices {
pub indices: Vec<u16>,
pub counts: Vec<usize>, }
impl PolygonIndices {
pub fn clear(&mut self) {
self.indices.clear();
self.counts.clear();
}
}
#[derive(Debug, Default, Clone)]
pub struct PolygonSlice {
pub start: usize,
pub range: Range<usize>,
}
pub struct PolygonCfg {
pub positions: Vec<f32>,
pub indices: PolygonIndices,
}
#[derive(Debug)]
pub struct Attribute<'a> {
pub unit: usize,
pub value: &'a mut Vec<f32>,
}
pub fn split_by_lg_0(
result: &mut PolygonIndices,
points: &mut Vec<f32>,
attrs: &mut [Attribute],
polygon_indices: &[u16],
lg_pos: &[f32],
start: (f32, f32),
end: (f32, f32)
) {
let _end = (end.0, -end.1);
let _start = (start.0, -start.1);
let dist_x = _end.0 - _start.0;
let dist_y = _end.1 - _start.1;
let dist = (dist_x.powi(2) + dist_y.powi(2)).sqrt();
let lg_lines: Vec<LineCfg> = line_segment_vertical_lines(&_start, &_end, lg_pos);
let pointe_len: usize = 2;
let src_points_count = points.len() / pointe_len;
let src_polygon_point_count = polygon_indices.len();
let src_lg_count = lg_pos.len();
let mut new_indices_list: Vec<u16> = Vec::new();
let mut new_dot_list: Vec<f32> = Vec::new();
let direct_vec2 = [(_end.0 - _start.0) / dist , (_end.1 - _start.1) / dist];
let mut lg_dot: Vec<f32> = Vec::new();
for percent in lg_pos {
lg_dot.push(get_dot(direct_vec2[0], direct_vec2[1], direct_vec2[0] * dist * percent, direct_vec2[1] * dist * percent));
}
let mut point0: Point2D;
let mut point1: Point2D;
let mut line0: LineCfg;
point0 = read_point_2d_f(&points, polygon_indices, src_polygon_point_count - 1);
let temp_dot = get_dot(direct_vec2[0], direct_vec2[1], point0.0 - _start.0, point0.1 - _start.1);
new_indices_list.push(polygon_indices[src_polygon_point_count - 1]);
new_dot_list.push(temp_dot);
let mut result_count: u16 = src_points_count as u16;
let mut index0 = src_polygon_point_count - 1;
let mut index1 = 0;
while index1 < src_polygon_point_count {
point1 = read_point_2d_f(&points, polygon_indices, index1);
if !(eq_f32(point0.0, point1.0) && eq_f32(point0.1, point1.1)) {
line0 = get_line_with_two_point(point0.0, point0.1, point1.0, point1.1);
if get_dot(direct_vec2[0], direct_vec2[1], point1.0 - point0.0, point1.1 - point0.1) > 0.0 {
let l_count = lg_lines.len();
let mut l_index: usize = 0;
while l_index < l_count {
let (is_get, _x, _y) = get_two_lines_intersection(line0, lg_lines[l_index]);
let has_intersect = is_get && is_between_2d(&point0, &point1, &(_x, _y));
if has_intersect {
result_count = result_count + 1;
points.extend_from_slice(&[_x, -_y]);
new_indices_list.push((result_count - 1) as u16);
new_dot_list.push(lg_dot[l_index]);
interp_attrs_by_line(attrs, polygon_indices, index0, index1, (_x, _y), point0, point1);
}
l_index = l_index + 1;
}
} else {
let l_count = lg_lines.len();
let mut l_index: usize = 0;
while l_index < l_count {
let (is_get, _x, _y) = get_two_lines_intersection(line0, lg_lines[l_count - l_index - 1]);
let has_intersect = is_get && is_between_2d(&point0, &point1, &(_x, _y));
if has_intersect {
result_count = result_count + 1;
points.extend_from_slice(&[_x, -_y]);
new_indices_list.push((result_count - 1) as u16);
new_dot_list.push(lg_dot[l_count - l_index - 1]);
interp_attrs_by_line(attrs, polygon_indices, index0, index1, (_x, _y), point0, point1);
}
l_index = l_index + 1;
}
}
}
if index1 < src_polygon_point_count - 1 {
let temp_dot = get_dot(direct_vec2[0], direct_vec2[1], point1.0 - _start.0, point1.1 - _start.1);
new_indices_list.push(polygon_indices[index1]);
new_dot_list.push(temp_dot);
}
point0 = point1;
index0 = index1;
index1 = index1 + 1;
}
let mut min_dot: f32;
let mut max_dot: f32;
let new_point_count = new_indices_list.len();
index1 = 0;
min_dot = lg_dot[index1];
let mut i_index = 0;
let new_polygon_start = result.indices.len();
while i_index < new_point_count {
if new_dot_list[i_index] <= min_dot {
result.indices.push(new_indices_list[i_index]);
}
i_index = i_index + 1;
}
let count = result.indices.len() - new_polygon_start;
if count > 2 {
result.counts.push(count);
} else {
unsafe { result.indices.set_len(new_polygon_start) } }
index1 = 0;
while index1 < src_lg_count - 1 {
min_dot = lg_dot[index1];
max_dot = lg_dot[index1 + 1];
i_index = 0;
let new_polygon_start = result.indices.len();
while i_index < new_point_count {
if min_dot <= new_dot_list[i_index] && new_dot_list[i_index] <= max_dot {
result.indices.push(new_indices_list[i_index]);
}
i_index = i_index + 1;
}
let count = result.indices.len() - new_polygon_start;
if count > 2 {
result.counts.push(count);
} else {
unsafe { result.indices.set_len(new_polygon_start) } }
index1 = index1 + 1;
}
index1 = src_lg_count - 1;
max_dot = lg_dot[index1];
let new_polygon_start = result.indices.len();
i_index = 0;
while i_index < new_point_count {
if max_dot <= new_dot_list[i_index] {
result.indices.push(new_indices_list[i_index]);
}
i_index = i_index + 1;
}
let count = result.indices.len() - new_polygon_start;
if count > 2 {
result.counts.push(count);
} else {
unsafe { result.indices.set_len(new_polygon_start) } }
}
fn interp_attrs_by_line (
attrs: &mut [Attribute],
indices: &[u16],
p0_index: usize,
p1_index: usize,
target: (f32, f32),
point0: (f32, f32),
point1: (f32, f32),
) {
if attrs.len() == 0 {
return;
}
let delta = point1.0 - point0.0;
let p0_weight = if delta.abs() < f32::EPSILON {
(target.1 - point0.1) / (point1.1 - point0.1)
} else {
(target.0 - point0.0) / (point1.0 - point0.0)
};
let p1_weight = 1.0 - p0_weight;
for attr in attrs.iter_mut() {
let index0 = indices[p0_index] as usize * attr.unit;
let index1 = indices[p1_index] as usize * attr.unit;
for i in 0..attr.unit {
let r = p1_weight * attr.value[index0 + i] + p0_weight * attr.value[index1 + i];
attr.value.push(r);
}
}
}
const EPSILON: f32 = std::f32::EPSILON * 1024.0;
#[inline]
pub fn eq_f32(v1: f32, v2: f32) -> bool { v1 == v2 || ((v2 - v1).abs() <= EPSILON) }
fn read_point_2d_f(points: &[f32], indices: &[u16], indices_index: usize) -> Point2D {
let ix = (indices[indices_index] * 2) as usize;
(points[ix + 0], -points[ix + 1])
}
fn read_point_2d(points: &[f32], indices: &[u16], indices_index: usize) -> Point2D {
let ix = (indices[indices_index] * 2) as usize;
(points[ix + 0], points[ix + 1])
}
#[derive(Debug, Clone)]
pub struct LgCfg{
pub unit: usize,
pub data: Vec<f32>,
}
pub fn interp_by_lg_0(points: &[f32], polygon_indices: &[u16], attrs: &mut [&mut Vec<f32>], lg_attrs: &Vec<LgCfg>, lg_pos: &[f32], start: (f32, f32), end: (f32, f32)) {
let dist_x = end.0 - start.0;
let dist_y = end.1 - start.1;
let dist = (dist_x.powi(2) + dist_y.powi(2)).sqrt();
let point_count = polygon_indices.len();
let lg_count = lg_pos.len();
let attr_count = lg_attrs.len();
let start_lg = lg_pos[0];
let end_lg = lg_pos[lg_count - 1];
let direct_vec2 = [(end.0 - start.0) / dist, (end.1 - start.1) / dist];
let mut point: Point2D;
let mut index = 0;
while index < point_count {
point = read_point_2d(points, polygon_indices, index);
let dot = get_dot(point.0 - start.0, point.1 - start.1, direct_vec2[0], direct_vec2[1]);
let mut attr_index: usize = 0;
let lg = dot / dist;
while attr_index < attr_count {
let src_attr = &lg_attrs[attr_index];
let pre: usize;
let nxt: usize;
let percent: f32;
if lg <= start_lg {
percent = 0.0;
pre = 0;
nxt = 1;
} else if lg >= end_lg {
percent = 1.0;
pre = lg_count - 2;
nxt = lg_count - 1;
} else {
let (_pre, _nxt) = find_pre_next_grad_direct(lg_pos, lg);
pre = _pre;
nxt = _nxt;
if pre != nxt {
percent = (lg - lg_pos[pre]) / (lg_pos[nxt] - lg_pos[pre]);
} else {
percent = 0.0;
}
}
let mut pre_attr: f32;
let mut nxt_attr: f32;
let attr_size = src_attr.unit;
let point_attr_index: u16 = (attr_size as u16) * polygon_indices[index];
let mut _cur_len = attrs[attr_index as usize].len() as u16;
let _targ_len = point_attr_index + (attr_size as u16);
while _cur_len < _targ_len {
attrs[attr_index as usize].push(0.0);
_cur_len = _cur_len + 1;
}
let mut a_index = 0;
while a_index < attr_size {
pre_attr = src_attr.data[pre * attr_size + a_index];
nxt_attr = src_attr.data[nxt * attr_size + a_index];
attrs[attr_index][point_attr_index as usize + a_index] = float_clip(pre_attr + (nxt_attr - pre_attr) * percent);
a_index = a_index + 1;
}
attr_index = attr_index + 1;
}
index = index + 1;
}
}
pub fn to_triangle_0(indices: &[u16], out_indices: &mut Vec<u16>) {
let mut index: usize = 1;
let count = indices.len();
while index <= count - 2 {
out_indices.push(indices[0]);
out_indices.push(indices[index]);
out_indices.push(indices[index + 1]);
index = index + 1;
}
}
const VEC_ARR: [f32;34] = [
1.0, 0.0,
0.9951847266721969, 0.0980171403295606,
0.9807852804032304, 0.1950903220161282,
0.9569403357322088, 0.2902846772544623,
0.9238795325112867, 0.3826834323650898,
0.881921264348355, 0.4713967368259976,
0.8314696123025452, 0.5555702330196022,
0.773010453362737, 0.6343932841636455,
0.7071067811865476, 0.7071067811865475,
0.6343932841636455, 0.7730104533627369,
0.5555702330196023, 0.8314696123025452,
0.4713967368259978, 0.8819212643483549,
0.3826834323650898, 0.9238795325112867,
0.2902846772544623, 0.9569403357322089,
0.1950903220161283, 0.9807852804032304,
0.0980171403295607, 0.9951847266721968,
0.0, 1.0
];
const RADIUS_4_8: f32 = 32.0;
const RADIUS_8_16: f32 = 128.0;
fn copy_level4() -> Vec<u16> {
vec![0,4,8,12,16]
}
fn copy_level8() -> Vec<u16> {
vec![ 0,2,4,6,8,10,12,14,16 ]
}
fn copy_level16() -> Vec<u16> {
vec![ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 ]
}
fn scale_level(mut lv: u16) -> u16 {
if lv <= 4 {
lv = 4;
} else if lv <= 8 {
lv = 8;
} else {
lv = 16;
}
lv
}
pub fn get_one_quarter_arc(center_x: f32, center_y: f32, radius: f32, area_id: u8) -> Point2DVec {
let segments: Vec<u16>;
if radius < RADIUS_4_8 {
segments = copy_level4();
} else if radius <= RADIUS_8_16 {
segments = copy_level8();
} else {
segments = copy_level16();
}
analy_one_quarter_arc(center_x, center_y, radius, area_id, &segments)
}
pub fn get_one_quarter_arc_with_level(center_x: f32, center_y: f32, radius: f32, area_id: u8, level: u16) -> Point2DVec {
let segments: Vec<u16>;
if level == 4 {
segments = copy_level4();
} else if level == 8 {
segments = copy_level8();
} else {
segments = copy_level16();
}
analy_one_quarter_arc(center_x, center_y, radius, area_id, &segments)
}
fn analy_one_quarter_arc(center_x: f32, center_y: f32, radius: f32, area_id: u8, segments: &Vec<u16>) -> Point2DVec {
let mut result_points: Vec<f32> = Vec::new();
let count = segments.len() as u16;
let mut index: u16 = 0;
let mut _index: u16 = 0;
while index <= count - 1 {
let mut x: f32;
let mut y: f32;
if area_id == 1 {
_index = index;
_index = segments[index as usize] * 2;
x = radius * VEC_ARR[(_index) as usize];
y = radius * VEC_ARR[(_index + 1) as usize];
x = center_x + x;
y = center_y + y;
} else if area_id == 2 {
_index = index;
_index = segments[index as usize] * 2;
x = - radius * VEC_ARR[(_index + 1) as usize];
y = radius * VEC_ARR[(_index) as usize];
x = center_x + x;
y = center_y + y;
} else if area_id == 3 {
_index = index;
_index = segments[index as usize] * 2;
x = - radius * VEC_ARR[(_index) as usize];
y = - radius * VEC_ARR[(_index + 1) as usize];
x = center_x + x;
y = center_y + y;
} else {
_index = index;
_index = segments[index as usize] * 2;
x = radius * VEC_ARR[(_index + 1) as usize];
y = - radius * VEC_ARR[(_index) as usize];
x = center_x + x;
y = center_y + y;
}
result_points.push(x);
result_points.push(y);
index = index + 1;
}
result_points
}
pub fn get_rounded_rect(x: f32, y: f32, w: f32, h: f32, radius: f32) -> Point2DVec {
let point_len: usize = 2;
let mut result: Vec<f32> = Vec::new();
let mut check_list: Vec<(f32,f32,u8)> = Vec::new();
check_list.push((x + radius, y - radius, 2));
check_list.push((x + radius, y - h + radius, 3));
check_list.push((x + w - radius, y - h + radius, 4));
check_list.push((x + w - radius, y - radius, 1));
for data in check_list {
let (_x,_y,a) = data;
let res = get_one_quarter_arc(_x, _y, radius, a);
let mut index = 0;
for v in res {
if index % point_len == 1 {
result.push(y + y - v);
} else {
result.push(v);
}
index = index + 1;
}
}
result
}
pub fn get_rounded_rect_with_level(x: f32, y: f32, w: f32, h: f32, radius: f32, level: u16) -> Vec<f32> {
let point_len: usize = 2;
let mut result: Vec<f32> = Vec::new();
let mut check_list: Vec<(f32,f32,u8)> = Vec::new();
check_list.push((x + radius, y - radius, 2));
check_list.push((x + radius, y - h + radius, 3));
check_list.push((x + w - radius, y - h + radius, 4));
check_list.push((x + w - radius, y - radius, 1));
for data in check_list {
let (_x,_y,a) = data;
let res = get_one_quarter_arc_with_level(_x, _y, radius, a, level);
let mut index = 0;
for v in res {
if index % point_len == 1 {
result.push(y + y - v);
} else {
result.push(v);
}
index = index + 1;
}
}
result
}
pub type LineCfg = (f32, f32, f32);
fn line_segment_vertical_lines(start_point: &(f32, f32), end_point: &(f32, f32), percents: &[f32]) -> Vec<LineCfg> {
let dist_x = end_point.0 - start_point.0;
let dist_y = end_point.1 - start_point.1;
let len = (dist_x.powi(2) + dist_y.powi(2)).sqrt();
let direct_vec2 = [ dist_x / len, dist_y / len];
let v_vec2 = get_vertical_vec2(direct_vec2);
let mut lines: Vec<LineCfg> = Vec::new();
for percent in percents {
let percent_len = len * percent;
let point = [start_point.0 + direct_vec2[0] * percent_len, start_point.1 + direct_vec2[1] * percent_len];
let line_cfg = get_line_with_direct(v_vec2, point[0], point[1]);
lines.push(line_cfg);
}
lines
}
fn get_vertical_vec2(direct_vec2: [f32;2]) -> [f32;2] {
[direct_vec2[1],-direct_vec2[0]]
}
fn get_line_with_direct(direct_vec2: [f32;2], x: f32, y: f32) -> (f32, f32, f32) {
let new_x = direct_vec2[0] + x;
let new_y = direct_vec2[1] + y;
get_line_with_two_point(x, y, new_x, new_y)
}
fn get_line_with_two_point(x0: f32, y0: f32, x1: f32, y1: f32) -> (f32, f32, f32) {
if eq_f32(x0, x1) && eq_f32(y0, y1) {
(1.0, -1.0, 0.0)
} else {
(y0 - y1, x1 - x0, x0 * y1 - y0 * x1)
}
}
fn get_two_lines_intersection(line1: LineCfg, line2: LineCfg) -> (bool, f32, f32) {
let (a0, b0, c0) = line1;
let (a1, b1, c1) = line2;
let d = a0 * b1 - a1 * b0;
let mut x = 0.0;
let mut y = 0.0;
let is_get;
if eq_f32(d, 0.0) {
if a0 * b1 == 0.0 && a0 != a1 && b0 != b1 {
if a0 == 0.0 {
is_get = true;
x = c0 / b0;
y = c1 / a1;
} else {
is_get = true;
x = c0 / a0;
y = c1 / b1;
}
} else {
is_get = false;
}
} else {
is_get = true;
x = (b0 * c1 - b1 * c0) / d;
y = (c0 * a1 - c1 * a0) / d;
}
if x.is_nan() {
x = 0.0;
}
x = float_clip(x);
y = float_clip(y);
(is_get, x, y)
}
fn get_dot(x0: f32, y0: f32, x1: f32, y1: f32) -> f32 {
float_clip(x0 * x1 + y0 * y1)
}
fn is_between(a: f32, b: f32, v: f32) -> bool {
if eq_f32(a, v) || eq_f32(b, v) {
return false;
}
if b < a {
return b < v && v <= (a + 0.0);
} else if a < b {
return (a - 0.0) <= v && v < b;
} else {
return a == v;
}
}
fn is_between_2d(point0: &(f32, f32), point1: &(f32, f32), target: &(f32, f32)) -> bool {
if eq_f32(point0.0, point1.0) {
if is_between(point0.1, point1.1, target.1) == true {
return true;
}
} else {
if is_between(point0.0, point1.0, target.0) == true {
return true;
}
}
return false;
}
fn find_pre_next_grad_direct(data_list: &[f32], value: f32) -> (usize, usize) {
let count = data_list.len();
let mut pre_index: usize = 0;
let mut nxt_index: usize = 0;
let mut index: usize = 0;
while index <= (count as usize) - 1 {
if data_list[(index) as usize] <= value {
pre_index = index;
} else {
nxt_index = index;
break;
}
nxt_index = index;
index = index + 1;
}
if pre_index == nxt_index {
pre_index = nxt_index - 1;
}
(pre_index, nxt_index)
}
fn get_direction_vector(angle: f32) -> [f32; 2] {
let _angle = angle % 360.0;
let radius = ((_angle as f32) / 180.0) * std::f32::consts::PI;
[radius.cos(), radius.sin()]
}
fn float_clip(v: f32) -> f32 {
(v * 10000.0).round() / 10000.0
}
type Point2DVec = Vec<f32>;
#[test]
fn test() {
let res = split_by_radius(0.0,0.0,50.0,50.0,5.0,Some(3));
println!("{:?}", res);
}