package tiny_appkits
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
Application engines from scratch: a spreadsheet, rich text, paint, draw, CAD, editors and more
Install
dune-project
Dependency
Authors
Maintainers
Sources
0.3.6.tar.gz
md5=7c636383d146d30ac6f2fa234a6253c8
sha512=c79f3823c5f8f57e5038eb640d487c61168b84aa07c61999d6622ef9fd0c890e2b03b4c6a7cdbbe9352a49e25dda00ac7bb14693cee8e3d7beeed251351a2af0
doc/src/tiny_appkits.appkit_pushpull/Skp_view.ml.html
Source file Skp_view.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86(* Claude Code * * Copyright (C) 2026 Yoann Padioleau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * (LGPL) as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. *) (* See Skp_view.mli *) type t = { target : Vec3.t; distance : float; azimuth : float; elevation : float; fov : float } type area = { cx : float; cy : float; w : float; h : float } let start = { target = (0., 0., 2.); distance = 22.; azimuth = -60.; elevation = 14.; fov = 35. } let radians d = d *. Float.pi /. 180. let eye t = let az = radians t.azimuth and el = radians t.elevation in Vec3.add t.target (Vec3.scale t.distance (cos el *. cos az, cos el *. sin az, sin el)) (* just in front of the eye: a centimetre *) let near = 0.01 let camera t : Camera.t = { eye = eye t; target = t.target; up = (0., 0., 1.); fov = t.fov; ortho = 0.; near; far = infinity } let to_screen t area v = match Camera.ndc (camera t) ~aspect:(area.w /. area.h) v with | Some (x, y) -> Some (area.cx +. (x *. area.w /. 2.), area.cy +. (y *. area.h /. 2.)) | None -> None let project t area p = to_screen t area (Camera.view (camera t) p) let ray t area (sx, sy) = let c = camera t in let right, up, forward = Camera.basis ~up:c.up ~eye:c.eye ~target:c.target () in let f = Camera.focal c in let x = (sx -. area.cx) /. (area.w /. 2.) *. (area.w /. area.h) /. f and y = (sy -. area.cy) /. (area.h /. 2.) /. f in (c.eye, Vec3.normalize (Vec3.add forward (Vec3.add (Vec3.scale x right) (Vec3.scale y up)))) (* in view coordinates, z is the depth: the plane where polygons are cut, its front the side away from the eye -- a little beyond [near], so that the corners the cut makes are not refused by Camera.ndc for being a rounding error nearer *) let cut_at = 2. *. near let in_front : Bsp.plane = ((0., 0., 1.), cut_at) let polygon t area corners = let c = camera t in let front, _ = Bsp.split in_front (List.map (fun (p, drawn) -> (Camera.view c p, drawn)) corners) in List.filter_map (fun (v, drawn) -> Option.map (fun s -> (s, drawn)) (to_screen t area v)) front let segment t area p q = let c = camera t in let (_, _, zp) as vp = Camera.view c p and ((_, _, zq) as vq) = Camera.view c q in let cut a za b zb = Vec3.add a (Vec3.scale ((cut_at -. za) /. (zb -. za)) (Vec3.sub b a)) in let ends = if zp >= cut_at && zq >= cut_at then Some (vp, vq) else if zp >= cut_at then Some (vp, cut vp zp vq zq) else if zq >= cut_at then Some (cut vq zq vp zp, vq) else None in match ends with | Some (a, b) -> ( match (to_screen t area a, to_screen t area b) with Some a, Some b -> Some (a, b) | _ -> None) | None -> None let orbit t dx dy = { t with azimuth = t.azimuth -. (dx *. 0.4); elevation = Float.max (-89.) (Float.min 89. (t.elevation -. (dy *. 0.4))) } let pan t area dx dy = let c = camera t in let right, up, _ = Camera.basis ~up:c.up ~eye:c.eye ~target:c.target () in (* the world's size of a screen unit, at the target's depth *) let unit = 2. *. t.distance /. Camera.focal c /. area.h in { t with target = Vec3.sub t.target (Vec3.add (Vec3.scale (dx *. unit) right) (Vec3.scale (dy *. unit) up)) } let zoom t notches = { t with distance = Float.max 0.5 (Float.min 2000. (t.distance *. (0.85 ** notches))) } let extents t points = match points with | [] -> start | p :: _ -> let lo = List.fold_left (fun (a, b, c) (x, y, z) -> (Float.min a x, Float.min b y, Float.min c z)) p points in let hi = List.fold_left (fun (a, b, c) (x, y, z) -> (Float.max a x, Float.max b y, Float.max c z)) p points in let radius = Float.max 1. (Vec3.length (Vec3.sub hi lo) /. 2.) in { t with target = Vec3.scale 0.5 (Vec3.add lo hi); distance = radius /. sin (radians t.fov /. 2.) *. 1.15 }
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>