関数計算機能をAppleScriptに提供するAppleScriptライブラリ「calcLibAS」をアップデートしてみました。
変更点:
・sdefを書いたので、各種関数が予約語で呼び出せるようになった
だけです。
–> Download calcLibASv1.5 (To ~/Library/Script Libraries/)
さまざまな関数計算の機能をAppleScriptに提供するモジュールと比べてもサポート関数の数が多く、さらに本ライブラリは単にJavaScriptCoreの関数計算機能を変換しているだけなので、ライブラリ内で計算は一切していません。
技術的に何も見るべき点がなく、高度なテーマに一切挑戦していないのに、大量の数値関数の機能を提供しているのが本ライブラリの特徴です。志の低さでは他に類を見ないレベルですが、実際に稼働して役に立っています。
本来はCephes Math Library(関数36個ぐらい)あたりをラッピングしようと考えていたのですが、JavaScriptCore経由でJavaScript(おそらくCephes Math Libraryをラッピング)の関数を呼び出してもほぼ同数の関数が使えることが判明したため、3時間ぐらいで作ってみたのがはじまりです。当初のバージョンはJXAで記述した計算ルーチンを呼び出していましたが、JXAが頻繁にクラッシュしたため、JavaScriptCoreを呼び出すように変更・高速化(最初のバージョンから28倍速)しました。
ハンドラ呼び出しとsdefによる予約語を通じて関数計算した場合で、計算精度などに差は出ていないことを内部の検証コマンドで確認してあります。
メンテナンスしやすいように、sdefからの呼び出しサービスを行うライブラリと実際の計算(呼び出し)を行うCoreライブラリの2つの部品に分けています。機能本体部分にsdefで定義した予約語を使うと、メンテナンスも何もできなくなるというapplescript-stdlibを反面教師とし、さらにsdefからの呼び出し部分がパラメータのチェックや例外処理への対応などで容易に機能がふくれあがっていくため、メンテナンス性を確保するためにこのような構造にしました。
log関数については、すでにAppleScriptビルトインで、まったく異なる働きを行うlogコマンド(スクリプトエディタ/Script Debuggerのログ表示機能でログ表示)があるので、重複を避けるためにsdef定義でlogarithmと表記するようにしました。
roundも同様にsdef定義でroundNumと表記しています。
実際に、三角関数やatan2などの関数を使い出していますが、精度や挙動、実行速度などに前バージョンから差異はありません。AppleScript用語の予約語がついて呼びやすくなっただけです。
AppleScript名:Every Functions |
— Created 2019-08-20 by Takaaki Naganoya — 2019 Piyomaru Software use AppleScript version "2.5" use scripting additions use framework "Foundation" use calSub : script "calcLibAS" set a001 to abs -10 set a002 to acos -1 set a003 to acosh 10 set a004 to asin 10 set a005 to asinh 10 set a006 to atan 10 set a007 to atan2 {10, 20} set a008 to atanh 10 set a009 to cbrt 3 set a010 to ceil 0.95 set a011 to clz32 1 set a012 to cos 1 set a013 to cosh 1 set a014 to exp 1 set a015 to expm1 -1 set a016 to floor 45.95 set a017 to fround 1.337 set a018 to hypot {3, 4, 5} set a019 to lmul {2, 5} set a020 to logarithm 10 set a021 to log10 2 set a022 to log1p 1 set a023 to log2 3 set a024 to max {1, 2, 3, 4, 6, 2, 10} set a025 to min {1, 2, 3, 4, 6, 2, 10, 0} set a026 to pow {7, 2} set a027 to rnd –random number set a028 to roundNum 5.95 set a029 to sign 10 set a030 to sin (pi / 2) set a031 to sinh 1 set a032 to sqrt 2 set a033 to tan 30 set a034 to tanh 10 set a035 to trunc 13.37 set aList to {a001, a002, a003, a004, a005, a006, a007, a008, a009, a010, a011, a012, a013, a014, a015, a016, a017, a018, a019, a020, a021, a022, a023, a024, a025, a026, a027, a028, a029, a030, a031, a032, a033, a034, a035} return test() of calSub –Check function to calc from sdef and each handlers excepting random numbers |
AppleScript名:Calc direction from place A to B |
— Created 2019-08-20 by Takaaki Naganoya — 2017-2019 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use script "calcLibAS" set coord1 to {latitude:35.73677496, longitude:139.63754457} –Nakamurabashi Sta. set coord2 to {latitude:35.78839012, longitude:139.61241447} –Wakoshi Sta. set dirRes1 to calcDirectionBetweenTwoPlaces(coord1, coord2) of me –> -25.925429877542 set coord2 to {latitude:35.7227821, longitude:139.63860897} –Saginomiya Sta. set dirRes2 to calcDirectionBetweenTwoPlaces(coord1, coord2) of me –> 175.649833487804 set coord2 to {latitude:35.73590542, longitude:139.62986745} –Fujimidai Sta. set dirRes3 to calcDirectionBetweenTwoPlaces(coord1, coord2) of me –> -96.385293928667 set coord2 to {latitude:35.73785024, longitude:139.65339321} –Nerima Sta. set dirRes4 to calcDirectionBetweenTwoPlaces(coord1, coord2) of me –> 85.959474671834 set coord2 to {latitude:35.71026838, longitude:139.81215754} –Tokyo Sky Tree set dirRes5 to calcDirectionBetweenTwoPlaces(coord1, coord2) of me –> 96.826542737106 –位置情報1から位置情報2の方角を計算。北が0度 on calcDirectionBetweenTwoPlaces(coord1, coord2) set deltaLong to (longitude of coord2) – (longitude of coord1) set yComponent to sin deltaLong set xComponent to (cos (latitude of coord1)) * (sin (latitude of coord2)) – (sin (latitude of coord1)) * (cos (latitude of coord2)) * (cos deltaLong) set radians to (atan2 {yComponent, xComponent}) as real set degreeRes to (radToDeg(radians) of me) return degreeRes end calcDirectionBetweenTwoPlaces on radToDeg(aRadian) return aRadian * (180 / pi) end radToDeg |
AppleScript名:日本測地系から世界測地系への座標変換.scpt |
— Created 2018-07-13 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use math : script "calcLibAS" set jpLat to 42.16593046887 set jpLng to 142.771877437246 set {wdLat, wdLng, wdH} to JapanGeodeticSystem’s convertIntoWgs(jpLat, jpLng) –> {42.168504277889, 142.768075650137, 61.914452206343} –https://altarf.net/computer/ruby/3347 –日本測地系から世界測地系に換算 script JapanGeodeticSystem –ラジアン(度) property rdNum : pi / 180 –日本測地系の定数(ベッセル楕円体) property rJP : 6.377397155E+6 –赤道半径 property fJP : 1 / 299.1528128 –扁平率 property e2JP : (2 * fJP) – (fJP * fJP) –第一離心率 –世界測地系の定数(WGS84) property rWS : 6.378137E+6 –赤道半径 property fWS : 1 / 298.257223563 –扁平率 property e2WS : (2 * fWS) – (fWS * fWS) –第一離心率 –並行移動量(m) property dxNum : -148 property dyNum : 507.0 property dzNum : 681.0 –楕円体高 property heightNum : 0 –日本測地系から世界測地系に変換する on convertIntoWgs(aLat, aLong) set {x, y, z} to llh2xyz(aLat, aLong, heightNum, rJP, e2JP, rdNum) of me set x to x + dxNum set y to y + dyNum set z to z + dzNum set {lat1, lng1, h1} to xyz2llh(x, y, z, rWS, e2WS, rdNum) of me return {lat1, lng1, h1} end convertIntoWgs –座標系の変換(緯度経度 -> xyz) on llh2xyz(latLocal, lngLocal, hLocal, aLocal, e2Local, rdLocal) set latLocal to latLocal * rdLocal set lngLocal to lngLocal * rdLocal set sbNum to sin latLocal set cbNum to cos latLocal set rnLocal to aLocal / (sqrt (1 – e2Local * sbNum * sbNum)) set xLocal to (rnLocal + hLocal) * cbNum * (cos lngLocal) set yLocal to (rnLocal + hLocal) * cbNum * (sin lngLocal) set zLocal to (rnLocal * (1 – e2Local) + hLocal) * sbNum return {xLocal, yLocal, zLocal} end llh2xyz –座標系の変換(xyz -> 緯度経度) on xyz2llh(x, y, z, a, e2, rdLocal) set bda to sqrt (1 – e2) set p to sqrt (x * x + y * y) set t to atan2 {z, p * bda} set stNum to sin (t) set ctNum to cos (t) set b to atan2 {z + e2 * a / bda * stNum * stNum * stNum, p – e2 * a * ctNum * ctNum * ctNum} set l to atan2 {y, x} set sb to sin (b) set rn to a / (sqrt (1 – e2 * sb * sb)) set h to p / (cos (b)) – rn set l1 to b / rdLocal set l2 to l / rdLocal return {l1, l2, h} end xyz2llh end script |
AppleScript名:Circulate Finder windows |
— Created 2014-11-17 by Takaaki Naganoya — Modified 2019-08-18 by Takaaki Naganoya — 2014-2019 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "AppKit" — for NSScreen use calLib : script "calcLibAS" property aNum : 300 property aOffset : 0 property maxWin : 6 property winList : {} property randList : {} property winSize : 300 –Initialize set winList to {} set randList to {} repeat maxWin times tell application "Finder" activate set aWin to make new Finder window tell aWin set toolbar visible to false set sidebar width to 0 set statusbar visible to false set position to {100, 100} set bounds to {100, 100, 100 + winSize, 100 + winSize} end tell set the end of winList to aWin set the end of randList to {random number from 0 to 400, random number from 0 to 400, random number from 1 to 360} end tell end repeat –Main repeat with i from 1 to 360 by 6 repeat with ii from 1 to maxWin set aWinObj to contents of item ii of winList set {aRandX, aRandY, aRandDegree} to item ii of randList set aDeg to i + aRandDegree set aSinNum to (sin aDeg) as real set aCosNum to (cos aDeg) as real set x to ((aNum * aSinNum) + aNum) * 2 + aOffset set y to (aNum * aCosNum) + aNum + aOffset ignoring application responses tell application "Finder" tell aWinObj set position to {(x as integer) + aRandX, (y as integer) + aRandY} end tell end tell end ignoring end repeat end repeat –Sweep tell application "Finder" repeat with i in winList tell i close end tell end repeat end tell |
AppleScript名:2点間の距離を求める(地球を球体として計算) |
— Created 2019-08-22 by Takaaki Naganoya use AppleScript version "2.5" use scripting additions use framework "Foundation" use script "calcLibAS" property earth_radius : 6378140 set aPoint to {lat:35.7398693, long:139.6474103} set bPoint to {lat:31.5719562, long:130.56257084} set aRes to calcDistanceBetweenTwoPoint(aPoint, bPoint) of me on calcDistanceBetweenTwoPoint(aPoint, bPoint) set lat1 to lat of aPoint set lng1 to long of aPoint set lat2 to lat of bPoint set lng2 to long of bPoint –緯度経度をラジアンに変換 set rlat1 to lat1 * pi / 180 set rlng1 to lng1 * pi / 180 set rlat2 to lat2 * pi / 180 set rlng2 to lng2 * pi / 180 — 2点の中心角(ラジアン)を求める set a to (sin rlat1) * (sin rlat2) + (cos rlat1) * (cos rlat2) * (cos rlng1 – rlng2) set rr to acos a –2点間の距離(メートル) set distance to earth_radius * rr return distance end calcDistanceBetweenTwoPoint |