Implement bounding box function for bezier-rs (#726)
* Implement bounding box function for bezier-rs * Fix eslint errors Co-authored-by: Linda Zheng <linda-zheng@users.noreply.github.com> * Rename bbox to bounding_box * Address Keavon's comments * Fix eslint issue Co-authored-by: Hannah Li <hannahli2010@gmail.com> Co-authored-by: Linda Zheng <linda-zheng@users.noreply.github.com>
This commit is contained in:
parent
4ebdd1abb1
commit
c05c93c8a2
|
|
@ -356,6 +356,19 @@ export default defineComponent({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Bounding Box",
|
||||||
|
callback: (canvas: HTMLCanvasElement, bezier: WasmBezierInstance): void => {
|
||||||
|
const context = getContextFromCanvas(canvas);
|
||||||
|
const bboxPoints: Point[] = JSON.parse(bezier.bounding_box());
|
||||||
|
const minPoint = bboxPoints[0];
|
||||||
|
const maxPoint = bboxPoints[1];
|
||||||
|
drawLine(context, minPoint, { x: minPoint.x, y: maxPoint.y }, COLORS.NON_INTERACTIVE.STROKE_1);
|
||||||
|
drawLine(context, minPoint, { x: maxPoint.x, y: minPoint.y }, COLORS.NON_INTERACTIVE.STROKE_1);
|
||||||
|
drawLine(context, maxPoint, { x: minPoint.x, y: maxPoint.y }, COLORS.NON_INTERACTIVE.STROKE_1);
|
||||||
|
drawLine(context, maxPoint, { x: maxPoint.x, y: minPoint.y }, COLORS.NON_INTERACTIVE.STROKE_1);
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
subpathFeatures: [
|
subpathFeatures: [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,16 @@ impl WasmBezier {
|
||||||
to_js_value(local_extrema)
|
to_js_value(local_extrema)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn de_casteljau_points(&self, t: f64) -> JsValue {
|
||||||
|
let hull = self
|
||||||
|
.0
|
||||||
|
.de_casteljau_points(t)
|
||||||
|
.iter()
|
||||||
|
.map(|level| level.iter().map(|&point| Point { x: point.x, y: point.y }).collect::<Vec<Point>>())
|
||||||
|
.collect::<Vec<Vec<Point>>>();
|
||||||
|
to_js_value(hull)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn rotate(&self, angle: f64) -> WasmBezier {
|
pub fn rotate(&self, angle: f64) -> WasmBezier {
|
||||||
WasmBezier(self.0.rotate(angle))
|
WasmBezier(self.0.rotate(angle))
|
||||||
}
|
}
|
||||||
|
|
@ -142,13 +152,8 @@ impl WasmBezier {
|
||||||
to_js_value(bezier_points)
|
to_js_value(bezier_points)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn de_casteljau_points(&self, t: f64) -> JsValue {
|
pub fn bounding_box(&self) -> JsValue {
|
||||||
let hull = self
|
let bbox_points: [Point; 2] = self.0.bounding_box().map(|p| Point { x: p.x, y: p.y });
|
||||||
.0
|
to_js_value(bbox_points)
|
||||||
.de_casteljau_points(t)
|
|
||||||
.iter()
|
|
||||||
.map(|level| level.iter().map(|&point| Point { x: point.x, y: point.y }).collect::<Vec<Point>>())
|
|
||||||
.collect::<Vec<Vec<Point>>>();
|
|
||||||
to_js_value(hull)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -773,6 +773,26 @@ impl Bezier {
|
||||||
});
|
});
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the min and max corners that represent the bounding box of the curve.
|
||||||
|
pub fn bounding_box(&self) -> [DVec2; 2] {
|
||||||
|
// Start by taking min/max of endpoints.
|
||||||
|
let mut endpoints_min = self.start.min(self.end);
|
||||||
|
let mut endpoints_max = self.start.max(self.end);
|
||||||
|
|
||||||
|
// Iterate through extrema points.
|
||||||
|
let extrema = self.local_extrema();
|
||||||
|
for t_values in extrema {
|
||||||
|
for t in t_values {
|
||||||
|
let point = self.evaluate(t);
|
||||||
|
// Update bounding box if new min/max is found.
|
||||||
|
endpoints_min = endpoints_min.min(point);
|
||||||
|
endpoints_max = endpoints_max.max(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[endpoints_min, endpoints_max]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue