Небольшое упрощение
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const std_math = std.math;
|
||||||
const Document = @import("../../models/Document.zig");
|
const Document = @import("../../models/Document.zig");
|
||||||
const pipeline = @import("pipeline.zig");
|
const pipeline = @import("pipeline.zig");
|
||||||
const DrawContext = pipeline.DrawContext;
|
const DrawContext = pipeline.DrawContext;
|
||||||
@@ -10,8 +11,6 @@ const Object = Document.Object;
|
|||||||
const default_stroke: Color.PMA = .{ .r = 0, .g = 0, .b = 0, .a = 255 };
|
const default_stroke: Color.PMA = .{ .r = 0, .g = 0, .b = 0, .a = 255 };
|
||||||
const default_thickness: f32 = 2.0;
|
const default_thickness: f32 = 2.0;
|
||||||
|
|
||||||
const std_math = std.math;
|
|
||||||
|
|
||||||
/// Эллипс с центром (0,0) и полуосями radii. Обводка — полоса расстояния до контура (чёткая линия, не круги).
|
/// Эллипс с центром (0,0) и полуосями radii. Обводка — полоса расстояния до контура (чёткая линия, не круги).
|
||||||
/// arc_percent: 100 — полный эллипс, иначе одна дуга; обход в коде от (0,ry) по квадрантам (визуально может казаться от низа против часовой из‑за экранной Y).
|
/// arc_percent: 100 — полный эллипс, иначе одна дуга; обход в коде от (0,ry) по квадрантам (визуально может казаться от низа против часовой из‑за экранной Y).
|
||||||
/// Отрисовка в отдельный буфер и один composite, чтобы при alpha<255 пиксели не накладывались несколько раз.
|
/// Отрисовка в отдельный буфер и один composite, чтобы при alpha<255 пиксели не накладывались несколько раз.
|
||||||
@@ -23,10 +22,7 @@ pub fn draw(ctx: *DrawContext, obj: *const Object, allocator: std.mem.Allocator)
|
|||||||
|
|
||||||
const stroke = if (obj.getProperty(.stroke_rgba)) |s| pipeline.rgbaToPma(s.stroke_rgba) else default_stroke;
|
const stroke = if (obj.getProperty(.stroke_rgba)) |s| pipeline.rgbaToPma(s.stroke_rgba) else default_stroke;
|
||||||
const thickness = if (obj.getProperty(.thickness)) |t| t.thickness else default_thickness;
|
const thickness = if (obj.getProperty(.thickness)) |t| t.thickness else default_thickness;
|
||||||
const arc_percent = blk: {
|
const arc_percent = std_math.clamp(if (obj.getProperty(.arc_percent)) |p| p.arc_percent else 100.0, 0.0, 100.0);
|
||||||
const p = obj.getProperty(.arc_percent);
|
|
||||||
break :blk std.math.clamp(if (p) |v| v.arc_percent else 100.0, 0.0, 100.0);
|
|
||||||
};
|
|
||||||
|
|
||||||
const t = &ctx.transform;
|
const t = &ctx.transform;
|
||||||
const min_r = @min(rx, ry);
|
const min_r = @min(rx, ry);
|
||||||
@@ -43,19 +39,11 @@ pub fn draw(ctx: *DrawContext, obj: *const Object, allocator: std.mem.Allocator)
|
|||||||
.{ .x = rx * margin, .y = ry * margin },
|
.{ .x = rx * margin, .y = ry * margin },
|
||||||
.{ .x = -rx * margin, .y = ry * margin },
|
.{ .x = -rx * margin, .y = ry * margin },
|
||||||
};
|
};
|
||||||
var min_bx: f32 = undefined;
|
var min_bx: f32 = std_math.inf(f32);
|
||||||
var min_by: f32 = undefined;
|
var min_by: f32 = std_math.inf(f32);
|
||||||
var max_bx: f32 = undefined;
|
var max_bx: f32 = -std_math.inf(f32);
|
||||||
var max_by: f32 = undefined;
|
var max_by: f32 = -std_math.inf(f32);
|
||||||
{
|
for (corners) |c| {
|
||||||
const w0 = ctx.localToWorld(corners[0].x, corners[0].y);
|
|
||||||
const b0 = ctx.worldToBufferF(w0.x, w0.y);
|
|
||||||
min_bx = b0.x;
|
|
||||||
min_by = b0.y;
|
|
||||||
max_bx = b0.x;
|
|
||||||
max_by = b0.y;
|
|
||||||
}
|
|
||||||
for (corners[1..]) |c| {
|
|
||||||
const w = ctx.localToWorld(c.x, c.y);
|
const w = ctx.localToWorld(c.x, c.y);
|
||||||
const b = ctx.worldToBufferF(w.x, w.y);
|
const b = ctx.worldToBufferF(w.x, w.y);
|
||||||
min_bx = @min(min_bx, b.x);
|
min_bx = @min(min_bx, b.x);
|
||||||
@@ -80,10 +68,7 @@ pub fn draw(ctx: *DrawContext, obj: *const Object, allocator: std.mem.Allocator)
|
|||||||
|
|
||||||
const inv_rx = 1.0 / rx;
|
const inv_rx = 1.0 / rx;
|
||||||
const inv_ry = 1.0 / ry;
|
const inv_ry = 1.0 / ry;
|
||||||
const arc_full = arc_percent >= 100.0;
|
const arc_len = 2.0 * std_math.pi * arc_percent / 100.0;
|
||||||
const t_start = std_math.pi / 2.0;
|
|
||||||
const t_end_raw = t_start - 2.0 * std_math.pi * arc_percent / 100.0;
|
|
||||||
const t_end = if (t_end_raw <= -std_math.pi) t_end_raw + 2.0 * std_math.pi else t_end_raw;
|
|
||||||
|
|
||||||
var by: i32 = y0;
|
var by: i32 = y0;
|
||||||
while (by < y1) : (by += 1) {
|
while (by < y1) : (by += 1) {
|
||||||
@@ -97,13 +82,10 @@ pub fn draw(ctx: *DrawContext, obj: *const Object, allocator: std.mem.Allocator)
|
|||||||
const ny = loc.y * inv_ry;
|
const ny = loc.y * inv_ry;
|
||||||
const d = nx * nx + ny * ny;
|
const d = nx * nx + ny * ny;
|
||||||
if (d < d_inner_sq or d > d_outer_sq) continue;
|
if (d < d_inner_sq or d > d_outer_sq) continue;
|
||||||
if (!arc_full) {
|
if (arc_percent < 100.0) {
|
||||||
const t_pt = std_math.atan2(ny, nx);
|
var diff = std_math.pi / 2.0 - std_math.atan2(ny, nx);
|
||||||
const in_arc = if (t_end <= t_start)
|
if (diff < 0) diff += 2.0 * std_math.pi;
|
||||||
(t_pt >= t_end and t_pt <= t_start)
|
if (diff > arc_len) continue;
|
||||||
else
|
|
||||||
(t_pt >= t_end or t_pt <= t_start);
|
|
||||||
if (!in_arc) continue;
|
|
||||||
}
|
}
|
||||||
stroke_ctx.blendPixelAtBuffer(bx, by, stroke);
|
stroke_ctx.blendPixelAtBuffer(bx, by, stroke);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user