feat: Добавил толщину линий, унифицировал геометрию
Переименовал основные геометрические модели (Point, Size, Rect, Scale, Radii), явно разделив их на типы с плавающей точкой (_f) и целочисленные (_i). Обновил использование этих типов во всем проекте для улучшения типобезопасности и ясности. Ввел новое свойство thickness для объектов и реализовал его применение при отрисовке линий и ломаных. Добавил Point2_i для целочисленных координат буфера в конвейере отрисовки.
This commit is contained in:
@@ -1,16 +1,17 @@
|
||||
const std = @import("std");
|
||||
const dvui = @import("dvui");
|
||||
const basic_models = @import("../../models/basic_models.zig");
|
||||
const Point2 = basic_models.Point2;
|
||||
const Scale2 = basic_models.Scale2;
|
||||
const ImageRect = basic_models.ImageRect;
|
||||
const Point2_f = basic_models.Point2_f;
|
||||
const Point2_i = basic_models.Point2_i;
|
||||
const Scale2_f = basic_models.Scale2_f;
|
||||
const Rect_i = basic_models.Rect_i;
|
||||
const Color = dvui.Color;
|
||||
|
||||
/// Трансформ объекта в мировых координатах документа (позиция, угол, масштаб, непрозрачность).
|
||||
pub const Transform = struct {
|
||||
position: Point2 = .{},
|
||||
position: Point2_f = .{},
|
||||
angle: f32 = 0,
|
||||
scale: Scale2 = .{},
|
||||
scale: Scale2_f = .{},
|
||||
opacity: f32 = 1.0,
|
||||
|
||||
/// Композиция: мировой трансформ = parent * local (local в пространстве родителя).
|
||||
@@ -41,7 +42,7 @@ pub const DrawContext = struct {
|
||||
pixels: []Color.PMA,
|
||||
buf_width: u32,
|
||||
buf_height: u32,
|
||||
visible_rect: ImageRect,
|
||||
visible_rect: Rect_i,
|
||||
scale_x: f32,
|
||||
scale_y: f32,
|
||||
transform: Transform = .{},
|
||||
@@ -51,7 +52,7 @@ pub const DrawContext = struct {
|
||||
}
|
||||
|
||||
/// Локальные координаты фигуры -> мировые (документ).
|
||||
pub fn localToWorld(self: *const DrawContext, local_x: f32, local_y: f32) Point2 {
|
||||
pub fn localToWorld(self: *const DrawContext, local_x: f32, local_y: f32) Point2_f {
|
||||
const t = &self.transform;
|
||||
const cos_a = std.math.cos(t.angle);
|
||||
const sin_a = std.math.sin(t.angle);
|
||||
@@ -61,8 +62,8 @@ pub const DrawContext = struct {
|
||||
};
|
||||
}
|
||||
|
||||
/// Мировые координаты документа -> координаты в буфере (могут быть вне [0, buf_w] x [0, buf_h]).
|
||||
pub fn worldToBufferF(self: *const DrawContext, wx: f32, wy: f32) Point2 {
|
||||
/// Мировые координаты документа -> координаты в буфере (float; могут быть вне [0, buf_w] x [0, buf_h]).
|
||||
pub fn worldToBufferF(self: *const DrawContext, wx: f32, wy: f32) Point2_f {
|
||||
const canvas_x = wx * self.scale_x;
|
||||
const canvas_y = wy * self.scale_y;
|
||||
const vx = @as(f32, @floatFromInt(self.visible_rect.x));
|
||||
@@ -73,8 +74,17 @@ pub const DrawContext = struct {
|
||||
};
|
||||
}
|
||||
|
||||
/// Мировые координаты документа -> целочисленные координаты в буфере (округление до ближайшего пикселя).
|
||||
pub fn worldToBuffer(self: *const DrawContext, wx: f32, wy: f32) Point2_i {
|
||||
const b = self.worldToBufferF(wx, wy);
|
||||
return .{
|
||||
.x = @intFromFloat(std.math.round(b.x)),
|
||||
.y = @intFromFloat(std.math.round(b.y)),
|
||||
};
|
||||
}
|
||||
|
||||
/// Координаты буфера -> мировые (документ). scale_x/scale_y не должны быть 0.
|
||||
pub fn bufferToWorld(self: *const DrawContext, buf_x: f32, buf_y: f32) Point2 {
|
||||
pub fn bufferToWorld(self: *const DrawContext, buf_x: f32, buf_y: f32) Point2_f {
|
||||
const vx = @as(f32, @floatFromInt(self.visible_rect.x));
|
||||
const vy = @as(f32, @floatFromInt(self.visible_rect.y));
|
||||
const canvas_x = buf_x + vx;
|
||||
@@ -88,7 +98,7 @@ pub const DrawContext = struct {
|
||||
}
|
||||
|
||||
/// Мировые координаты -> локальные фигуры (обратное к localToWorld).
|
||||
pub fn worldToLocal(self: *const DrawContext, wx: f32, wy: f32) Point2 {
|
||||
pub fn worldToLocal(self: *const DrawContext, wx: f32, wy: f32) Point2_f {
|
||||
const t = &self.transform;
|
||||
const dx = wx - t.position.x;
|
||||
const dy = wy - t.position.y;
|
||||
|
||||
Reference in New Issue
Block a user