おまけの計算
CyUtilモジュールのbcd関数を使えば5アームクランクのbcd(ボルト=サークル=ダイアメーター(クランクのpcd)が分かります。
例えばあるクランクの隣りあったチェーンリング取り付けボルト穴の距離(ピッチ)を測って
76mmだった時、
CyUtil> bcd 76
129.29892
ですのでこのクランクのpcdは130となります。
これは、半径rの円に内接する正5角形の1辺の長さからrを求める計算です。
上図の三角形abcで辺acはピッチの半分、∠acbは直角、∠abcは360÷(5×2)ですので
例えばあるクランクの隣りあったチェーンリング取り付けボルト穴の距離(ピッチ)を測って
76mmだった時、
CyUtil> bcd 76
129.29892
ですのでこのクランクのpcdは130となります。
これは、半径rの円に内接する正5角形の1辺の長さからrを求める計算です。
上図の三角形abcで辺acはピッチの半分、∠acbは直角、∠abcは360÷(5×2)ですので
三角関数のサインを適用すればいいことが分かります。
Prelude> (76/2) / sin ((3.14*2)/10) *2
129.35564152105735
(簡易計算としてはピッチを1.7倍してもよい
Prelude> 76*1.7
129.2
pcdはほぼ決まっているのでこれで十分です。
)
****************
Prelude> (76/2) / sin ((3.14*2)/10) *2
129.35564152105735
(簡易計算としてはピッチを1.7倍してもよい
Prelude> 76*1.7
129.2
pcdはほぼ決まっているのでこれで十分です。
)
****************
pcd関数を使えばチェーンリングのpcdが分かります。この場合のpcdはチェーンのピンが形作る仮想円です。
例えば歯数50Tのチェーンリングのpcdは
Prelude> :l CyUtil.hs
Ok, modules loaded: CyUtil.
Prelude CyUtil> pcd 50
202.25983
ですので、逆にチェーンリングのpcdを測って、202mmであればそのチェーンリングの歯数は50Tだと分かります。
pcdは測りづらいので歯底距離を測ります。
Prelude CyUtil> grd 50
194.41385
前もって歯底距離の一覧表を作っておけば、チェーンリング、コグの歯数を調べることができます。
Prelude CyUtil> map (\x-> (x, round1 (grd x))) [10..60]
[(10,"32.9"),(11,"37.3"),(12,"40.9"),(13,"45.3"),(14,"49.0"),(15,"53.3"),(16,"57.0"),(17,"61.3"),(18,"65.1"),(19,"69.4"),(20,"73.2"),(21,"77.4"),(22,"81.2"),(23,"85.5"),(24,"89.3"),(25,"93.5"),(26,"97.4"),(27,"101.6"),(28,"105.5"),(29,"109.7"),(30,"113.5"),(31,"117.7"),(32,"121.6"),(33,"125.8"),(34,"129.7"),(35,"133.9"),(36,"137.8"),(37,"142.0"),(38,"145.9"),(39,"150.0"),(40,"153.9"),(41,"158.1"),(42,"162.0"),(43,"166.2"),(44,"170.1"),(45,"174.3"),(46,"178.2"),(47,"182.3"),(48,"186.3"),(49,"190.4"),(50,"194.4"),(51,"198.5"),(52,"202.4"),(53,"206.6"),(54,"210.5"),(55,"214.7"),(56,"218.6"),(57,"222.7"),(58,"226.7"),(59,"230.8"),(60,"234.8")]
またpcdはシングルバイクのチェーン長を計算する時にも使います。
import CyUtil
import System.Environment
class Gear a where
getPhase :: a -> IO Float
getL :: a -> IO Float
data FG = FG Int deriving Show
data RG = RG Int deriving Show
instance Gear FG where
getPhase _ = getG >>= return . (*2) . (+ d90)
getL f@(FG a) = getPhase f >>= calL a
instance Gear RG where
getPhase _ = getG >>= return . (*2) . (+ d90) . negate
getL r@(RG a) = getPhase r >>= calL a
calL a = return . (*(fromIntegral a)) . (/ yen)
getG = do
(FG a,RG b,c) <- mkGS
let l = pcr a - pcr b
return $ asin (l / c)
mkGS = do
[a,b,c] <- getArgs
return $ (FG (read a), RG (read b), (read c))
chLen = do
(_,_,c) <- mkGS
t <- getG
return $ myCos (c, t) / lOfLink * 2
main = do
(a,b,c) <- mkGS
l <- getL a
ll <- getL b
lll <- chLen
print $ l+ll+lll
補助線を1本加えますと計算方法がわかりやすくなります。
直角三角形abcの各辺の長さを計算します。
辺acはチェーンステイ長。辺bcは前後ギヤのPCDの差から。辺abは他辺から三平方の定理で計算できます。
すこし面倒なのが前後ギヤへのチェーンの巻きつき量ですが、
角bdeの角度がわかれば計算できます。
上図から角bdeは角bacに等しいようです。
角bacは三角関数の逆関数アークサイン(haskellではasin)で求めます。
ghcでコンパイル。
すこし面倒なのが前後ギヤへのチェーンの巻きつき量ですが、
角bdeの角度がわかれば計算できます。
上図から角bdeは角bacに等しいようです。
角bacは三角関数の逆関数アークサイン(haskellではasin)で求めます。
ghcでコンパイル。
$ ghc g.hs
Linking g ...
コマンドライン引数で数値を渡します。
他のページ(カスタムジャパンさん)の計算結果を参考にします。
$ ./g 48 16 405
96.594635
**********************************************
Gui版
--chainLen.hs
import Graphics.UI.Gtk
import CyUtil
import Control.Monad
import MySpin
initData :: [Double]
initData = [48,16,405]
data GearSystem = GS{fg::FG,rg::RG,csl::Double} deriving Show
mkGS :: [Double] -> GearSystem
mkGS [a,b,c] = GS (FG(round a)) (RG(round b)) c
getG :: GearSystem -> Double
getG (GS (FG a) (RG b) c) =
let l = pcr a - pcr b
in asin (l / c)
class Gear a where
getPhase :: GearSystem -> a -> Double
getL :: GearSystem -> a -> Double
data FG = FG Int deriving Show
data RG = RG Int deriving Show
instance Gear FG where
getPhase gs (FG _) = (d90 + getG gs) / d180
getL gs fg@(FG t) = fromIntegral t * getPhase gs fg
instance Gear RG where
getPhase gs (RG _) = (d90 - getG gs) / d180
getL gs rg@(RG t) = fromIntegral t * getPhase gs rg
chLen :: GearSystem -> Double
chLen gs@(GS _ _ c) =
let t = getG gs
in myCos (c, t) / lOfLink * 2
links :: [Double] -> Double
links ds = let gs@(GS a b c) = mkGS ds in getL gs a + getL gs b + chLen gs
main = do
initGUI
window <- windowNew
hbox <- hBoxNew False 0
vbox <- vBoxNew False 0
boxPackStart vbox hbox PackNatural 0
let [a,b,c] = initData
let spmods = [ ("前ギヤ(T)" ,20, 60 ,1,a),
("後ろギヤ(T)" ,6, 30 ,1,b),
("チェーンステイ長(mm)" ,300, 1000 ,1,c)]
spins <- myAddSpinButtons hbox spmods
label <- labelNew Nothing
update label spins
mapM (\x-> onValueSpinned x (update label spins)) spins
boxPackStart vbox label PackNatural 0
containerAdd window vbox
widgetShowAll window
onDestroy window mainQuit
mainGUI
update label spins = do
ds <- mapM (\x -> get x spinButtonValue) spins
let l = links ds
labelSetText label ("チェーン長(リンク数)=" ++ (round1 l))
***********************************************
--CyUtil.hs
module CyUtil where
import Data.Complex
rad d = ((2*pi)/360)*d
dig r = r / (yen/360)
yen = rad 360
d90 = rad 90
d180 = rad 180
dist1 c1 c2 = magnitude (c1-c2)
dist ((a,b),(c,d)) =
let
c1 = mkPolar a b
c2 = mkPolar c d
in dist1 c1 c2
pita l1 l2 = dist1 (0 :+ l1) (l2 :+ 0)
myCos (a,b) = realPart $ mkPolar a b
round1 x = a ++ take 2 b
where (a,b) = break (=='.') $ show x
d1 = 7.75 -- チェーン ローラー の半径(mm)
lOfLink = 25.4 / 2 -- チェーンリンク長(mm)
rOfPolygon n l = (l / 2) / sin ((yen / n) / 2)
r5 = rOfPolygon 5
bcd = (* 2) . r5
pcr x = rOfPolygon (fromIntegral x) lOfLink
pcd = (*2) . pcr
grd x = if odd x
then pcd x - d1
else dist ((r, rad (-180)),(r, yen / (fromIntegral x) / 2))
where r = pcd x / 2 - (d1 / 2)
CyUtil も少し書き換えていると思いますので、再録します。
実行例
**********************************************************
にソースファイルがあります。
0 件のコメント:
コメントを投稿