coding UTF-8; // 文字化け予防 // 使用するライブラリの読み込み import GUI; import Graphics; import Graphics2D; import Color; import Math; // ウィンドウのサイズ const int WINDOW_WIDTH = 450; const int WINDOW_HEIGHT = 570; // 角度ディスプレイのサイズの位置 const int DISPLAY_WIDTH = 450; const int DISPLAY_HEIGHT = 410; const int DISPLAY_Y = 80; // 角度ディスプレイの円の半径 const int CIRCLE_RADIUS = 175; // GUIコンポーネントのIDを控える変数 int window = NULL; int radianInputField = NULL; int degreeInputField = NULL; int radianToDegreeButton = NULL; int degreeToRadianButton = NULL; int radianOverPiLabel = NULL; int angleSlider = NULL; int displayLabel = NULL; // 角度ディスプレイの描画エンジンとグラフィックスリソースのID int displayRenderer = NULL; int displayGraphics = NULL; // プログラム実行時に、自動で呼び出される main 関数 // (このプログラムの処理はここから始まります) void main() { // ウィンドウのGUI類を構築 initializeWindow(); // 角度ディスプレイの初回描画 updateDisplay(0.0); // GUIアプリなので、コンソール画面は不要なので非表示にする hide(); } // 度数法での角度を、ラジアンの値に変換する関数 // ----- // * 引数 degree: 度数法での角度の値 float degreeToRadian(float degree) { // 1度あたりのラジアン float radianPerDegree = (2.0 * PI) / 360.0; // 上記に度の値をかけて、ラジアン値を求める float radian = radianPerDegree * degree; return radian; } // ラジアンを、度数法での角度に変換する関数 // ----- // * 引数 radian: ラジアンの値 float radianToDegree(float radian) { // 1ラジアンあたりの度数 float degreePerRadian = 360.0 / (2.0 * PI); // 上記にラジアン値をかけて、度の値を求める float degree = degreePerRadian * radian; return degree; } // ウィンドウや、その上のGUI部品などを構築する処理 void initializeWindow() { // ウィンドウを生成(この上に各種GUI部品を配置していく) window = newWindow(50, 50, WINDOW_WIDTH, WINDOW_HEIGHT, "Radian Converter"); // 度数法での角度入力欄の上に、文字列ラベルを生成/配置 int degreeLabel = newTextLabel(10, 5, 140, 20, "度数法での角度:"); mountComponent(degreeLabel, window); // 度数法での角度入力欄を生成/配置 degreeInputField = newTextField(10, 25, 140, 30, "0.0"); mountComponent(degreeInputField, window); // ラジアンでの角度入力欄の上に、文字列ラベルを生成/配置 int radianLabel = newTextLabel(280, 5, 140, 20, "ラジアン:"); mountComponent(radianLabel, window); // ラジアンでの角度入力欄を生成/配置 radianInputField = newTextField(280, 25, 140, 30, "0.0"); mountComponent(radianInputField, window); // ラジアンでの角度入力欄の下に、何πラジアンかを表示するラベルを生成/配置 radianOverPiLabel = newTextLabel(280, 55, 140, 15, "(0.0 π)"); mountComponent(radianOverPiLabel, window); // 度数法からラジアンへの変換ボタンを生成/配置 degreeToRadianButton = newButton(190, 10, 50, 30, ">>"); mountComponent(degreeToRadianButton, window); // ラジアンから度数法への変換ボタンを生成/配置 radianToDegreeButton = newButton(190, 40, 50, 30, "<<"); mountComponent(radianToDegreeButton, window); // 角度ディスプレイ用の2D描画エンジンやグラフィックスリソースを生成 displayGraphics = newGraphics(); displayRenderer = newGraphics2DRenderer(DISPLAY_WIDTH, DISPLAY_HEIGHT, displayGraphics); // 角度ディスプレイの表示ラベルを生成/配置 displayLabel = newImageLabel(0, DISPLAY_Y, DISPLAY_WIDTH, DISPLAY_HEIGHT, displayGraphics); mountComponent(displayLabel, window); // 角度スライダーを生成/配置 angleSlider = newHorizontalSlider(10, DISPLAY_Y + DISPLAY_HEIGHT + 10, WINDOW_WIDTH - 35, 30, 0, 0, 360); mountComponent(angleSlider, window); } // 角度ディスプレイの内容を更新(描画)する関数 // ----- // * 引数 degree: 度数法での角度 void updateDisplay(float degree) { // 度数に対応するラジアンを求める float radian = degreeToRadian(degree); // 円の中心座標や、外接長方形の左上端の位置、サイズなどを求める int circleCenterX = DISPLAY_WIDTH / 2; int circleCenterY = DISPLAY_HEIGHT / 2; int circleLeftTopX = circleCenterX - CIRCLE_RADIUS; int circleLeftTopY = circleCenterY - CIRCLE_RADIUS; int circleSize = CIRCLE_RADIUS * 2; // 円周上の、角度に対応する地点の座標を求める int anglePointX = round(circleCenterX + CIRCLE_RADIUS * cos(radian), 8, HALF_UP); int anglePointY = round(circleCenterY - CIRCLE_RADIUS * sin(radian), 8, HALF_UP); // 現在の描画内容を、白色でクリアする setGraphics2DColor(displayRenderer, WHITE); clearGraphics2D(displayRenderer); // 円を描く setDrawColor(displayRenderer, BLACK); drawEllipse(displayRenderer, circleLeftTopX, circleLeftTopY, circleSize, circleSize, false); // 円の中心から、指定角度の線と、角度 0 の基準線を引く drawLine(displayRenderer, circleCenterX, circleCenterY, circleCenterX + CIRCLE_RADIUS, circleCenterY); drawLine(displayRenderer, circleCenterX, circleCenterY, anglePointX, anglePointY); // 上記の 2 本の線の間を、円弧で繋ぐ(小刻みに線を引いて円弧を描く) float arcR = 40; for (float arcBeginRadian=0.0; arcBeginRadian < radian; arcBeginRadian += 0.03) { float arcEndRadian = arcBeginRadian + 0.03; if (radian < arcEndRadian) { arcEndRadian = radian; } int arcBeginX = round(circleCenterX + arcR * cos(arcBeginRadian), 8, HALF_UP); int arcBeginY = round(circleCenterY - arcR * sin(arcBeginRadian), 8, HALF_UP); int arcEndX = round(circleCenterX + arcR * cos(arcEndRadian), 8, HALF_UP); int arcEndY = round(circleCenterY - arcR * sin(arcEndRadian), 8, HALF_UP); setDrawColor(displayRenderer, BLACK); drawLine(displayRenderer, arcBeginX, arcBeginY, arcEndX, arcEndY); } // 円周上の、指定角度の位置に、赤色の点を描く setDrawColor(displayRenderer, RED); drawPoint(displayRenderer, anglePointX, anglePointY, 5, true); // 円周上の、0、90、180、270度の位置に目盛り数字を描く setDrawColor(displayRenderer, BLACK); setDrawFontSize(displayRenderer, 16); drawText(displayRenderer, circleCenterX + CIRCLE_RADIUS + 10, circleCenterY + 5, "0"); drawText(displayRenderer, circleCenterX - 10, circleCenterY - CIRCLE_RADIUS - 10, "90"); drawText(displayRenderer, circleCenterX - CIRCLE_RADIUS - 40, circleCenterY + 5, "180"); drawText(displayRenderer, circleCenterX - 12, circleCenterY + CIRCLE_RADIUS + 22, "270"); // 角度ディスプレイの表示ラベル、およびウィンドウを再描画 paintComponent(displayLabel); paintComponent(window); } // ボタンが押された際に実行されるイベントハンドラ関数 // ----- // * 引数 componentID: 押されたボタンのGUIコンポーネントID // * 引数 buttonText: 押されたボタンの文字列 void onButtonClick(int componentID, string buttonText) { // 度数法からラジアンへの変換ボタン「 >> 」が押された場合の処理 if (componentID == degreeToRadianButton) { // 入力内容が正しいかどうかを検査 string degreeExpression = getComponentText(degreeInputField); if (!evaluable(degreeExpression, 0.0)) { alert("度数法の角度の入力値(または計算式)が、想定外の内容です。"); return; } // 入力内容を度数法の数値へ変換(式が入力された場合は計算される) float degree = eval(degreeExpression, 0.0); // 度数からラジアン値へ変換 float radian = degreeToRadian(degree); // そのラジアン値が「何π」かの値も求める float radianOverPi = radian / PI; // 角度ディスプレイを更新(再描画) updateDisplay(degree); // 変換結果の数値などを丸めつつ、テキストフィールド/ラベル等に表示する radian = round(radian, 8, HALF_UP); radianOverPi = round(radianOverPi, 8, HALF_UP); setComponentText(radianInputField, (string)radian); setComponentText(radianOverPiLabel, "(" + radianOverPi + " π)"); return; } // ラジアンから度数法への変換ボタン「 << 」が押された場合の処理 if (componentID == radianToDegreeButton) { // 入力内容が正しいかどうかを検査 string radianExpression = getComponentText(radianInputField); if (!evaluable(radianExpression, 0.0)) { alert("ラジアンの入力値(または計算式)が、想定外の内容です。"); return; } // 入力内容をラジアンの数値へ変換(式が入力された場合は計算される) float radian = eval(radianExpression, 0.0); // そのラジアン値が「何π」かの値も求める float radianOverPi = radian / PI; // ラジアン値から度数へ変換 float degree = radianToDegree(radian); // 角度ディスプレイを更新(再描画) updateDisplay(degree); // 変換結果の数値などを丸めつつ、テキストフィールド/ラベル等に表示する degree = round(degree, 8, HALF_UP); radianOverPi = round(radianOverPi, 8, HALF_UP); setComponentText(degreeInputField, (string)degree); setComponentText(radianOverPiLabel, "(" + radianOverPi + " π)"); return; } } // スライダーが操作された際に実行されるイベントハンドラ関数 // ----- // * 引数 componentID: 操作されたスライダーのGUIコンポーネントID // * 引数 value: 操作されたスライダーの現在値 void onSliderMove(int componentID, int value) { // スライダーの値は、0 から 360 までの整数値を取るように作成したので、そのまま度数と見なす float degree = (float)value; // 度数からラジアンへ変換 float radian = degreeToRadian(degree); // そのラジアン値が「何π」かの値も求める float radianOverPi = radian / PI; // 角度ディスプレイを更新(再描画) updateDisplay(degree); // 度数やラジアンの数値を、小数点以下8桁以内に丸めた上で、テキストフィールド/ラベル等に表示する degree = round(degree, 8, HALF_UP); radian = round(radian, 8, HALF_UP); radianOverPi = round(radianOverPi, 8, HALF_UP); setComponentText(degreeInputField, (string)degree); setComponentText(radianInputField, (string)radian); setComponentText(radianOverPiLabel, "(" + radianOverPi + " π)"); } // ウィンドウが閉じられた際に実行されるイベントハンドラ // ----- // * 引数 componentID: 閉じられたウィンドウのGUIコンポーネントID void onWindowClose(int componentID) { // プログラムの実行を終了する exit(); }