■分数の記号の作成

◇基本は簡単だが応用は難しい◇
 分数の記号の表現は,「基本となる考え方 aの上にbを書くには」で解説しましたように,基本の原理さえ理解できれば簡単に実現できます.しかし,実用に耐えうるものにするには,多くの課題をクリアしなければなりません.おそらく,ここで予定している関数の中で,分数と行列が一番大変です.

◇フォントの幅◇
 MS ゴシックのような固定ピッチフォントでは,右の図1のようにアルファベットの文字によらず横幅が一定に表示されますが,英文を固定ピッチフォントで書くと間延びして見えます.MS Pゴシックのようなプロポーショナルフォントでは,文字ごとに横幅が異なります.iは狭く, w は広く表示されます.
 当面,分数の横線に使いたいハイフンはポイントサイズの半分程度の幅を持っていますが,左端から右端まで印字されているとは限りません.また,文字がくっつかないように文字送りもあります.このようにして,ハイフンを続けて書き込んでも右の図2のように破線になります.
 途切れない横線にするには,横幅よりも狭い間隔で重ねます.
 1文字当りの横幅が8pxのとき
for(kk = 0; kk < haba; kk++)
  document.write(' .......left:kk*7px; ........ '-' );
のように横幅よりも小さな送り量で印字するとつながります.(どのくらい小さければよいかは実験した方が早い.)

 見本の関数では,日本語全角文字の罫線を使っているので16pxのフォントで16pxよりも小さな幅で印字すれば,つながるはずです.
図1  




図2  
◇分母と分子の中央位置をそろえる◇
 分母と分子の文字数が異なるとき,右の図3のように文字数の少ない方を下げて表示すれば自然に見えます.
 font-size:16px; のとき,1文字の幅が8pxとすれば,
文字幅×文字数の差÷2 だけ下げればよいので,
(文字数の半分×文字数の差) だけ下げればよいことになります.

 (プロポーショナルフォントを使う限り完全には合いませんが,幅の狭い文字や広い文字ばかり偏ることは少なく,たいてい合います.どうしても合わないときは,分母文字数,分子文字数,横幅が引数で指定できますので,分子を右に下げたければ分子の文字数を実際よりも少なく書き込むようにします.また,横線の幅をもっと長くしたいときは,横幅を大きめに指定します.)
図3  
◇分母の分母,分母の分子の表示位置◇
 単純な分数は、割と簡単に表示できますが,分数を合成したときに,分子の分子,分子の分母の表示位置(y座標)は?
 右の図4のように,font-size:16px;を1単位として,建物のfloor を下を0階,1階,・・・,上を−1階,−2階,・・・とすると,単純分数の分子のfloorは-1階ですが,合成した場合
分子の分子 : floor = (-1) + (-1) = (-2)
分子の分母 : floor =(-1) + (0) = (-1)
となって,予定のfloorに入ります.

 一方,単純分数の分母のfloorは0 ですが
分母の分子 : floor = (0) + (-1) = (-1)
分母の分母 : floor =(0) + (0) = (0)
とすると予定のfloorよりも1階上にいます.

そこで,ある分数を分数の分子に代入するときはそのままの floor とし,分数の分母に代入するときは,floorを1加えるように,引数を1つ追加すれば解決します.
 Frac(bunshi, bunbo, bottom_or_top)
詳しくは,下の関数例を見てください.
図4  
◇単純分数だけはセンター位置が違う◇
 繁分数として合成される場合を想定して分数の表示位置を考察してきましたが,実際上最もよく使うのは単純な分数です.右の図5のような左辺の分数が,右辺として使う本文の中央位置と合うようにしておけば,関数呼び出し側で手直しする手間が省けます.

 ■以上のまとめ■  引数を1つ増やして,次のように分岐すればfloor の割り当てがスムーズにできます.
(floorは英単語なので避けてbottom1という引数名を使うことにして)
bottom1 == 'c' (center)ならば半分下げる
bottom1 == 'b' (bottom)ならば1階下げる
bottom1 == 't' (top)ならばその階からスタートする
図5   = - k2y
分数を表示する関数の例 ・・・ (合成関数の項目参照::関数は間接呼び出し用に作成し,直接呼び出し用は間接呼び出し用の引用とする.)

function cFrac_101(bunshi, bunbo, bottom1, haba, bunshi_haba, bunbo_haba, ffamily) // 引数が多い?[?]
{//-----------------------3個目以降の引数を省略したときの取り扱い
//分子の幅
if(bunshi_haba == null || bunshi_haba == '')
  bunshi_len = bunshi.toString().length; //<sapn><input>などのタグを使わないときは略してもよい
else
  bunshi_len = parseInt(bunshi_haba);

//分母の幅
if(bunbo_haba == null || bunbo_haba == '')//<sapn><input>などのタグを使わないときは略してもよい
  bunbo_len = bunbo.toString().length;
else
  bunbo_len = parseInt(bunbo_haba);

//横線の幅
if(haba == null || haba == '')
yoko_haba = Math.max(bunshi_len, bunbo_len);
else
yoko_haba = parseInt(haba);

//font-family
if(ffamily == null || ffamily == '') //fontが略されれば Comic Sans MSとする
  ffamily2 = "Comic Sans MS";
else
  ffamily2 = ffamily;
//-----------------------------------------------------------------
str1 = "";
bunshi_floor = -1;//分子の初期位置
bunbo_floor = 0; //分母の初期位置

if(bottom1 == 'b' || bottom1 == 'B') //分母に代入する分数の第3引数にはbかBを使う
{
 bunshi_floor = 0;
 bunbo_floor = 1;
 str1 += '<span class="mother1" style="position:relative;top:0px;">';
}
else if(bottom1 == 'c' || bottom1 == 'C' || bottom1 == '' || bottom1 == null) //第3引数がc,Cまたは空白または略されれば
単純分数として中央に置く

 str1 += '<span class="mother1" style="position:relative;top:8px;">';
else if(bottom1 == 't' || bottom1 == 'T') //分子に代入する分数には第3引数にt,Tを使う
 str1 += '<span class="mother1" style="position:relative;top:0px;">';

saidai = parseInt(yoko_haba);
n_start = (saidai - parseInt(bunshi_len)) * 4; //分子のスタート位置は(最大幅-分子文字数)×font幅の半分の長さ
d_start = (saidai - parseInt(bunbo_len)) * 4; //分母のスタート位置は(最大幅-分母文字数)×font幅の半分の長さ

for(kk = 0; kk < saidai; kk++)
  str1 += '<span class="child1" style="position:absolute; left:' + (kk*8) + 'px; top:'+ (bunbo_floor * 16 )+'px; font-size:8px;font-weight:medium;">─</span>';//横線を引く

str1 += '<span class="child1" style="position:absolute; left:' + n_start + 'px; top:'+(bunshi_floor*16 )+'px;font-family:'+ ffamily2+'; font-size:16px;font-weight:medium;">'+ bunshi +'</span>';

str1 +='<span class="child1" style="position:absolute; left:'+ d_start +'px; top:'+(bunbo_floor*16 ) +'px; font-family:'+ ffamily2+';font-size:16px;font-weight:medium;">'+ bunbo +'</span>';
str1 += ' </span>';

for(kk = 0; kk < saidai; kk++)
 str1 += '<span class="mother1" style=" position:relative; visibility: hidden; left:' + kk*16 + 'px; top:0px;font-family:'+ ffamily2+'; font-size:16px;font-weight:medium;">n</span>';//文字送り量の調整

return (str1);
}

//直接版
function Frac_101(bunshi, bunbo, bottom1, haba, bunshi_haba, bunbo_haba, ffamily)
{document.write(cFrac_101(bunshi, bunbo, bottom1, haba, bunshi_haba, bunbo_haba, ffamily));
}
◇所要時間15分程度の問題◇
 上で作成した分数表示関数( Frac_101)を用いて,右のような繁分数式を表示すると,分子の差を表わす符号(−)は親分子の本来位置に表示されます (これは低過ぎます).この符号を,関数呼び出し側で調整して望ましい位置に表示されるようにしてください.
[ 答案例 ]
◇所要時間30分程度の問題◇
 分数を表示する関数の間接呼び出し用を
function cFrac_101(bunshi, bunbo, bottom1, haba, bunshi_haba, bunbo_haba, ffamily)
直接呼び出し用を
function Frac_101(bunshi, bunbo, bottom1, haba, bunshi_haba, bunbo_haba, ffamily)
で定義したとします.各引数の意味は日本語の読みとおり.
また,累乗根を表示する関数の間接呼び出し用を
function cRoot_101(shiki, mojisuu, ruijokon, ruijo, ffamily)
直接呼び出し用を
function Root_101(shiki, mojisuu, ruijokon, ruijo, ffamily)
で定義したとします.このとき,右のように分数に累乗根が合成されているものと,累乗根に分数が合成されているものを表示してください.
[ 答案例 ]


+



[ 教材例 ]

○メニューに戻る