←Previous | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Next→

  //hyoushigi 拍子木
  //  鍵盤と腕木の間の板
  if (hyoushigiOn) {
    for (let k = 0; k < 2; k++) {  //0=左,1=右
      let x0 = k == 0 ? hyoushigiX0 : hyoushigiX1 - hyoushigiWidth;
      let x1 = x0 + hyoushigiWidth;
      let ph = phNewBox (x0, x1,
                         hyoushigiY0, hyoushigiY1,
                         hyoushigiZ0, hyoushigiZ1);
      zentaiHako.push (setupPolyhedron (ph, "hyoushigi_" + k, COLOR_BODY));
    }
  }

  //kyakuchuu 脚柱
  //  重いグランドピアノを支える3本の足
  //  3本の脚をなるべく大きな三角形に配置してバランスを保っている
  //  先端にキャスターが付いている
  //
  //  素人がグランドピアノを動かしてよいのは水平で強固で滑らかな床の上で3本の脚を接地させたまま転がすところまで
  //  段差を乗り越えようとして下手に持ち上げると脚にかかる重量のバランスが崩れて脚を折ってしまうのでやめたほうがよい
  //
  //  脚の位置の参考
  //    http://yamaha.custhelp.com/app/answers/detail/a_id/1754
  //    C5Xは幅145cm、奥行き198cm、前脚が前から33cm、左右から9cm、後脚は前脚から148cm、前脚左低音側から内側に33cm
  //    C6Xは幅150cm、奥行き210cm、前脚が前から40cm、左右から9cm、後脚は前脚から151cm、前脚左低音側から内側に32cm
  //
  if (kyakuchuuOn) {
    //  舟肘木のような部材を、前脚は前後、後脚は左右に向けて配置する
    //
    //                    -165               -75  -50        0         50   75               165 y
    //          z           +                 +    +         +         +    +                 +
    //         600          +-----------------------------------------------------------------+
    //                      |                                                                 |
    //                      |                                                                 |
    //                      |                                                                 |
    //         560          +------                                                     ------+
    //                             ~~~---                                         ---~~~
    //                                   ~~--                                 --~~
    //         530                           ~+----+-------------------+----+~
    //                                             |                   |
    //                                             |                   |
    //         500                                 |                   |
    //                                             |                   |
    //                                             |                   |
    //                                             |                   |
    //                                             |                   |
    //         450                                 |                   |
    //                                             |                   |
    //                      |                      |                   |                   \  |
    //                      | /                    |                   |                    \ |
    //         410          *                      |                   |                      *
    //         400         (1)                     |                   |                     (2)
    //                                             |                   |
    //                                             \                   /
    //                                              |                 |
    //                                              |                 |
    //         350                                  |                 |
    //                                              |                 |
    //                                              |                 |
    //                                              |                 |
    //                                              |                 |
    //         300                                  |                 |
    //                                              |                 |
    //                                              |                 |
    //                                              |                 |
    //                                              |                 |
    //         250                                  |                 |
    //                                              |                 |
    //                                              \                 /
    //                                               |               |
    //                                               |               |
    //         200                                   |               |
    //                                               |               |
    //                                               |               |
    //                                               |               |
    //                                               |               |
    //         150                                   |               |
    //                                               |               |
    //                                               |               |
    //                                               |               |
    //                                               |               |
    //         100                                   |               |
    //                                               |               |
    //          80                                   +---------------+
    //                                               +       +       +
    //                                              -40      0       40 y
    //
    //                                       -75  -50        0         50   75 x
    //          z                             +    +         +         +    +
    //         600                            +-----------------------------+
    //                                        |                             |
    //                                        |                             |
    //                                        |                             |
    //         560                            +-----------------------------+
    //                                        |                             |
    //                                        |                             |
    //         530                            +----+-------------------+----+
    //                                             |                   |
    //                                             |                   |
    //         500                                 |                   |
    //                                             |                   |
    //                                             |                   |
    //                                             |                   |
    //                                             |                   |
    //         450                                 |                   |
    //                                             |                   |
    //                                             |                   |
    //                                             |                   |
    //                                             |                   |
    //         400                                 |                   |
    //                                             |                   |
    //                                             \                   /
    //                                              |                 |
    //                                              |                 |
    //         350                                  |                 |
    //                                              |                 |
    //                                              |                 |
    //                                              |                 |
    //                                              |                 |
    //         300                                  |                 |
    //                                              |                 |
    //                                              |                 |
    //                                              |                 |
    //                                              |                 |
    //         250                                  |                 |
    //                                              |                 |
    //                                              \                 /
    //                                               |               |
    //                                               |               |
    //         200                                   |               |
    //                                               |               |
    //                                               |               |
    //                                               |               |
    //                                               |               |
    //         150                                   |               |
    //                                               |               |
    //                                               |               |
    //                                               |               |
    //                                               |               |
    //         100                                   |               |
    //                                               |               |
    //          80                                   +---------------+
    //                                               +       +       +
    //                                              -40      0       40 x
    //
    //
    const gap = 0.5;
    for (let pos = 0; pos < 3; pos++) {  //0=左前脚(-x),1=右前脚(+x),2=後脚(+y)
      let ox = pos == 0 ? pianoX0 + 100 : pos == 1 ? pianoX1 - 100 : pianoX0 + 450;
      let oy = pos < 2 ? pianoY0 + 350 : pianoY0 + 1850;
      let oz = pianoZ0;
      //枠
      let kyakuchuuWaku = phNewBox (ox - (pos < 2 ? 75 : 165), ox + (pos < 2 ? 75 : 165),
                                    oy - (pos < 2 ? 165 : 75), oy + (pos < 2 ? 165 : 75),
                                    oz, oz + 600,
                                    1, 1, 1, 1, 1, 1);
      zentaiHako.push (setupPolyhedron (kyakuchuuWaku, "kyakuchuu_waku_" + pos, COLOR_WAKU));
      kyakuchuuWaku.ph$isWaku = true;
      kyakuchuuWaku.ph$hakoNumber = hakoArray.length;
      //箱
      let kyakuchuuHako = [];
      hakoArray.push (kyakuchuuHako);
      //
      //funahijiki 舟肘木
      if (true) {
        let t = deg (atan2 (90, 120));
        let ph = phNewPolygonYZ (pgTurtle ("j165,600 d a180 f330 l90 f40 l90 cr" + t + ",150 l" + t + " f150 l" + t + " cr" + t + ",150"), [-75, 75]);
        if (pos == 2) {
          phRotateXY (ph, rad (90));  //後脚を90度回転させる
        }
        phTranslateXYZ (ph, ox, oy, oz);
        kyakuchuuHako.push (setupPolyhedron (ph, "funahijiki_" + pos, COLOR_BODY));
      }
      //kykuchuu 脚柱
      //             7+---------+6
      //             /|        /|
      //      z     / |       / |
      //     530  4+---------+5 |
      //           |  |      |  |       y
      //           | 3+------|--+2     40
      //           | /       | /
      //           |/        |/
      //      80  0+---------+1    -40
      //          -40        40 x
      if (true) {
        let ph = phNew ([[-40, -40, 80 + gap],  //0
                         [40, -40, 80 + gap],  //1
                         [40, 40, 80 + gap],  //2
                         [-40, 40, 80 + gap],  //3
                         [-50, -50, 530 - gap],  //4
                         [50, -50, 530 - gap],  //5
                         [50, 50, 530 - gap],  //6
                         [-50, 50, 530 - gap]],  //7
                        [[0, 4, 7, 3],  //-x
                         [1, 2, 6, 5],  //+x
                         [0, 1, 5, 4],  //-y
                         [2, 3, 7, 6],  //+y
                         [0, 3, 2, 1],  //-z open
                         [4, 5, 6, 7]],  //+z open
                        [0, 0, 0, 0, 1, 1]);
        phTranslateXYZ (ph, ox, oy, oz);
        kyakuchuuHako.push (setupPolyhedron (ph, "kyakuchuu_" + pos, COLOR_BODY));
      }
      //caster キャスター
      if (true) {
        //
        //         -50 -40 -30 -20 -10   0  10  20  30  40 y
        //       z  +  +  +  +  +  +  +  +  +  +
        //      80+    ┌───────────────┐
        //              │                              │  取付座
        //      70+    └┬─────────────┬┘
        //                └── ┬──────┬ ──┘    旋回部
        //      60+┌───── │3           │2
        //          │         / 4            │
        //      50+│       /                │
        //          │    5/                  │           本体
        //      40+│    │                   │
        //          │    │                 / 1
        //      30+│    │    ○         /               車軸
        //          │    │             / │
        //      20+│    │           /   │
        //          │    └─────0     │
        //      10+│                      │              車輪
        //          │                      │
        //       0+└───────────┘
        //          +  +  +  +  +  +  +  +  +  +
        //         -50 -40 -30 -20 -10   0  10  20  30  40 y
        //       x  +  +  +  +  +  +  +  +  +  +
        //      80+    ┌───────────────┐
        //              │┌─────────────┐│
        //      70+    ││     ┌──────┐     ││
        //              ││     └──────┘     ││
        //      60+┌───────────┐        ││
        //          │                      │        ││
        //      50+│                      │        ││
        //          │                      │        ││
        //      40+│                      │        ││
        //          │                      │        ││
        //      30+│                      │        ││
        //          │                      │        ││
        //      20+└───────────┘        ││
        //              ││     ┌──────┐     ││
        //      10+    ││     └──────┘     ││
        //              │└─────────────┘│
        //       0+    └───────────────┘
        //          +  +  +  +  +  +  +  +  +  +
        //         -50 -40 -30 -20 -10   0  10  20  30  40 y
        //
        //toritsukeza 取付座
        if (true) {
          let ph = phNewBox (-40, 40,
                             -40, 40,
                             70 + gap, 80 - gap,
                             0, 0, 0, 0, 0, 1);  //+z open
          phTranslateXYZ (ph, ox, oy, oz);
          kyakuchuuHako.push (setupPolyhedron (ph, "caster_" + pos + "_toritsukeza", COLOR_CASTER));
        }
        //senkaibu 旋回部
        if (true) {
          let ph = phNewCylinderXY (0, 0, 35, 65 + gap, 70 - gap);
          phTranslateXYZ (ph, ox, oy, oz);
          kyakuchuuHako.push (setupPolyhedron (ph, "caster_" + pos + "_senkaibu", COLOR_CASTER));
        }
        //hontai 本体
        if (true) {
          for (let k = 0; k < 2; k++) {
            let x0 = -30 + 55 * k;
            let x1 = x0 + 5;
            let ph = phNewPolygonYZ (pgTurtle ("j17.5,40 d a90 f" + (24 + gap) + " l90 f35 l90 f" + (4 + gap) + " r45 f" + (17.5 * sqrt (2)) + " cl180," + (27.5 / sqrt (2))), [x0, x1]);
            phTranslateXYZ (ph, ox, oy, oz);
            kyakuchuuHako.push (setupPolyhedron (ph, "caster_" + pos + "_hontai" + k, COLOR_CASTER));
          }
        }
        //shajiku 車軸
        //sharin 車輪
        if (true) {
          let ph = phNewCylinderYZ (-20, 30, 30, -20, 20);
          phTranslateXYZ (ph, ox, oy, oz);
          kyakuchuuHako.push (setupPolyhedron (ph, "caster_" + pos + "_sharin", COLOR_CASTER));
        }
      }
    }
  }

  //spacer 後脚のスペーサー
  if (spacerOn) {
    //
    //                   200      250 260 285 300      350       400       450       500       550      600 615  640 x
    //          y         +         + +    +  +         +         +         +         *         +         +  +    +
    //        2000                                                      1997*         |
    //          90                                            1990*                   |
    //          80                                  1977*                             |                           |
    //          70                                                                    |                           |
    //          60                        1958*                                       |                           |
    //          50                     1951*                                          |                           |
    //          40                1939*                                               |                           |
    //          30              1933* |    ___________________________________________________________________    |
    //          20                    |    |(285,1925)                                                       |    |
    //          10                    |    |                                                                 |    |
    //        1900    1900*           |    |                                                                 |    |
    //          90                    |    |                                                                 |    |
    //          80                    |    |                                                                 |    |
    //          70                    |    |                                                                 |    |
    //          60                    |    |                                                                 |    |
    //          50                    |    |                                +(450,1850)                      |    |
    //          40                    |    |                                                                 |    |
    //          30                    |    |                                                                 |    |
    //          20                    |    |                                                                 |    |
    //          10                    |    |                                                                 |    |
    //        1800                    |    |                                                                 |    |
    //          90                    |    |                                                                 |    |
    //          80                    |    |(285,1775)                                                       |    |
    //          70                    |    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    |
    //          60                    |                                                                           |
    //          50                   0+---------------------------------------------------------------------------+1
    const gap = 0.5;
    let va = [[260, 1750],  //0
              [640, 1750]];  //1
    for (let x = 640; 500 < x; x -= 20) {
      let y = 1400 + sqrt (600 ** 2 - (x - 500) ** 2);
      va.push ([x, y]);
    }
    for (let x = 500; 260 <= x; x -= 40) {
      let y = 1500 + sqrt (500 ** 2 - (500 - x) ** 2);
      va.push ([x, y]);
    }
    let ph = phNewPolygonXY1 (va, [600 + gap, 645 - gap]);
    phTranslateXYZ (ph, pianoX0, pianoY0, pianoZ0);
    zentaiHako.push (setupPolyhedron (ph, "spacer", COLOR_BODY));
  }

  //pedal ペダル
  //  左
  //    ソフトペダル(グランドピアノ)
  //      ハンマーを横にずらす。弦が3本の鍵は2本、弦が2本の鍵は1本だけ叩くことで音量を抑える。弱音ペダル。シフトペダル
  //    ソフトペダル(アップライトピアノ)
  //      ハンマーを弦に近づける。弦を弱く叩くことで音量を抑える。弱音ペダル
  //  中央
  //    ソステヌートペダル(グランドピアノ)
  //      押している鍵のダンパーを弦から離す
  //    マフラーペダル(アップライトピアノ)
  //      ハンマーと弦の間にフェルトを挟む。音が小さくなる。練習用。消音ペダル
  //  右
  //    ダンパーペダル、ラウドペダル、フォルテペダル、サスティニングペダル
  //      すべての鍵のダンパーを弦から離す。叩いていない弦も共鳴してよく響く
  if (pedalOn) {
    //
    //              ------
    //              111111------------------
    //              221100998877665544332211-  112233
    //              505050505050505050505050505050505 y
    //              +  +  +           + +         + +
    //      -195                      +
    //      -185                     /|
    //      -175                    / |
    //      -165                   /  |
    //      -155                  /   |
    //      -145        150  120/     |100
    //      -135               /      |
    //      -125              /       |
    //      -115             /        |
    //      -105           /          |      70
    //       -95       /~~/-          +-------------+
    //       -85      /30/| ~~--    20| +---------+ |
    //       -75      \ / |     ~~~---+ |    50   | |
    //       -65       +--+-----------+ |50       | |
    //       -55        ~~---    60 20| |    ~    | |
    //       -45        15   ~~~~-----+ |         | |
    //       -35                    30| +---------+ |
    //       -25                      |             |
    //       -15      -+--------------+             |
    //       -05    |  |15    75    30|             |190
    //        05    |~~|15            |      ~      |
    //        15      -+--------------+             |
    //        25     15             30|             |
    //        35                      | +---------+ |
    //        45                 -----+ |    50   | |
    //        55        15---~~~~60 20| |50       | |
    //        65       +--+-----------+ |    ~    | |
    //        75      / \ |        ---+ |         | |
    //        85      \30\|   --~~~ 20| +---------+ |
    //        95       \  \-~~        +-------------+
    //       105        ~~ \          |
    //       115             \        |
    //       125              \       |
    //       135               \      |
    //       145        150  120\     |100
    //       155                  \   |
    //       165                   \  |
    //       175                    \ |
    //       185                     \|
    //       195                      +
    //        x     +  +  +           + +         + +
    //              ------
    //              111111------------------
    //              221100998877665544332211-  112233
    //              505050505050505050505050505050505 y
    //              +                 + +         + +
    //        z
    //       600                        +---------+
    //       590                        |         |
    //     :::::  ::::::::::::::::::::::::::::::::::::::::
    //        70                        |         |
    //        60                      +-+---------+-+
    //        50    +-----------------|             |
    //        40    |                 |             |
    //        30    ~~~~~~~~~~~~~~~~~~|             |
    //        20                      ~~~~~~~~~~~~~~~
    //              +                 + +         + +
    //              ------
    //              111111------------------
    //              221100998877665544332211-  112233
    //              505050505050505050505050505050505 y
    //
    const gap = 0.5;
    let ox = (pianoX0 + pianoX1) / 2;
    let oy = pianoY0 + 350;
    let oz = pianoZ0;
    //枠
    let pedalWaku = phNewBox (ox - 95, ox + 95,
                              oy - 125, oy + 35,
                              oz + 5, oz + 600,  //oz+20,oz+600
                              1, 1, 1, 1, 1, 1);
    zentaiHako.push (setupPolyhedron (pedalWaku, "pedal_waku", COLOR_WAKU));
    pedalWaku.ph$isWaku = true;
    pedalWaku.ph$hakoNumber = hakoArray.length;
    //箱
    let pedalHako = [];
    hakoArray.push (pedalHako);
    //
    //hako 箱
    if (true) {
      let ph = phNewBox (-95, 95,
                         -33, 35,  //-35+gap,35
                         25, 60);
      phTranslateXYZ (ph, ox, oy, oz);
      pedalHako.push (setupPolyhedron (ph, "pedal_hako", COLOR_BODY));
    }
    //hashira 柱
    if (true) {
      for (let k = 0; k < 2; k++) {  //0=左の柱,1=右の柱
        let x = -60 + 120 * k;
        let ph = phNewBox (x - 25, x + 25,
                           -25, 25,
                           60 + gap, 600 - gap,
                           0, 0,
                           0, 0,
                           1, 1);  //-z open +z open
        phTranslateXYZ (ph, ox, oy, oz);
        pedalHako.push (setupPolyhedron (ph, "pedal_hashira_" + k, COLOR_BODY));
      }
    }
    //pedal ペダル
    if (true) {
      const hingeX = ox;
      const hingeY = oy + 20;
      const hingeZ = oz + 35;
      pedalPha1 = [];
      pedalPhaA2 = [];
      pedalPhaK = [];
      for (let num = 0; num < 3; num++) {
        let pha1 = [phTranslateXYZ (phNewPolygonXY (pgTurtle (num == 0 ? "j-75,-35 d a-90 cr30,120 cl180,15 cl30,150" :  //左ペダル
                                                              num == 1 ? "j-15,-35 d a-90 f75 cl180,15 f75" :  //中央ペダル
                                                              "j45,-35 d a-90 cl30,150 cl180,15 cr30,120"),  //右ペダル
                                                    [35, 50]),
                                    ox, oy, oz)];
        for (let i = 0; i < pha1.length; i++) {
          pedalHako.push (setupPolyhedron (pha1[i], "pedal_" + num + "_" + i, COLOR_PEDAL));
          setMousedownAction (pha1[i], "pedal_" + num);
        }
        let phaA2 = [];
        for (let pos = 0; pos <= 1; pos++) {
          let pha2 = [];
          for (let i = 0; i < pha1.length; i++) {
            pha2[i] = phTranslateXYZ (phRotateYZ (phTranslateXYZ (phNewCopy (pha1[i]),
                                                                  -hingeX, -hingeY, -hingeZ),
                                                  rad (7.5 * pos)),
                                      hingeX, hingeY, hingeZ);
          }
          phaA2[pos] = pha2;
        }
        pedalPha1[num] = pha1;
        pedalPhaA2[num] = phaA2;
        pedalPhaK[num] = 0;
      }
    }
  }

  //kiban 基板
  if (kibanOn) {
    let x0 = pianoX0 * 0.9 + pianoX1 * 0.1;
    let xm = pianoX0 * 0.5 + pianoX1 * 0.5;
    let x1 = pianoX0 * 0.3 + pianoX1 * 0.7;
    let y0 = maekamachiY1 * 0.95 + pianoY1 * 0.05;
    let ym = maekamachiY1 * 0.45 + pianoY1 * 0.55;
    let y1 = maekamachiY1 * 0.2 + pianoY1 * 0.8;
    let z0 = yaneZ0 - 210 + 1;
    let z1 = yaneZ0 - 200 - 1;
    let ph = phNewPolygonXY1 ([[x0, y0],
                               [x1, y0],
                               [x1, ym],
                               [xm, ym],
                               [xm, y1],
                               [x0, y1]], [z0, z1]);
    zentaiHako.push (setupPolyhedron (ph, "kiban", COLOR_KIBAN));
  }

  //YM2151
  if (ym2151On) {
    let ox = pianoX0 * 0.75 + pianoX1 * 0.25;
    let oy = maekamachiY1 * 0.7 + pianoY1 * 0.3;
    let oz = yaneZ0 - 200;
    for (let kk = 0; kk < 2; kk++) {
      let bx = 2.54 * 9 * kk;
      //枠
      let ym2151Waku = phNewBox (ox + (bx - 7.8) * 20, ox + (bx + 7.8) * 20,
                                 oy - 15.9 * 20, oy + 15.9 * 20,
                                 oz, oz + 4.3 * 20,
                                 1, 1, 1, 1, 1, 1);
      zentaiHako.push (setupPolyhedron (ym2151Waku, "ym2151_waku_" + kk, COLOR_WAKU));
      ym2151Waku.ph$isWaku = true;
      ym2151Waku.ph$hakoNumber = hakoArray.length;
      //箱
      let ym2151Hako = [];
      hakoArray.push (ym2151Hako);
      //
      //  ishi 石
      //       -6  -5  -4  -3  -2  -1   0   1   2   3   4   5   6
      //   -3     *   *   *   *   *   *   *   *   *   *   *   *
      //       +-------------------------------------------------+
      //   -2  |  *   *   *   *   *   *   *   *   *   *   *   *  |
      //       |                                                 |
      //   -1  |  *   *   *   *   *   *   *   *   *   *   *   *  |
      //       |                                                 |
      //    0  |  *   *   *   *   *   * + *   *   *   *   *   *  |
      //       |                                                 |
      //    1  |  *   *   *   *   *   *   *   *   *   *   *   *  |
      //       |                                                 |
      //    2  |  *   *   *   *   *   *   *   *   *   *   *   *  |
      //       +-------------------------------------------------+
      //    3     *   *   *   *   *   *   *   *   *   *   *   *
      //    x
      if (true) {
        let ph = phNewBox (-6.3, 6.3,
                           -15.9, 15.9,
                           0.2, 4.0);  //mm
        phTranslateXYZ (ph, bx, 0, 0);
        phScaleXYZ (ph, 20, 20, 20);
        phTranslateXYZ (ph, ox, oy, oz);
        ym2151Hako.push (setupPolyhedron (ph, "ym2151_" + kk + "_ishi", COLOR_ISHI));
      }
      //  ashi 足
      if (true) {
        //     z
        //    24
        //    22  +------------+
        //    20  |            |
        //    18  +--------+   |
        //    16           |   |     2.5*2.54=6.35
        //    14           |   |     3.0*2.54=7.62
        //    12           |   |
        //    10           |   |
        //     8           |   |
        //     6           |   |
        //     4           |   |
        //     2           +---+
        //     0  --------------
        //        66666777777777
        //        56789012345678 x
        for (let k = 0; k < 2; k++) {
          //枠
          let waku = phNewBox (k == 0 ? ox + (bx - 7.8) * 20 : ox + (bx + 6.5) * 20,
                               k == 0 ? ox + (bx - 6.5) * 20 : ox + (bx + 7.8) * 20,
                               oy - (5.5 * 2.54 + 0.6) * 20,
                               oy + (5.5 * 2.54 + 0.6) * 20,
                               oz + 0.2 * 20,
                               oz + 2.2 * 20,
                               1, 1, 1, 1, 1, 1);
          ym2151Hako.push (setupPolyhedron (waku, "ym2151_" + kk + "_ashi_" + k + "_waku", COLOR_WAKU));
          waku.ph$isWaku = true;
          waku.ph$hakoNumber = hakoArray.length;
          //箱
          let hako = [];
          hakoArray.push (hako);
          //
          for (let j = 0; j <= 11; j++) {
            let y = (j - 5.5) * 2.54;
            //          z    x
            let va = [[2.2, 6.5],  //xzで見て右回り
                      [2.2, 7.8],
                      [0.2, 7.8],
                      [0.2, 7.4],
                      [1.8, 7.4],
                      [1.8, 6.5]];
            let ph = phNewPolygonZX1 (va, [y - 0.6, y + 0.6]);
            if (k == 0) {  //-x側
              phRotateXY (ph, rad (180));
            }
            phTranslateXYZ (ph, bx, 0, 0);
            phScaleXYZ (ph, 20, 20, 20);
            phTranslateXYZ (ph, ox, oy, oz);
            hako.push (setupPolyhedron (ph, "ym2151_" + kk + "_ashi_" + k + "_" + j, COLOR_PIN));
          }
        }
      }
      //  moji 文字
      //                             1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 4 4 4
      //         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 y
      //         0           1     5           7      10      11        16      19          18      27
      //     0  ●          ●    ●          ●      ●───●        ●      ●─────●      ●
      //     1    \      /      │\      /│    ●          ●12    │      │                  │
      //     2      \  /        │  \  /  │     9          ●13    │      │        21        │
      //     3        ●2         │    ●    │              /        │    20●────●        │
      //     4        │          │     6    │            /          │                  ●22    │
      //     5        │          │          │          /            │                  │      │
      //     6        │          │          │        /              │                  │      │
      //     7        │          │          │      /                │    26●          ●23    │
      //     8        ●          ●          ●    ●─────●      ●        ●───●        ●
      //     x         3           4           8    14          15      17        25      24        28
      //                             1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 4 4 4
      //         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 y
      if (true) {
        pgStrokeLinecap = "round";
        pgStrokeLinejoin = "round";
        let pg = pgPolyline ({
          pl$vertexArray: [[0, 0], [0, 6], [3, 3], [8, 3],  //0-3  Y
                           [8, 9], [0, 9], [3, 12], [0, 15], [8, 15],  //4-8  M
                           [1, 18], [0, 19], [0, 23], [1, 24], [2, 24], [8, 18], [8, 24],  //9-15  2
                           [0, 28], [8, 28],  //16-27  1
                           [0, 38], [0, 32], [4, 32], [4, 37], [5, 38], [7, 38], [8, 37], [8, 33], [7, 32],  //18-26  5
                           [0, 42], [8, 42]],  //27-28  1
          pl$edgeArray: [[2], [2], [0, 3, 1], [2],  //0-3  Y
                         [5], [4, 6], [5, 7], [6, 8], [7],  //4-8  M
                         [10], [9, 11], [10, 12], [11, 13], [12, 14], [13, 15], [14],  //9-15  2
                         [17], [16],  //16-17  1
                         [19], [18, 20], [19, 21], [20, 22], [21, 23], [22, 24], [23, 25], [24, 26], [25],  //18-26  5
                         [28], [27]]  //27-28  1
          }, 1);
        let ph = phNewPolygonXY (pg, [0, 0.2]);
        phTranslateXYZ (ph, -8 / 2, -42 / 2, 0);
        phScaleXYZ (ph, 0.5, 0.5, 0.5);  //文字の高さ4mm厚み0.1mm
        phTranslateXYZ (ph, bx, 0, 4.2);  //4.2mm持ち上げて石の上に乗せる
        phScaleXYZ (ph, 20, 20, 20);
        phTranslateXYZ (ph, ox, oy, oz);
        ym2151Hako.push (setupPolyhedron (ph, "ym2151_" + kk + "_moji", COLOR_MOJI));
      }
    }
  }

  //MSM6258V
  if (msm6258vOn) {
    let ox = pianoX0 * 0.7 + pianoX1 * 0.3;
    let oy = maekamachiY1 * 0.35 + pianoY1 * 0.65;
    let oz = yaneZ0 - 200;
    //枠
    let msm6258vWaku = phNewBox (ox - 6.4 * 20, ox + 6.4 * 20,
                                 oy - 7.0 * 20, oy + 7.0 * 20,
                                 oz, oz + 2.3 * 20,
                                 1, 1, 1, 1, 1, 1);
    zentaiHako.push (setupPolyhedron (msm6258vWaku, "msm6258v_waku", COLOR_WAKU));
    msm6258vWaku.ph$isWaku = true;
    msm6258vWaku.ph$hakoNumber = hakoArray.length;
    //箱
    let msm6258vHako = [];
    hakoArray.push (msm6258vHako);
    //
    //          ------------------------
    //          555544444333332222211111----     111112222233333444445555
    //          642086420864208642086420864202468024680246802468024680246 y
    //     -48          *   *   *   *   *   *   *   *   *   *   *
    //     -44     +-------------------------------------------------+
    //     -40  *  |*   *   *   *   *   *   *   *   *   *   *   *   *|  *
    //     -36     |                                                 |
    //     -32  *  |*   *   *   *   *   *   *   *   *   *   *   *   *|  *
    //     -28     |                                                 |
    //     -24  *  |*   *   *   *   *   *   *   *   *   *   *   *   *|  *
    //     -20     |                                                 |
    //     -16  *  |*   *   *   *   *   *   *   *   *   *   *   *   *|  *
    //     -12     |                                                 |
    //      -8  *  |*   *   *   *   *   *   *   *   *   *   *   *   *|  *
    //      -4     |                                                 |
    //       0  *  |*   *   *   *   *   *   +   *   *   *   *   *   *|  *
    //       4     |                                                 |
    //       8  *  |*   *   *   *   *   *   *   *   *   *   *   *   *|  *
    //      12     |                                                 |
    //      16  *  |*   *   *   *   *   *   *   *   *   *   *   *   *|  *
    //      20     |                                                 |
    //      24  *  |*   *   *   *   *   *   *   *   *   *   *   *   *|  *
    //      28     |                                                 |
    //      32  *  |*   *   *   *   *   *   *   *   *   *   *   *   *|  *
    //      36     |                                                 |
    //      40  *  |*   *   *   *   *   *   *   *   *   *   *   *   *|  *
    //      44     +-------------------------------------------------+
    //      48          *   *   *   *   *   *   *   *   *   *   *
    //       x
    //  ishi 石
    if (true) {
      let ph = phNewBox (-4.4, 4.4,
                         -5.0, 5.0,
                         0.2, 2.0);  //mm
      phScaleXYZ (ph, 20, 20, 20);
      phTranslateXYZ (ph, ox, oy, oz);
      msm6258vHako.push (setupPolyhedron (ph, "msm6258v_ishi", COLOR_ISHI));
    }
    //  ashi 足
    //     z
    //    10    +-----+
    //     8    +---+ |
    //     6        | |
    //     4        | +-----------+
    //     2        +-------------+
    //     0  ---------------------
    //        444444555555555566666
    //        456789012345678901234 x
    if (true) {
      for (let kk = 0; kk <= 1; kk++) {
        //枠
        let waku = phNewBox (kk == 0 ? ox - 6.4 * 20 : ox + 4.6 * 20,
                             kk == 0 ? ox - 4.6 * 20 : ox + 6.4 * 20,
                             oy - (0.8 * 5 + 0.15) * 20,
                             oy + (0.8 * 5 + 0.15) * 20,
                             oz + 0.2 * 20,
                             oz + 1.0 * 20,
                             1, 1, 1, 1, 1, 1);
        msm6258vHako.push (setupPolyhedron (waku, "msm6258v_ashi_x_" + kk + "_waku", COLOR_WAKU));
        waku.ph$isWaku = true;
        waku.ph$hakoNumber = hakoArray.length;
        //箱
        let hako = [];
        hakoArray.push (hako);
        //
        for (let k = 0; k <= 10; k++) {
          let y = 0.8 * (k - 5);
          //          z    x
          let va = [[1.0, 4.6],  //xzで見て右回り
                    [1.0, 5.2],
                    [0.4, 5.2],
                    [0.4, 6.4],
                    [0.2, 6.4],
                    [0.2, 5.0],
                    [0.8, 5.0],
                    [0.8, 4.6]];
          let ph = phNewPolygonZX1 (va, [y - 0.15, y + 0.15]);
          if (kk == 0) {  //-y側
            phRotateXY (ph, rad (180));
          }
          phScaleXYZ (ph, 20, 20, 20);
          phTranslateXYZ (ph, ox, oy, oz);
          hako.push (setupPolyhedron (ph, "msm6258v_ashi_x_" + kk + "_" + k, COLOR_PIN));
        }
      }
      //     z
      //    10    +-----+
      //     8    +---+ |
      //     6        | |
      //     4        | +-----------+
      //     2        +-------------+
      //     0  ---------------------
      //        555555555566666666667
      //        012345678901234567890 y
      for (let kk = 0; kk <= 1; kk++) {
        //枠
        let waku = phNewBox (ox - (0.8 * 5 + 0.15) * 20,
                             ox + (0.8 * 5 + 0.15) * 20,
                             kk == 0 ? oy - 7.0 * 20 : oy + 5.2 * 20,
                             kk == 0 ? oy - 5.2 * 20 : oy + 7.0 * 20,
                             oz + 0.2 * 20,
                             oz + 1.0 * 20,
                             1, 1, 1, 1, 1, 1);
        msm6258vHako.push (setupPolyhedron (waku, "msm6258v_ashi_y_" + kk + "_waku", COLOR_WAKU));
        waku.ph$isWaku = true;
        waku.ph$hakoNumber = hakoArray.length;
        //箱
        let hako = [];
        hakoArray.push (hako);
        //
        for (let k = 0; k <= 10; k++) {
          let x = 0.8 * (k - 5);
          //          y    z
          let va = [[5.2, 0.8],  //yzで見て左回り
                    [5.6, 0.8],
                    [5.6, 0.2],
                    [7.0, 0.2],
                    [7.0, 0.4],
                    [5.8, 0.4],
                    [5.8, 1.0],
                    [5.2, 1.0]];
          let ph = phNewPolygonYZ1 (va, [x - 0.15, x + 0.15]);
          if (kk == 0) {  //-y側
            phRotateXY (ph, rad (180));
          }
          phScaleXYZ (ph, 20, 20, 20);
          phTranslateXYZ (ph, ox, oy, oz);
          hako.push (setupPolyhedron (ph, "msm6258v_ashi_y_" + kk + "_" + k, COLOR_PIN));
        }
      }
    }
    //  moji 文字
    //                             1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 5 5
    //         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 y
    //         1           3       7       6        18      19      25          24      34      33      49          53
    //     0  ●          ●      ●───●        ●───●      ●─────●      ●───●48    ●          ●
    //     1  │\      /│   8●          ●5   ●          ●20  │              35●          ●47  │          │
    //     2  │  \  /  │    │15      14      17          ●21  │        27    36●37      38●46  │          │
    //     3  │    ●    │    │●───●                /    26●────●        ●───●45    │          │
    //     4  │     2    │  16●          ●13          /                    ●2839●          ●44  │          │
    //     5  │          │    │          │          /                      │    │          │  50●          ●52
    //     6  │          │    │          │        /                        │    │          │      \      /
    //     7  │          │   9●          ●12    /            32●          ●2940●          ●43      \  /
    //     8  ●          ●      ●───●      ●─────●      ●───●        ●───●            ●
    //     x   0           4      10      11      22          23      31      30        41      42            51
    //                             1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 5 5
    //         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 y
    if (true) {
      pgStrokeLinecap = "round";
      pgStrokeLinejoin = "round";
      let pg = pgPolyline ({
        pl$vertexArray: [[8, 0], [0, 0], [3, 3], [0, 6], [8, 6],  //0-4  M
                         [1, 15], [0, 14], [0, 10], [1, 9], [7, 9], [8, 10], [8, 14], [7, 15], [4, 15], [3, 14], [3, 10], [4, 9],  //5-16  6
                         [1, 18], [0, 19], [0, 23], [1, 24], [2, 24], [8, 18], [8, 24],  //17-23  2
                         [0, 33], [0, 27], [3, 27], [3, 32], [4, 33], [7, 33], [8, 32], [8, 28], [7, 27],  //24-32  5
                         [0, 41], [0, 37], [1, 36], [2, 36], [3, 37], [3, 41], [4, 36], [7, 36], [8, 37], [8, 41], [7, 42], [4, 42], [3, 41], [2, 42], [1, 42], [0, 41],  //33-48  8
                         [0, 45], [5, 45], [8, 48], [5, 51], [0, 51]],  //49-53  V
        pl$edgeArray: [[1], [0, 2], [1, 3], [2, 4], [3],  //0-4  M
                       [6], [5, 7], [6, 8], [7, 9], [8, 10], [9, 11], [10, 12], [11, 13], [12, 14], [13, 15], [14, 16], [15],  //5-16  6
                       [18], [17, 19], [18, 20], [19, 21], [20, 22], [21, 23], [22],  //17-23  2
                       [25], [24, 26], [25, 27], [26, 28], [27, 29], [28, 30], [29, 31], [30, 32], [31],  //24-32  5
                       [34], [33, 35], [34, 36], [35, 37], [36, 38, 39], [37], [37, 40], [39, 41], [40, 42], [41, 43], [42, 44], [43, 45], [44, 46], [45, 47], [46, 48], [47],  //33-48  8
                       [50], [49, 51], [50, 52], [51, 53], [52]]  //49-53  V
        }, 1);
      let ph = phNewPolygonXY (pg, [0, 0.2]);
      phTranslateXYZ (ph, -8 / 2, -51 / 2, 0);
      phScaleXYZ (ph, 0.15, 0.15, 0.15);  //文字の高さ1.2mm厚み0.03mm
      phTranslateXYZ (ph, 0, 0, 2.2);  //2.2mm持ち上げて石の上に乗せる
      phScaleXYZ (ph, 20, 20, 20);
      phTranslateXYZ (ph, ox, oy, oz);
      msm6258vHako.push (setupPolyhedron (ph, "msm6258v_moji", COLOR_MOJI));
    }
  }

  //椅子
  //       z
  //      500 +---+---------------+---+
  //          |   |               |   |
  //          +---+               +---+
  //      425 +-+-------------------+-+
  //      400 +-+-------------------+-+
  //          |                       |
  //      350 |   +---------------+   |
  //          |   |               |   |
  //      300 |   |               |   |
  //          |   |               |   |
  //          |   |               |   |
  //          |   |               |   |
  //      200 |   |               |   |
  //          |   |               |   |
  //          |   |               |   |
  //          |   |               |   |
  //      100 |   |               |   |
  //          |   |               |   |
  //          |   |               |   |
  //          |   |               |   |
  //        0 +---+               +---+
  //          0   50             250 300 y
  if (isuOn) {
    const isuWidth = 600;
    const isuHeight = 250;
    const isuDepth = 500;
    const isuX0 = (pianoX0 + pianoX1 - isuWidth) * 0.5;
    const isuX1 = (pianoX0 + pianoX1 + isuWidth) * 0.5;
    const isuY1 = pianoY0 - 300;
    const isuY0 = isuY1 - isuHeight;
    const isuZ0 = pianoZ0;
    const isuZ1 = isuZ0 + isuDepth;
    //枠
    let isuWaku = phNewBox (isuX0, isuX1, isuY0, isuY1, isuZ0, isuZ1,
                            1, 1, 1, 1, 1, 1);
    zentaiHako.push (setupPolyhedron (isuWaku, "isu_waku", COLOR_WAKU));
    isuWaku.ph$isWaku = true;
    isuWaku.ph$hakoNumber = hakoArray.length;
    //箱
    let isuHako = [];
    hakoArray.push (isuHako);
    //座面
    {
      let ph = phTranslateXYZ (phNewPolygonYZ (pgTurtle ("j0," + (isuDepth - 75) + " d a0 f" + isuHeight + " l90 f25 cl90,50 f" + (isuHeight - 100) + " cl90,50 u"),
                                               [0, isuWidth]),
                               isuX0, isuY0, isuZ0);
      isuHako.push (setupPolyhedron (ph, "isu_zamen", COLOR_ISU));
    }
    //リフト
    {
      let ph = phTranslateXYZ (phNewBox (50, isuWidth - 50, 50, isuHeight - 50, isuDepth - 100, isuDepth - 75,
                                         0, 0, 0, 0, 1, 1),
                               isuX0, isuY0, isuZ0);
      isuHako.push (setupPolyhedron (ph, "isu_lift", COLOR_LIFT));
    }
    //台
    {
      let ph = phTranslateXYZ (phNewBox (0, isuWidth, 0, isuHeight, isuDepth - 175, isuDepth - 100),
                               isuX0, isuY0, isuZ0);
      isuHako.push (setupPolyhedron (ph, "isu_dai", COLOR_ISU));
    }
    //足
    for (let j = 0; j < 2; j++) {
      let y = (isuHeight - 50) * j;
      for (let i = 0; i < 2; i++) {
        let x = (isuWidth - 50) * i;
        let ph = phTranslateXYZ (phNewBox (x, x + 50, y, y + 50, 0, isuDepth - 175,
                                           0, 0, 0, 0, 1, 1),
                                 isuX0, isuY0, isuZ0);
        isuHako.push (setupPolyhedron (ph, "isu_ashi_" + i + "_" + j, COLOR_ISU));
      }
    }
  }

}


//--------------------------------------------------------------------------------
//y = softLanding (x)
//  ソフトランディング関数
//  0<=y<=1  出力
//  0<=x<=1  入力
//  ピアノの鍵盤蓋には指を挟んで怪我をしないようにソフトランディング機構が付いているものがある
//  鍵盤蓋の開閉速度を角度によって変えることでそれっぽく見せる
//
//  perl -e "use lib'.';use Graph;$g=new Graph(80,40,0,1,0,1);$g->grid();sub f{(1-cos($_[0]*$Graph::PI))/2;}$g->func(*f,0,1);print$g;"
//    +                                                                         *******
//    |                                                                     *****      
//    |                                                                  ****          
//    |                                                                ***             
//    |                                                              ***               
//    |                                                            ***                 
//    |                                                          ***                   
//    |                                                        ***                     
//    |                                                       **                       
//    |                                                     ***                        
//    |                                                    **                          
//    |                                                  ***                           
//    |                                                 **                             
//    |                                               ***                              
//    |                                              **                                
//    |                                             **                                 
//    |                                           ***                                  
//    |                                          **                                    
//    |                                         **                                     
//    |                                        **                                      
//    |                                      ***                                       
//    |                                     **                                         
//    |                                    **                                          
//    |                                   **                                           
//    |                                 ***                                            
//    |                                **                                              
//    |                               **                                               
//    |                             ***                                                
//    |                            **                                                  
//    |                          ***                                                   
//    |                         **                                                     
//    |                       ***                                                      
//    |                      **                                                        
//    |                    ***                                                         
//    |                  ***                                                           
//    |                ***                                                             
//    |              ***                                                               
//    |            ***                                                                 
//    |         ****                                                                   
//    |     *****                                                                      
//    *******-------------------------------------------------------------------------+
function softLanding (x) {
  return (1 - cos (x * PI)) * 0.5;
}


//--------------------------------------------------------------------------------
//  パーツを開閉できるようにする
function setMousedownAction (ph, elementType) {
  let polygonArray = ph.ph$polygonArray;
  for (let polygonNumber = 0; polygonNumber < polygonArray.length; polygonNumber++) {
    let polygon = polygonArray[polygonNumber];
    let elementArray = polygon.pg$elementArray;
    for (let screenNumber = 0; screenNumber <= 2; screenNumber++) {
      let element = elementArray[screenNumber];
      addEvent (element, "mousedown", function () {
        mouseDownElementType = elementType;
      });
    }
  }
}

//  譜面台を開閉する
function fumendaiOpenClose () {
  if (yanePhaK != yanePhaN) {  //屋根が開いていないときは譜面台を開閉できない
    return;
  }
  //開閉タスクを起動する
  if (fumendaiPhaK == 0) {  //閉じている
    mouseOpeningClosing = true;  //開閉中
    fumendaiPhaD = 1;  //開く
←Previous | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Next→