土木測量プログラムの開発 (座標計算)

2017/04/06


座標計算

座標計算は座標値を距離・角度に変換するケースと観測データを座標値に変換するケースに大別されますが、これを別個のプログラムとして勘定するのではなく一つの座標計算プログラムとします。

入力画面でF4キーを押すと入力モードが大座標入力、小座標入力、観測データ入力の順に切り替わります。

入力モードに応じて出力が異なります。

距離と角度の表示がある場合、観測データとの差を計算したい場合があります。 計算結果の表示中に F4 キーを押すことで小窓を開き計算できるようにするため次の関数を作成します。 また、専用の数値入力と数値表示のパターンを該当関数に登録しておきます。(この変更部分は掲載しません。 最下行の圧縮ファイル内で確認してください。)

//prog00.h

// 距離測定 **************************
void TS_meas(double d) {
    double i = d;
    double j;

// 画面保存
    SaveDisp(SAVEDISP_PAGE1);
    Bdisp_AreaReverseVRAM(63, 56, 83, 63);
    PopUpWin(2);
    CPrint(6, 3, (char*)"L =", 0, 0);
    while(1) {
        FuncKey = 0;
        i = InputVal(3, d, 3);
        if (FuncKey == 1 || FuncKey == 2) return;
        if (i == d) return;
        j = i - d;
        if (j < 0) {
            CPrint(4, 4, (char*)"Back :", 0, 0);
        } else {
            CPrint(4, 4, (char*)"コウハ :", 0, 0);
        }
        PrintNum(11, 4, fabs(j), 1);
    }
}

最下行のメニュー表示 (BottomLine) 関数を修正しました。 (対象ビットを論理積で読み取ってます)

//prog00.h

// 最下行表示 ****************************
void BottomLine(char type) {
//F1
    Bdisp_DrawLineVRAM( 0, 56, 19, 56);
    Bdisp_DrawLineVRAM( 20, 56, 20, 63);
    PrintMini(2, 58,(unsigned char *)" F1",MINI_OVER);

//F2
    Bdisp_DrawLineVRAM( 22, 56, 41, 56);
    Bdisp_DrawLineVRAM( 42, 56, 42, 63);
    PrintMini(24, 58,(unsigned char *)" F2",MINI_OVER);

//F4
    if (type & 8) {
        Bdisp_DrawLineVRAM( 63, 56, 82, 56);
        Bdisp_DrawLineVRAM( 83, 56, 83, 63);
        PrintMini(65, 58,(unsigned char *)" TS ",MINI_OVER);
    }
    if (type & 4) {
        Bdisp_DrawLineVRAM( 63, 56, 82, 56);
        Bdisp_DrawLineVRAM( 83, 56, 83, 63);
        PrintMini(65, 58,(unsigned char *)"MODE",MINI_OVER);
    }

//F5
    if (type & 2) {
        Bdisp_DrawLineVRAM( 85, 56, 104, 56);
        Bdisp_DrawLineVRAM(105, 56, 105, 63);
        PrintMini(87, 58,(unsigned char *)"OPT",MINI_OVER);
    }

//F6
    if (type & 16) {
        Bdisp_DrawLineVRAM(107, 56, 126, 56);
        Bdisp_DrawLineVRAM(127, 56, 127, 63);
        PrintMini(111, 58,(unsigned char *)"RST",MINI_OVER);
    }
    if (type & 1) {
        Bdisp_DrawLineVRAM(107, 56, 126, 56);
        Bdisp_DrawLineVRAM(127, 56, 127, 63);
        PrintMini(109, 58,(unsigned char *)"MEM",MINI_OVER);
    }
}

既に登録されている座標変換の要素を基点に、座標値を変換(移動と回転)します。 ワールド座標やローカル座標等の呼び方もありますが、変換前の座標を大座標、変換後の座標を小座標と呼ぶこととします。

関数は大座標を小座標に変換するものと、小座標をダイザヒョウに変換するものの2つ作ります。

//prog01.h

// 座標変換 大→小 *******************
void convB2S(zahyo p0, double a, zahyo z, zahyo *ans) {
    (*ans).x = cos(a) * (z.x - p0.x) + sin(a) * (z.y - p0.y);
    (*ans).y = sin(a) * (p0.x - z.x) + cos(a) * (z.y - p0.y);
}

// 座標変換 小→大 *******************
void convS2B(zahyo p0, double a, zahyo z, zahyo *ans) {
    (*ans).x = p0.x * cos(-a) + z.y * sin(-a) + p0.x;
    (*ans).y = -z.x * sin(-a) + z.y * cos(a) + p0.y;
}

関数は大座標を小座標に変換するものと、小座標をダイザヒョウに変換するものの2つ作ります。

//prog21.h

// 座標計算 ******************************
void prog21(void) {
    int fileHandle, tmp;
    zahyo lx, sx, lans, sans;
    ladata p, la, ans;

// データ読み込み
    fileHandle = Bfile_OpenMainMemory(datafile);
    tmp = Bfile_ReadFile (fileHandle, &lx, sizeof(lx), ad_P21_LX);
    tmp = Bfile_ReadFile (fileHandle, &sx, sizeof(sx), ad_P21_SX);
    tmp = Bfile_ReadFile (fileHandle, &la, sizeof(la), ad_P21_LA);
    tmp = Bfile_CloseFile(fileHandle);

P21_START:
    Bdisp_AllClr_DDVRAM();
    CPrint(1, 1, (char*)"[ ザヒョウ ケイサン ]", 0, 0);

    switch(P21Mode) {
// 小座標入力
        case 1:
            CPrint(18, 1, (char*)"-xy-", 0, 0);
            BottomLine(5);
            CPrint(5, 3, (char*)"x =", 0, 0);
            CPrint(5, 4, (char*)"y =", 0, 0);
            InputXYZ(3, &sx, 2);
            if (FuncKey == 1 || FuncKey == 2) return;
            if (FuncKey == 4) {
                P21Mode = 2;
                goto P21_START;
            }
            break;
// 観測入力
        case 2:
            CPrint(18, 1, (char*)"-LA-", 0, 0);
            BottomLine(4);
            p = la;
            CPrint(5, 3, (char*)"L =", 0, 0);
            PrintNum(8, 3, p.l, 0);
            CPrint(5, 4, (char*)"A =", 0, 0);
            PirintDMS(9, 4, p.a, 1);
            p.l = InputVal(3, p.l, 0);
            if (FuncKey == 1 || FuncKey == 2) return;
            if (FuncKey == 4) {
                P21Mode = 0;
                goto P21_START;
            }
            p.a = InputVal(4, la.a, 1);
            if (FuncKey == 1 || FuncKey == 2) return;
            if (FuncKey == 4) {
                P21Mode = 0;
                goto P21_START;
            }
            la = p;
            break;
// 大座標入力
        default:
            CPrint(18, 1, (char*)"-XY-", 0, 0);
            BottomLine(5);
            CPrint(5, 3, (char*)"X =", 0, 0);
            CPrint(5, 4, (char*)"Y =", 0, 0);
            InputXYZ(3, &lx, 2);
            if (FuncKey == 1 || FuncKey == 2) return;
            if (FuncKey == 4) {
                P21Mode = 1;
                goto P21_START;
            }
            break;
    }

// データ書き込み
    fileHandle = Bfile_OpenMainMemory(datafile);
    tmp = Bfile_SeekFile(fileHandle, ad_P21_MODE);
    tmp = Bfile_WriteFile(fileHandle, &P21Mode, sizeof(P21Mode));
    tmp = Bfile_SeekFile(fileHandle, ad_P21_LX);
    tmp = Bfile_WriteFile(fileHandle, &lx, sizeof(lx));
    tmp = Bfile_WriteFile(fileHandle, &sx, sizeof(sx));
    tmp = Bfile_WriteFile(fileHandle, &la, sizeof(la));
    tmp = Bfile_CloseFile(fileHandle);

// 計算
    switch(P21Mode) {
        case 1:
            convS2B(henkan, henkan_ha, sx, &lans);
            TS_pol(lans, &ans);
            break;
        case 2:
            TS_rec(la, &lans);
            convB2S(henkan, henkan_ha, lans, &sans);
            break;
        default:
            convB2S(henkan, henkan_ha, lx, &sans);
            TS_pol(lx, &ans);
            break;
    }

// 計算結果の表示
    Bdisp_AllClr_DDVRAM();
    CPrint(1, 1, (char*)"[ ザヒョウ ケイサン ]", 0, 0);
    switch(P21Mode) {
// xy → XY,LA
        case 1:
            CPrint(18, 1, (char*)"-xy-", 0, 0);
            RevLineC(0, 0, 0);
            BottomLine(9);
            CPrint(5, 2, (char*)"X =", 0, 0);
            PrintNum(8, 2, lans.x, 0);
            CPrint(5, 3, (char*)"Y =", 0, 0);
            PrintNum(8, 3, lans.y, 0);
            CPrint(5, 4, (char*)"A =", 0, 0);
            PirintDMS(9, 4, ans.a, 0);
            CPrint(5, 5, (char*)"L =", 0, 0);
            PrintNum(8, 5, ans.l, 0);
            memo = lans;
            break;
// LA → XY,xy
        case 2:
            CPrint(18, 1, (char*)"-LA-", 0, 0);
            RevLineC(0, 0, 0);
            BottomLine(1);
            CPrint(5, 2, (char*)"X =", 0, 0);
            PrintNum(8, 2, lans.x, 0);
            CPrint(5, 3, (char*)"Y =", 0, 0);
            PrintNum(8, 3, lans.y, 0);
            CPrint(5, 4, (char*)"x =", 0, 0);
            PrintNum(8, 4, sans.x, 0);
            CPrint(5, 5, (char*)"y =", 0, 0);
            PrintNum(8, 5, sans.y, 0);
            memo = lans;
            break;
// XY → xy,LA
        default:
            CPrint(18, 1, (char*)"-XY-", 0, 0);
            RevLineC(0, 0, 0);
            BottomLine(9);
            CPrint(5, 2, (char*)"x =", 0, 0);
            PrintNum(8, 2, sans.x, 0);
            CPrint(5, 3, (char*)"y =", 0, 0);
            PrintNum(8, 3, sans.y, 0);
            CPrint(5, 4, (char*)"A =", 0, 0);
            PirintDMS(9, 4, ans.a, 0);
            CPrint(5, 5, (char*)"L =", 0, 0);
            PrintNum(8, 5, ans.l, 0);
            memo = sans;
            break;
    }
    Wait();
    if (FuncKey == 1 || FuncKey == 2) return;
    if (P21Mode != 2 && FuncKey == 4) TS_meas(ans.l);
    if (FuncKey == 6) SaveMemo();

    goto P21_START;
}


座標登録プログラム

ファイルに保存したり呼び出したりする座標メモを直接編集するプログラムを作成します。

プログラムは F1 メニューから呼び出すようにするので、Menu 関数を修正しています。 また関連する関数をいくつか修正しています。

//prog17.h

// 座標登録 ******************************
void prog17(void) {
    int fileHandle, tmp;
    double d;
    int i, num;

P17_START:
    num = 0;
    Bdisp_AllClr_DDVRAM();
    CPrint(1, 1, (char*)"[ ザヒョウ MEMO トウロク ]", 0, 0);
    RevLineC(0, 0, 0);
    BottomLine(16);

    while(1) {
//番号入力
        locate(2, 3);
        Print((unsigned char*)"Memo =");
        d = InputVal(3, num, 4);
        if (FuncKey == 1 || FuncKey == 2) return;
        if (FuncKey == 6) goto P17_RESET;
        if (d == 0) return;
        num = d;

// ファイル読み込み
        fileHandle = Bfile_OpenMainMemory(xyz_file);
        tmp = Bfile_ReadFile(fileHandle, &memo, 24, (num-1)*24);
        if(tmp < 0) ErrorWindow(3, 1701);
        tmp = Bfile_CloseFile(fileHandle);

//座標入力
        CPrint(5, 4, (char*)"X =", 0, 0);
        PrintNum(8, 4, memo.x, 0);
        CPrint(5, 5, (char*)"Y =", 0, 0);
        PrintNum(8, 5, memo.y, 0);
        CPrint(5, 6, (char*)"Z =", 0, 0);
        PrintNum(8, 6, memo.y, 0);

        InputXYZ(4, &memo, 5);
        if (FuncKey == 1 || FuncKey == 2) return;
        if (FuncKey == 6) goto P17_RESET;

// ファイル書き込み
        fileHandle = Bfile_OpenMainMemory(xyz_file);
        tmp = Bfile_SeekFile(fileHandle, (num-1)*24);
        tmp = Bfile_WriteFile(fileHandle, &memo, 24);
        if(tmp < 0) ErrorWindow(3, 1702);
        tmp = Bfile_CloseFile(fileHandle);
    }

P17_RESET:
    Bdisp_AreaReverseVRAM(107, 56, 127, 63);
    PopUpWin(1);
    PopUpWin(1);
    locate(4, 4);
    Print((unsigned char*)"RESET !! [F6]");
    Wait();
    if (FuncKey == 1 || FuncKey == 2) return;
    if (FuncKey != 6) goto P17_START;
    locate(4, 4);
    Print((unsigned char*)" OK ? [F6]");
    Wait();
    if (FuncKey == 1 || FuncKey == 2) return;
    if (FuncKey != 6) goto P17_START;

    memo.x = 0;
    memo.y = 0;
    memo.z = 0;

    fileHandle = Bfile_OpenMainMemory(xyz_file);
    tmp = Bfile_SeekFile(fileHandle, 0);
    for (i=0; i<100; i++) {
        tmp = Bfile_WriteFile(fileHandle, (void *)&memo, 24);
        if(tmp < 0) ErrorWindow(3, 1703);
    }
    tmp = Bfile_CloseFile(fileHandle);

    goto P17_START;
}

ここまでの取りまとめ。

docal-002.zip