Определение позиции дочернего объекта
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
const std = @import("std");
|
||||
const dvui = @import("dvui");
|
||||
const basic_models = @import("../../models/basic_models.zig");
|
||||
const Document = @import("../../models/Document.zig");
|
||||
const Point2_f = basic_models.Point2_f;
|
||||
const Point2_i = basic_models.Point2_i;
|
||||
const Scale2_f = basic_models.Scale2_f;
|
||||
@@ -14,6 +15,19 @@ pub const Transform = struct {
|
||||
scale: Scale2_f = .{},
|
||||
opacity: f32 = 1.0,
|
||||
|
||||
pub fn init(obj: *const Document.Object) Transform {
|
||||
const pos = if (obj.getProperty(.position)) |p| p.position else Point2_f{ .x = 0, .y = 0 };
|
||||
const angle = if (obj.getProperty(.angle)) |p| p.angle else 0;
|
||||
const scale = if (obj.getProperty(.scale)) |p| p.scale else Scale2_f{ .scale_x = 1, .scale_y = 1 };
|
||||
const opacity = if (obj.getProperty(.opacity)) |p| p.opacity else 1.0;
|
||||
return .{
|
||||
.position = pos,
|
||||
.angle = angle,
|
||||
.scale = scale,
|
||||
.opacity = opacity,
|
||||
};
|
||||
}
|
||||
|
||||
/// Композиция: world = parent * local.
|
||||
pub fn compose(parent: Transform, local: Transform) Transform {
|
||||
const cos_a = std.math.cos(parent.angle);
|
||||
@@ -36,6 +50,20 @@ pub const Transform = struct {
|
||||
}
|
||||
};
|
||||
|
||||
/// Мировые -> локальные для заданного трансформа.
|
||||
pub fn worldToLocalTransform(t: Transform, wx: f32, wy: f32) Point2_f {
|
||||
const dx = wx - t.position.x;
|
||||
const dy = wy - t.position.y;
|
||||
const cos_a = std.math.cos(-t.angle);
|
||||
const sin_a = std.math.sin(-t.angle);
|
||||
const sx = if (t.scale.scale_x != 0) t.scale.scale_x else 1.0;
|
||||
const sy = if (t.scale.scale_y != 0) t.scale.scale_y else 1.0;
|
||||
return .{
|
||||
.x = (dx * cos_a - dy * sin_a) / sx,
|
||||
.y = (dx * sin_a + dy * cos_a) / sy,
|
||||
};
|
||||
}
|
||||
|
||||
/// Конвейер отрисовки: локальные координаты -> трансформ -> буфер.
|
||||
pub const DrawContext = struct {
|
||||
pixels: []Color.PMA,
|
||||
@@ -100,17 +128,7 @@ pub const DrawContext = struct {
|
||||
|
||||
/// Мировые -> локальные.
|
||||
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;
|
||||
const cos_a = std.math.cos(-t.angle);
|
||||
const sin_a = std.math.sin(-t.angle);
|
||||
const sx = if (t.scale.scale_x != 0) t.scale.scale_x else 1.0;
|
||||
const sy = if (t.scale.scale_y != 0) t.scale.scale_y else 1.0;
|
||||
return .{
|
||||
.x = (dx * cos_a - dy * sin_a) / sx,
|
||||
.y = (dx * sin_a + dy * cos_a) / sy,
|
||||
};
|
||||
return worldToLocalTransform(self.transform, wx, wy);
|
||||
}
|
||||
|
||||
/// Смешивает цвет в пикселе буфера с учётом opacity трансформа. В replace_mode просто перезаписывает пиксель.
|
||||
|
||||
Reference in New Issue
Block a user