summaryrefslogtreecommitdiffstats
path: root/virtual-programs
diff options
context:
space:
mode:
authorOmar Rizwan <omar@omar.website>2023-07-09 03:47:41 +0000
committerOmar Rizwan <omar@omar.website>2023-07-09 03:47:41 +0000
commit96b7384bb36c87e13b0fc8b528d0f94fd9feed22 (patch)
treebf9adb8f79e45570c36f6c0cf4da71f1c6f24646 /virtual-programs
parentImplement `region move` (at least for AA regions) (diff)
downloadfolk-96b7384bb36c87e13b0fc8b528d0f94fd9feed22.tar.gz
folk-96b7384bb36c87e13b0fc8b528d0f94fd9feed22.zip
region move: Implement % move
Diffstat (limited to 'virtual-programs')
-rw-r--r--virtual-programs/regions.folk44
1 files changed, 40 insertions, 4 deletions
diff --git a/virtual-programs/regions.folk b/virtual-programs/regions.folk
index 343ffe03..7f16196c 100644
--- a/virtual-programs/regions.folk
+++ b/virtual-programs/regions.folk
@@ -41,6 +41,31 @@ namespace eval ::region {
expr {[llength $r] >= 3 ? [lindex $r 2] : 0}
}
+ proc width {r} {
+ set minXp 100000
+ set maxXp -100000
+ set theta [angle $r]
+ foreach v [vertices $r] {
+ lassign $v x y
+ set xp [expr {$x*cos($theta) + $y*sin($theta)}]
+ if {$xp < $minXp} { set minXp $xp }
+ if {$xp > $maxXp} { set maxXp $xp }
+ }
+ expr { $maxXp - $minXp }
+ }
+ proc height {r} {
+ set minYp 100000
+ set maxYp -100000
+ set theta [angle $r]
+ foreach v [vertices $r] {
+ lassign $v x y
+ set yp [expr {-$x*sin($theta) + $y*cos($theta)}]
+ if {$yp < $minYp} { set minYp $yp }
+ if {$yp > $maxYp} { set maxYp $yp }
+ }
+ expr { $maxYp - $minYp }
+ }
+
proc mapVertices {varname r body} {
lreplace $r 0 0 [uplevel [list lmap $varname [vertices $r] $body]]
}
@@ -85,8 +110,7 @@ namespace eval ::region {
vec2 scale 0.25 $vecsum
}
- # Utilities that transform regions while preserving center
- proc clip {r args} {
+ proc scale {r args} {
foreach {property value} $args {
if {$property eq "width"} {
@@ -95,15 +119,27 @@ namespace eval ::region {
} else {
error "region clip: Invalid property $property"
}
+
+ # TODO: Support %
+ # TODO: Support scale-all
+ set r [mapVertices v $r {vec2 add $v $dv}]
}
}
proc move {r args} {
set angle [angle $r]
- # FIXME: This one should work on any region -- just map over vertices.
+ # This one should work on any region -- just map over vertices.
foreach {direction distance} $args {
- if {![regexp {([0-9]+)px} $distance -> distance]} {
+ if {![regexp {([0-9]+)(px|%)} $distance -> distance unit]} {
error "region move: Invalid distance $distance"
}
+ if {$unit eq "%"} {
+ # Convert to pixels
+ if {$direction eq "left" || $direction eq "right"} {
+ set distance [expr {[width $r] * $distance * 0.01}]
+ } elseif {$direction eq "up" || $direction eq "down"} {
+ set distance [expr {[height $r] * $distance * 0.01}]
+ }
+ }
set dx [if {$direction eq "left"} {- $distance} \
elseif {$direction eq "right"} {+ $distance} \
else {+ 0}]