Get rectangle corners as triangles

This commit is contained in:
Synthasmagoria 2026-08-30 15:06:47 +02:00
commit b95b7659c3
5 changed files with 96 additions and 60 deletions

BIN
default

Binary file not shown.

View file

@ -5,6 +5,7 @@ import "core:math"
import "core:math/ease"
import "core:math/linalg"
import "core:slice"
import "core:sort"
import "core:fmt"
ANIMATION_COLOR_ORIGIN :: rl.RED
@ -101,12 +102,48 @@ rectangle_corners_transform_mat2 :: proc "contextless" (corners: RectangleCorner
}
draw_animation_rectangle_corners :: proc(corners: RectangleCorners, color: rl.Color) {
rl.DrawTriangle(corners.tl, corners.bl, corners.br, {**color.rgb, color.a >> 1})
rl.DrawTriangle(corners.br, corners.tr, corners.tl, {**color.rgb, color.a >> 1})
rl.DrawLineV(corners.tl, corners.tr, color)
rl.DrawLineV(corners.tr, corners.br, color)
rl.DrawLineV(corners.br, corners.bl, color)
rl.DrawLineV(corners.bl, corners.tl, color)
triangles := rectangle_corners_get_triangles(corners)
draw_triangle(triangles[0], {**color.rgb, color.a >> 1})
draw_triangle(triangles[1], {**color.rgb, color.a >> 1})
rl.DrawLineEx(triangles[0][0], triangles[0][1], 2.0, color)
rl.DrawLineEx(triangles[0][1], triangles[0][2], 2.0, color)
rl.DrawLineEx(triangles[1][0], triangles[1][1], 2.0, color)
rl.DrawLineEx(triangles[1][1], triangles[1][2], 2.0, color)
}
rectangle_corners_get_triangles :: proc (corners: RectangleCorners) -> [2]tri2 {
middle := (corners.tl + corners.tr + corners.br + corners.bl) / 4.0
corners := [4]v2{corners.tl, corners.tr, corners.br, corners.bl}
AngleAndReference :: struct{angle: f32, corner: v2}
corners_polar: [4]AngleAndReference
for i in 0..<4 {
corner_centered := corners[i] - middle
corners_polar[i] = {
angle = linalg.atan2(-corner_centered.y, corner_centered.x),
corner = corners[i]
}
}
corners_slice := corners_polar[:]
sorting_interface := sort.Interface {
collection = &corners_slice,
len = proc(it: sort.Interface) -> int {
array := (cast(^[]AngleAndReference)it.collection)^
return 4
},
less = proc(it: sort.Interface, i, j: int) -> bool {
array := (cast(^[]AngleAndReference)it.collection)^
return array[i].angle < array[j].angle
},
swap = proc(it: sort.Interface, i, j: int) {
array := (cast(^[]AngleAndReference)it.collection)^
array[i], array[j] = array[j], array[i]
},
}
sort.sort(sorting_interface)
return {
{corners_slice[0].corner, corners_slice[1].corner, corners_slice[2].corner},
{corners_slice[2].corner, corners_slice[3].corner, corners_slice[0].corner},
}
}
/*
@ -177,12 +214,12 @@ animation_draw :: proc(animation: Animation, global_transform: mat3) {
draw_animation_rectangle_corners(rectangle_corners_transform_mat3(global_transform, shape), ANIMATION_COLOR_ORIGIN)
transform := linalg.identity(mat3)
matrices := slice.reinterpret([]mat3, animation.matrices[:animation.matrix_count * 9])
for mat in matrices {
transform *= mat
shape_next := rectangle_corners_transform_mat3(transform, shape)
shape_next_world := rectangle_corners_transform_mat3(global_transform, shape_next)
draw_animation_rectangle_corners(shape_next_world, ANIMATION_COLOR_ORIGIN)
}
// for mat in matrices {
// transform *= mat
// shape_next := rectangle_corners_transform_mat3(transform, shape)
// shape_next_world := rectangle_corners_transform_mat3(global_transform, shape_next)
// draw_animation_rectangle_corners(shape_next_world, ANIMATION_COLOR_ORIGIN)
// }

View file

@ -2,16 +2,18 @@ package main
import rl "libraries/raylib"
import "core:log"
import "libraries/back"
main :: proc() {
// exe_path := os.args[0]
// exe_dir := filepath.dir(string(exe_path))
// os.set_working_directory(exe_dir)
rl.ChangeDirectory(rl.GetApplicationDirectory())
// back.register_segfault_handler()
// context.assertion_failure_proc = back.assertion_failure_proc
back.register_segfault_handler()
context.assertion_failure_proc = back.assertion_failure_proc
register_illegal_instruction_handler()
context.logger = log.create_console_logger()
init()

View file

@ -31,6 +31,7 @@ import rl "libraries/raylib"
import ui "libraries/snths_ui"
import "core:mem"
import "core:fmt"
import "core:math"
import "core:math/linalg"
import "core:strings"
@ -372,6 +373,11 @@ program_show_dialog :: proc(program: ^Program, dialog_type: ProgramDialogType, m
program.state = .Dialog
program.dialog_type = dialog_type
program.dialog_message = message
mem.set(&program.dialog_data, 0, size_of(program.dialog_data))
for i in 0..<len(program.dialog_data.input_float_values) {
program.dialog_data.input_float_values[i] = 0.0
program.dialog_data.input_float_value_strings[i][0] = '0'
}
}
program_init :: proc(allocator := context.allocator) {
@ -598,36 +604,21 @@ program_update :: proc() {
program_add_identity_matrix :: proc() {
value_strings, values := matrix_pool_get_mat3()
value_strings[0][0] = '1'
values[0] = 1.0
value_strings[4][0] = '1'
values[4] = 1.0
value_strings[8][0] = '1'
values[8] = 1.0
write_matrix_to_values_and_value_strings(values, value_strings, mat3(1))
}
program_add_translation_matrix :: proc(x, y, z: f32) {
value_strings, values := matrix_pool_get_mat3()
value_strings[0][0] = '1'
values[0] = 1.0
value_strings[4][0] = '1'
values[4] = 1.0
fmt.bprint(value_strings[6][:], x)
values[6] = x
fmt.bprint(value_strings[7][:], y)
values[7] = y
fmt.bprint(value_strings[8][:], z)
values[8] = z
write_matrix_to_values_and_value_strings(values, value_strings, mat3 {
1, 0, x,
0, 1, y,
0, 0, z,
})
}
program_add_scalar_matrix :: proc(x, y, z: f32) {
value_strings, values := matrix_pool_get_mat3()
fmt.bprint(value_strings[0][:], x)
values[0] = x
fmt.bprint(value_strings[4][:], y)
values[4] = y
fmt.bprint(value_strings[8][:], z)
values[8] = z
write_matrix_to_values_and_value_strings(values, value_strings, linalg.matrix3_scale(v3{x, y, z}))
}
program_add_rotation_matrix :: proc(angle: f32) {
@ -637,31 +628,29 @@ program_add_rotation_matrix :: proc(angle: f32) {
case .Degrees: radians = linalg.RAD_PER_DEG * angle
case .Radians: radians = angle
}
write_matrix_to_values_and_value_strings(values, value_strings, matrix3_rotate2(radians))
}
a := linalg.cos(radians)
b := linalg.sin(radians)
fmt.bprintf(value_strings[0][:], "%.3f", a)
values[0] = a
fmt.bprintf(value_strings[1][:], "%.3f", -b)
values[1] = -b
fmt.bprintf(value_strings[3][:], "%.3f", b)
values[3] = b
fmt.bprintf(value_strings[4][:], "%.3f", a)
values[4] = a
fmt.bprint(value_strings[8][:], f32(1.0))
values[8] = 1.0
write_matrix_to_values_and_value_strings :: proc(values: []f32, value_strings: []InputFloatField, mat: mat3) {
for i in 0..<9 {
col := i % 3
row := i / 3
values[i] = mat[col, row]
write_float_to_buffer(value_strings[i][:], mat[col, row])
}
}
// rotmat := linalg.matrix2_rotate_f32(angle)
// fmt.bprint(value_strings[0][:], rotmat[0, 0])
// values[0] = rotmat[0, 0]
// fmt.bprint(value_strings[1][:], rotmat[0, 1])
// values[1] = rotmat[0, 1]
// fmt.bprint(value_strings[1][:], rotmat[1, 0])
// values[3] = rotmat[1, 0]
// fmt.bprint(value_strings[4][:], rotmat[1, 1])
// values[4] = rotmat[1, 1]
// fmt.bprint(value_strings[8][:], 1)
// values[8] = 1.0
write_float_to_buffer :: proc(buffer: []byte, value: f32) {
fraction := fract(value)
if fraction == 0.0 {
fmt.bprintf(buffer, "%.0f", value)
} else if math.floor(fraction * 10.0) == 1.0 {
fmt.bprintf(buffer, "%.1f", value)
} else if math.floor(fraction * 100.0) == 1.0 {
fmt.bprintf(buffer, "%.2f", value)
} else {
fmt.bprintf(buffer, "%.3f", value)
}
}
program_build_dialog_ui :: proc(ctx: ^ui.Context, dialog_type: ProgramDialogType) -> []ui.Element {

View file

@ -93,6 +93,10 @@ draw_float_aligned :: proc(value: f32, position: v2, style: FontStyle, halign: J
draw_text_aligned(text, position, style, halign, valign, color)
}
draw_triangle :: proc(t: tri2, color: rl.Color) {
rl.DrawTriangle(t[0], t[1], t[2], color)
}
/// ### MATH ### ///
fract :: proc(val: f32) -> f32 {
return val - math.trunc(val)
@ -322,3 +326,7 @@ matrix3_transform_rect2 :: proc(m: mat3, r: rect2) -> rect2 {
br := m * v3{r.x + r.width, r.y + r.height, 1.0}
return {**tl.xy, **(br - tl).xy}
}
euclidean_to_polar :: proc(v: v2) -> v2 {
return {linalg.atan2(-v.y, v.x), linalg.length(v)}
}