1989年開業 技術士 佐伯英子(情報工学部門) 文部科学省登録番号 第22082号 日本技術士会会員 東大阪商工会議所会員

≫サンプルプログラム一覧 

オープンソース/C言語サンプルプログラム 三角形を表示する(2)

●コマンドプロンプトに三角形を表示するプログラムです。
 キャラクタ画面に対応する2次元配列を使い、三角形上の要素に * を
 設定します。
 この配列は、キャラクタ画面のビットマップになります。
●頂点と頂点を結ぶ辺は、線分を補完する関数 Gen_line( ) で生成します。
 右の下の図のように、傾きが大きいときも線が途切れないよう、補完して
 います。補完なしの簡単なプログラムは 三角形を表示する(1)zukei301
 参照してください。
●各辺の計算が終了したら、最後に配列の内容を1行ずつ表示します。
 キャラクタ画面の原点は左上隅なので、最後の行から表示します。

 ≫ソースファイルのダウンロード: zukei302.c

【練習問題】
●頂点の座標を変更していろいろな三角形を表示してみよう。
●このプログラムは、頂点に範囲外の座標を設定すると正常に動作しない。
 有効な範囲はx,yそれぞれいくらか。

【応用問題】
座標が有効範囲を超えても暴走しないよう、プログラムを変更しなさい。


2012. 7. 7 注釈を訂正しました。(第9行目) // 25x80文字分の配列


/***************************/
/*  三角形を表示する(2) */
/***************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

char  buf[25][80];                       // 25x80文字分の配列

void  Gen_line(int,int,int,int);         // 線分生成


void  main( )
{
    int     x1= 5,y1= 0;                 // 頂点1
    int     x2=25,y2= 0;                 // 頂点2
    int     x3=30,y3=10;                 // 頂点3
    int     y;

    memset(&buf[0][0],' ',25*80);        // 配列を空白で初期化

    //--線分プロット--
    Gen_line(x1,y1,x2,y2);               // 線分生成
    Gen_line(x2,y2,x3,y3);               // 線分生成
    Gen_line(x3,y3,x1,y1);               // 線分生成

	//--表示--
    for( y=24; y>=0; y-- )
      { printf("%.80s",&buf[y][0]); }   // 画面1行表示
    fflush(stdout);
}


void  Gen_line(
/*------------*/
/*  線分生成  */
/*------------*/
int  xS,  // 始点
int  yS,
int  xE,  // 終点
int  yE)
{
    double  dx,dy,a=0,b=0;
    int     x,y,yO,yN;

    buf[yS][xS]='*';                                    // 始点
    buf[yE][xE]='*';                                    // 終点

    if ( xS==xE )                                       // 垂直線
      {
        if ( yS>yE ) { y=yS; yS=yE; yE=y; }
        for( y=yS+1; y<yE; y++ ) buf[y][xS]='*';        // 線分上の点
      }
    else
      {
        if ( xS>xE )
          { x=xS; xS=xE; xE=x; y=yS; yS=yE; yE=y; }     // 始点終点入れ替え

        dx=xE-xS; dy=yE-yS;
        a=dy/dx; b=yS-a*xS;                             // 直線の係数

        if ( a>=-1.0 && a<=1.0 )                        // 傾きが小さい
          {
            for( x=xS+1; x<xE; x++ )                    // 線分補完
              {
                y=a*x+b+0.5;                            // 計算結果は四捨五入
                buf[y][x]='*';
              }
          }
        else if ( a>=0 )                                // 傾きが大きくプラス
          {
            for( x=xS+1,yO=yS; x<=xE; x++,yO=yN )       // 線分補完
              {
                yN=a*x+b+0.5;
                for( y=yO+1; y<=yN; y++ ) buf[y][x]='*';
              }
          }
        else                                            // 傾きが大きくマイナス
          {
            for( x=xS+1,yO=yS; x<=xE; x++,yO=yN )       // 線分補完
              {
                yN=a*x+b+0.5;
                for( y=yO-1; y>=yN; y-- ) buf[y][x]='*';
              }
          }
      }
}
   

※SSL暗号化通信対応

佐伯英子技術士事務所 〒542-0073 大阪市中央区日本橋 1-14-13 サンオフィス日本橋601  E-mail: info@saeki-pe.com