[Odin] Read start point, trace path and display[Odin] Read start point, trace path and display
🖼️
Some Good Points
Week 35, 2026
package main
import "core:fmt"
import "core:os"
import "core:strings"
import "core:strconv"
import rl "vendor:raylib"
main :: proc () {
image_file :: "challenge35.png"
// image_file :: "example.png"
start, err := read_start_point(image_file)
assert(err == nil)
path := path_trace(image_file, start)
fmt.println(path)
path_display(path)
}
read_start_point :: proc (image_file: string) -> (point: [2] int, err: os.Error) {
buf: [256] u8
file: ^os.File
defer os.close(file)
file = os.open(image_file) or_return
os.read(file, buf[:]) or_return
offset :: 0x34
pair: string
for i:=offset; buf[i]<='9'; i+=1 {
pair = string(buf[offset:i+1])
}
fmt.printfln("|%s|", pair)
sep := strings.index(pair, ",")
assert(sep > 0)
point[0], _ = strconv.parse_int(pair[:sep])
point[1], _ = strconv.parse_int(pair[sep+1:])
fmt.println(point)
return
}
Path :: [dynamic; 200] [2] int
path_trace :: proc (image_file: cstring, start_pos: [2] int) -> (path: Path) {
image := rl.LoadImage(image_file)
defer rl.UnloadImage(image)
rl.ImageFormat(&image, .UNCOMPRESSED_R8G8B8)
w := int(image.width)
h := int(image.height)
pixels := (cast ([^] [3] u8) image.data)[:w*h]
append(&path, start_pos)
for c := pixels[start_pos.y*w+start_pos.x]; c!={}; /**/ {
r, g, b := int(c.r), int(c.g), int(c.b)
pos: [2] int
switch {
case r!=0 && g!=0: pos = { r, g }
case r!=0 && b!=0: pos = { r, b }
case g!=0 && b!=0: pos = { g, b }
}
append(&path, pos)
c = pixels[pos.y*w+pos.x]
}
return
}
path_display :: proc (path: Path) {
rl.SetConfigFlags({ .VSYNC_HINT })
rl.InitWindow(800, 800, "week35")
defer rl.CloseWindow()
tex := _path_gen_texture(path)
defer rl.UnloadTexture(tex)
tex_scale := f32(rl.GetScreenHeight()) / f32(tex.height)
for !rl.WindowShouldClose() {
rl.BeginDrawing()
rl.ClearBackground({0,16,32,255})
rl.DrawTextureEx(tex, {}, rotation=0, scale=tex_scale, tint=rl.WHITE)
rl.EndDrawing()
}
}
_path_gen_texture :: proc (path: Path) -> rl.Texture {
img := rl.GenImageColor(256, 256, rl.DARKGRAY)
defer rl.UnloadImage(img)
for p, i in path {
c := i==0 ? rl.YELLOW : i==len(path)-1 ? rl.BEIGE : rl.WHITE
rl.ImageDrawCircle(&img, i32(p.x), i32(p.y), 4, c)
}
return rl.LoadTextureFromImage(img)
}