feat: 实现椭圆功能
This commit is contained in:
@@ -653,6 +653,73 @@ impl MSCanvas {
|
|||||||
self.bezier(points);
|
self.bezier(points);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ellipse(&mut self, center: Point, rx: f32, ry: f32) {
|
||||||
|
let mut x = 0.0;
|
||||||
|
let mut y = ry; // 初始时将y设置为半高
|
||||||
|
|
||||||
|
// 计算初始决策参数
|
||||||
|
let mut decision = ry * ry - rx * rx * ry + rx * rx / 4.0;
|
||||||
|
|
||||||
|
while ry * ry * x < rx * rx * y {
|
||||||
|
// 在每个阶段,根据对称性绘制四个方向上的点
|
||||||
|
self.draw_pixel_at(Point::new(center.x + x, center.y + y));
|
||||||
|
self.draw_pixel_at(Point::new(center.x - x, center.y + y));
|
||||||
|
self.draw_pixel_at(Point::new(center.x + x, center.y - y));
|
||||||
|
self.draw_pixel_at(Point::new(center.x - x, center.y - y));
|
||||||
|
|
||||||
|
if decision < 0.0 {
|
||||||
|
x += 1.0;
|
||||||
|
decision += 2.0 * ry * ry * x + ry * ry;
|
||||||
|
} else {
|
||||||
|
x += 1.0;
|
||||||
|
y -= 1.0;
|
||||||
|
decision += 2.0 * ry * ry * x - 2.0 * rx * rx * y + ry * ry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
decision =
|
||||||
|
ry * ry * (x + 0.5) * (x + 0.5) + rx * rx * (y - 1.0) * (y - 1.0) - rx * rx * ry * ry;
|
||||||
|
|
||||||
|
while y > 0.0 {
|
||||||
|
// 同样地,根据对称性绘制四个方向上的点
|
||||||
|
self.draw_pixel_at(Point::new(center.x + x, center.y + y));
|
||||||
|
self.draw_pixel_at(Point::new(center.x - x, center.y + y));
|
||||||
|
self.draw_pixel_at(Point::new(center.x + x, center.y - y));
|
||||||
|
self.draw_pixel_at(Point::new(center.x - x, center.y - y));
|
||||||
|
|
||||||
|
if decision > 0.0 {
|
||||||
|
y -= 1.0;
|
||||||
|
decision += rx * rx - 2.0 * rx * rx * y;
|
||||||
|
} else {
|
||||||
|
x += 1.0;
|
||||||
|
y -= 1.0;
|
||||||
|
decision += 2.0 * ry * ry * x - 2.0 * rx * rx * y + rx * rx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ellipse1(&mut self, p1: Point, p2: Point) {
|
||||||
|
let mut rx = (p2.x - p1.x) / 2.0;
|
||||||
|
let mut ry = (p2.y - p1.y) / 2.0;
|
||||||
|
if rx > 0.0 && ry > 0.0 {
|
||||||
|
let center = Point::new(p1.x + rx, p1.y + ry);
|
||||||
|
self.ellipse(center, rx, ry);
|
||||||
|
} else if rx < 0.0 && ry < 0.0 {
|
||||||
|
rx = -rx;
|
||||||
|
ry = -ry;
|
||||||
|
let center = Point::new(p1.x - rx, p1.y - ry);
|
||||||
|
self.ellipse(center, rx, ry);
|
||||||
|
} else if ry < 0.0 {
|
||||||
|
ry = -ry;
|
||||||
|
let center = Point::new(p1.x + rx, p1.y - ry);
|
||||||
|
self.ellipse(center, rx, ry);
|
||||||
|
} else {
|
||||||
|
rx = -rx;
|
||||||
|
let center = Point::new(p1.x - rx, p1.y + ry);
|
||||||
|
self.ellipse(center, rx, ry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn begin_path(&mut self) {
|
pub fn begin_path(&mut self) {
|
||||||
self.path2d = Path2D::new();
|
self.path2d = Path2D::new();
|
||||||
}
|
}
|
||||||
|
|||||||
25
src/paint.rs
25
src/paint.rs
@@ -447,6 +447,9 @@ impl PaintApp {
|
|||||||
Tool::Polygon => {
|
Tool::Polygon => {
|
||||||
self.update_with_polygon(message);
|
self.update_with_polygon(message);
|
||||||
}
|
}
|
||||||
|
Tool::Ellipse => {
|
||||||
|
self.update_with_ellipse(message);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -794,6 +797,28 @@ impl PaintApp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_with_ellipse(&mut self, message: Message) {
|
||||||
|
match message {
|
||||||
|
Message::MousePressed(pos) => {
|
||||||
|
self.is_drawing = true;
|
||||||
|
self.canvas.save_pixels();
|
||||||
|
self.begin_point = pos;
|
||||||
|
}
|
||||||
|
Message::MouseReleased(pos) => {
|
||||||
|
self.is_drawing = false;
|
||||||
|
self.begin_point = pos;
|
||||||
|
}
|
||||||
|
Message::MouseMoved(pos) => {
|
||||||
|
if self.is_drawing {
|
||||||
|
self.canvas.restore_pixels();
|
||||||
|
self.canvas.ellipse1(self.begin_point, pos);
|
||||||
|
self.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
pub fn update_tool_states(&mut self, tool: Tool) {
|
pub fn update_tool_states(&mut self, tool: Tool) {
|
||||||
|
|||||||
Reference in New Issue
Block a user