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/ease"
import "core:math/linalg" import "core:math/linalg"
import "core:slice" import "core:slice"
import "core:sort"
import "core:fmt" import "core:fmt"
ANIMATION_COLOR_ORIGIN :: rl.RED 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) { draw_animation_rectangle_corners :: proc(corners: RectangleCorners, color: rl.Color) {
rl.DrawTriangle(corners.tl, corners.bl, corners.br, {**color.rgb, color.a >> 1}) triangles := rectangle_corners_get_triangles(corners)
rl.DrawTriangle(corners.br, corners.tr, corners.tl, {**color.rgb, color.a >> 1}) draw_triangle(triangles[0], {**color.rgb, color.a >> 1})
rl.DrawLineV(corners.tl, corners.tr, color) draw_triangle(triangles[1], {**color.rgb, color.a >> 1})
rl.DrawLineV(corners.tr, corners.br, color) rl.DrawLineEx(triangles[0][0], triangles[0][1], 2.0, color)
rl.DrawLineV(corners.br, corners.bl, color) rl.DrawLineEx(triangles[0][1], triangles[0][2], 2.0, color)
rl.DrawLineV(corners.bl, corners.tl, 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) draw_animation_rectangle_corners(rectangle_corners_transform_mat3(global_transform, shape), ANIMATION_COLOR_ORIGIN)
transform := linalg.identity(mat3) transform := linalg.identity(mat3)
matrices := slice.reinterpret([]mat3, animation.matrices[:animation.matrix_count * 9]) matrices := slice.reinterpret([]mat3, animation.matrices[:animation.matrix_count * 9])
for mat in matrices { // for mat in matrices {
transform *= mat // transform *= mat
shape_next := rectangle_corners_transform_mat3(transform, shape) // shape_next := rectangle_corners_transform_mat3(transform, shape)
shape_next_world := rectangle_corners_transform_mat3(global_transform, shape_next) // shape_next_world := rectangle_corners_transform_mat3(global_transform, shape_next)
draw_animation_rectangle_corners(shape_next_world, ANIMATION_COLOR_ORIGIN) // draw_animation_rectangle_corners(shape_next_world, ANIMATION_COLOR_ORIGIN)
} // }

View file

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

View file

@ -31,6 +31,7 @@ import rl "libraries/raylib"
import ui "libraries/snths_ui" import ui "libraries/snths_ui"
import "core:mem" import "core:mem"
import "core:fmt" import "core:fmt"
import "core:math"
import "core:math/linalg" import "core:math/linalg"
import "core:strings" import "core:strings"
@ -372,6 +373,11 @@ program_show_dialog :: proc(program: ^Program, dialog_type: ProgramDialogType, m
program.state = .Dialog program.state = .Dialog
program.dialog_type = dialog_type program.dialog_type = dialog_type
program.dialog_message = message 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) { program_init :: proc(allocator := context.allocator) {
@ -598,36 +604,21 @@ program_update :: proc() {
program_add_identity_matrix :: proc() { program_add_identity_matrix :: proc() {
value_strings, values := matrix_pool_get_mat3() value_strings, values := matrix_pool_get_mat3()
value_strings[0][0] = '1' write_matrix_to_values_and_value_strings(values, value_strings, mat3(1))
values[0] = 1.0
value_strings[4][0] = '1'
values[4] = 1.0
value_strings[8][0] = '1'
values[8] = 1.0
} }
program_add_translation_matrix :: proc(x, y, z: f32) { program_add_translation_matrix :: proc(x, y, z: f32) {
value_strings, values := matrix_pool_get_mat3() value_strings, values := matrix_pool_get_mat3()
value_strings[0][0] = '1' write_matrix_to_values_and_value_strings(values, value_strings, mat3 {
values[0] = 1.0 1, 0, x,
value_strings[4][0] = '1' 0, 1, y,
values[4] = 1.0 0, 0, z,
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
} }
program_add_scalar_matrix :: proc(x, y, z: f32) { program_add_scalar_matrix :: proc(x, y, z: f32) {
value_strings, values := matrix_pool_get_mat3() value_strings, values := matrix_pool_get_mat3()
fmt.bprint(value_strings[0][:], x) write_matrix_to_values_and_value_strings(values, value_strings, linalg.matrix3_scale(v3{x, y, z}))
values[0] = x
fmt.bprint(value_strings[4][:], y)
values[4] = y
fmt.bprint(value_strings[8][:], z)
values[8] = z
} }
program_add_rotation_matrix :: proc(angle: f32) { 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 .Degrees: radians = linalg.RAD_PER_DEG * angle
case .Radians: radians = angle case .Radians: radians = angle
} }
write_matrix_to_values_and_value_strings(values, value_strings, matrix3_rotate2(radians))
}
a := linalg.cos(radians) write_matrix_to_values_and_value_strings :: proc(values: []f32, value_strings: []InputFloatField, mat: mat3) {
b := linalg.sin(radians) for i in 0..<9 {
fmt.bprintf(value_strings[0][:], "%.3f", a) col := i % 3
values[0] = a row := i / 3
fmt.bprintf(value_strings[1][:], "%.3f", -b) values[i] = mat[col, row]
values[1] = -b write_float_to_buffer(value_strings[i][:], mat[col, row])
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
// rotmat := linalg.matrix2_rotate_f32(angle) write_float_to_buffer :: proc(buffer: []byte, value: f32) {
// fmt.bprint(value_strings[0][:], rotmat[0, 0]) fraction := fract(value)
// values[0] = rotmat[0, 0] if fraction == 0.0 {
// fmt.bprint(value_strings[1][:], rotmat[0, 1]) fmt.bprintf(buffer, "%.0f", value)
// values[1] = rotmat[0, 1] } else if math.floor(fraction * 10.0) == 1.0 {
// fmt.bprint(value_strings[1][:], rotmat[1, 0]) fmt.bprintf(buffer, "%.1f", value)
// values[3] = rotmat[1, 0] } else if math.floor(fraction * 100.0) == 1.0 {
// fmt.bprint(value_strings[4][:], rotmat[1, 1]) fmt.bprintf(buffer, "%.2f", value)
// values[4] = rotmat[1, 1] } else {
// fmt.bprint(value_strings[8][:], 1) fmt.bprintf(buffer, "%.3f", value)
// values[8] = 1.0 }
} }
program_build_dialog_ui :: proc(ctx: ^ui.Context, dialog_type: ProgramDialogType) -> []ui.Element { 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_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 ### /// /// ### MATH ### ///
fract :: proc(val: f32) -> f32 { fract :: proc(val: f32) -> f32 {
return val - math.trunc(val) 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} br := m * v3{r.x + r.width, r.y + r.height, 1.0}
return {**tl.xy, **(br - tl).xy} return {**tl.xy, **(br - tl).xy}
} }
euclidean_to_polar :: proc(v: v2) -> v2 {
return {linalg.atan2(-v.y, v.x), linalg.length(v)}
}