feat: 实现椭圆功能
This commit is contained in:
@@ -653,6 +653,73 @@ impl MSCanvas {
|
||||
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) {
|
||||
self.path2d = Path2D::new();
|
||||
}
|
||||
|
||||
25
src/paint.rs
25
src/paint.rs
@@ -447,6 +447,9 @@ impl PaintApp {
|
||||
Tool::Polygon => {
|
||||
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
|
||||
|
||||
pub fn update_tool_states(&mut self, tool: Tool) {
|
||||
|
||||
Reference in New Issue
Block a user