一直線上にない3点 A,B,C との距離が等しい点Pの求め方


目次
0、はじめに
1、C言語(C99)での実装
2、テスト結果
3、ライセンス及び免責事項
4、終わりに


0、はじめに

データ処理をしていると、内接円や外接円を求めたくなることが多々ある。
また、ある瞬間に異なる3点以上で信号を受信した時に、信号の発生源の場所を特定したくなる
ケースも出て来るが、これらは等距離点を探し出す事と同意義なので、高校数学で考えてみる。
結果のみ用意してあるので、気分転換の頭の体操として過程を追うには丁度良いかもしれない。


1、C言語(C99)での実装

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

typedef struct POINT { float x, y; } POINT;

POINT CenterOfCirclePassingThroughThreePoints( POINT A, POINT B, POINT C ){
    int      BBBB_AAAA = (B.x*B.x + B.y*B.y) - (A.x*A.x + A.y*A.y);
    int      AAAA_CCCC = (A.x*A.x + A.y*A.y) - (C.x*C.x + C.y*C.y);
    int      CCCC_BBBB = (C.x*C.x + C.y*C.y) - (B.x*B.x + B.y*B.y);
    int Px_Numerator   = A.y*CCCC_BBBB + B.y*AAAA_CCCC + C.y*BBBB_AAAA;
    int Px_Denominator = 2*((B.y-C.y)*(A.x-C.x) - (B.x-C.x)*(A.y-C.y));
    int Py_Numerator   = A.x*CCCC_BBBB + B.x*AAAA_CCCC + C.x*BBBB_AAAA;
    int Py_Denominator = 2*((B.x-C.x)*(A.y-C.y) - (A.x-C.x)*(B.y-C.y));
    float           Px = (float)Px_Numerator / (float)Px_Denominator;
    float           Py = (float)Py_Numerator / (float)Py_Denominator;
    return (POINT){ Px, Py };
}


int main(){ srand((unsigned int)time(NULL));
    for(int e=0; e<64; e++ ) { // 0 <= x < 1000, 0 <= y < 1000
        POINT A = (POINT){ rand() % 1000, rand() % 1000 };
        POINT B = (POINT){ rand() % 1000, rand() % 1000 };
        POINT C = (POINT){ rand() % 1000, rand() % 1000 };
        if( (A.x-C.x)*(B.y-C.y) == (B.x-C.x)*(A.y-C.y) ) continue;

        POINT P = CenterOfCirclePassingThroughThreePoints( A, B, C );
        int AP = sqrt( (A.x - P.x)*(A.x - P.x) + (A.y - P.y)*(A.y - P.y) );
        int BP = sqrt( (B.x - P.x)*(B.x - P.x) + (B.y - P.y)*(B.y - P.y) );
        int CP = sqrt( (C.x - P.x)*(C.x - P.x) + (C.y - P.y)*(C.y - P.y) );

        //// Determine if they are equal distance
        char *flag = ( AP!=BP || BP!=CP || CP!=AP ) ? "*" : " " ;

        printf( "A:(% 5.0f,% 5.0f), ", A.x, A.y );
        printf( "B:(% 5.0f,% 5.0f), ", B.x, B.y );
        printf( "C:(% 5.0f,% 5.0f)  ", C.x, C.y );
        printf( "P:(% 8.1f,% 8.1f) ", P.x, P.y ); printf("\t");
        printf( "AP,BP,CP:%s% 6d,% 6d,% 6d\n", flag, AP, BP, CP );
    }
    return 0;
}


・インライン展開でも支障ない程の、簡単な四則演算のみの短くシンプルな実装
rand() 関数を使って、点 A,B,C の座標を動的に作成した検証用データ
・3点が一直線上にあるかの判定処理(一直線上にある時、P点は存在しない)
      if( (A.x-C.x)*(B.y-C.y)==(B.x-C.x)*(A.y-C.y) )continue;


2、テスト結果

実行結果 『算出点 P と 3点 A,B,C との距離(AP,BP,CP)は一定』

A:(   69,  127), B:(  381,  947), C:(   76,  112)    P:(   633.8,   381.4)      AP,BP,CP:    619,   619,   619
A:(  338,   78), B:(  784,  563), C:(  815,  975)    P:(     8.6,   828.5)      AP,BP,CP:    819,   819,   819
A:(  836,  820), B:(  349,  322), C:(  689,  431)    P:(   394.6,   764.5)      AP,BP,CP:    444,   444,   444
A:(  423,  873), B:(  387,  199), C:(   74,  654)    P:(   390.8,   536.8)      AP,BP,CP:    337,   337,   337
A:(  359,  176), B:(  521,  182), C:(  466,  607)    P:(   432.3,   386.6)      AP,BP,CP:    222,   222,   222
A:(  370,  550), B:(  148,  457), C:(  962,  554)    P:(   673.0,  -484.8)      AP,BP,CP:   1078,  1078,  1078
A:(  165,  497), B:(  520,  524), C:(  702,  622)    P:(   292.8,  1163.9)      AP,BP,CP:    679,   679,   679
A:(  545,  209), B:(  299,  788), C:(   56,  850)    P:(    56.1,   343.0)      AP,BP,CP:    506,   506,   506
A:(   95,  362), B:(  145,  154), C:(  792,   20)    P:(   524.0,   355.1)      AP,BP,CP:    429,   429,   429
A:(  262,   75), B:(  765,  681), C:(  321,   55)    P:(   423.1,   453.1)      AP,BP,CP:    410,   410,   410
A:(  846,  616), B:(  811,    3), C:(    3,  206)    P:(   463.7,   330.3)      AP,BP,CP:    477,   477,   477
A:(  868,  582), B:(  744,  763), C:(  236,  483)    P:(   556.8,   501.8)      AP,BP,CP:    321,   321,   321
A:(  687,   47), B:(  849,  314), C:(  678,  335)    P:(   747.4,   193.0)      AP,BP,CP:    158,   158,   158
A:(  362,  198), B:(  426,  900), C:(  108,  971)    P:(   185.0,   568.1)      AP,BP,CP:    410,   410,   410
A:(   52,  190), B:(  827,  878), C:(  419,  268)    P:(    86.1,   932.1)      AP,BP,CP:    742,   742,   742
A:(  491,  738), B:(  122,  591), C:(  471,  976)    P:(   237.9,   836.6)      AP,BP,CP:    271,   271,   271
A:(  396,  752), B:(  785,  462), C:(  870,  631)    P:(   622.3,   649.7)      AP,BP,CP:    248,   248,   248
A:(  124,  603), B:(   59,  766), C:(  599,  402)    P:(   509.0,   851.0)      AP,BP,CP:    457,   457,   457
A:(  757,  677), B:(  650,  405), C:(  755,  415)    P:(   689.5,   546.5)      AP,BP,CP:    146,   146,   146
A:(  558,  844), B:(   30,  845), C:(  624,  687)    P:(   293.6,   640.5)      AP,BP,CP:    333,   333,   333
A:(  408,  241), B:(   78,  120), C:(  503,  246)    P:(   495.0,  -506.7)      AP,BP,CP:    752,   752,   752
A:(  870,  636), B:(  246,  526), C:(  219,  571)    P:(   532.0,   728.2)      AP,BP,CP:    350,   350,   350
A:(  678,  884), B:(   24,   22), C:(  835,  691)    P:(   348.1,   455.2)      AP,BP,CP:    541,   541,   541
A:(  482,  760), B:(  793,  558), C:(  809,  768)    P:(   647.7,   674.7)      AP,BP,CP:    186,   186,   186
A:(  617,   26), B:(  792,  703), C:(  366,  417)    P:(   711.5,   362.7)      AP,BP,CP:    349,   349,   349
A:(  782,  381), B:(  909,  352), C:(  948,  656)    P:(   878.4,   510.4)      AP,BP,CP:    161,   161,   161
A:(  900,  891), B:(  263,  176), C:(  706,  336)    P:(   290.7,   792.6)      AP,BP,CP:    617,   617,   617
A:(  328,  388), B:(  616,  137), C:(  282,  129)    P:(   446.6,   233.4)      AP,BP,CP:    194,   194,   194
A:(  958,  182), B:(  611,  853), C:(  193,  322)    P:(   607.3,   425.9)      AP,BP,CP:    427,   427,   427
A:(  695,  375), B:(  476,  837), C:(  298,  113)    P:(   335.7,   487.6)      AP,BP,CP:    376,   376,   376
A:(  548,  706), B:(  861,  168), C:(  633,  569)    P:( -6312.4, -3645.3)      AP,BP,CP:   8124,  8124,  8124
A:(  619,  283), B:(  841,  672), C:(  876,  579)    P:(   624.8,   537.5)      AP,BP,CP:    254,   254,   254
A:(   15,  278), B:(  625,  338), C:(  444,   72)    P:(   315.5,   354.0)      AP,BP,CP:    309,   309,   309
A:(  208,  647), B:(  533,  583), C:(  147,   16)    P:(   312.1,   318.5)      AP,BP,CP:    344,   344,   344
A:(  838,  449), B:(  668,  569), C:(  956,   95)    P:(   489.9,   136.3)      AP,BP,CP:    467,   467,   467
A:(  380,  285), B:(  609,  576), C:(  925,  977)    P:( 515715.7,-405018.5)    AP,BP,CP:  655623, 655623, 655623
A:(  612,  844), B:(  500,  737), C:(  399,  100)    P:(   993.8,   332.2)      AP,BP,CP:    638,   638,   638
A:(  203,  550), B:(  949,  591), C:(  741,  181)    P:(   578.7,   521.1)      AP,BP,CP:    376,   376,   376
A:(  699,  736), B:(  155,   14), C:(  126,  918)    P:(   299.5,   471.1)      AP,BP,CP:    479,   479,   479
A:(  439,  226), B:(  222,  948), C:(  592,  486)    P:(   193.1,   545.7)      AP,BP,CP:    403,   403,   403
A:(  378,  338), B:(  229,  368), C:(  356,  723)    P:(   338.9,   528.9)      AP,BP,CP:    194,   194,   194
A:(   77,  296), B:(  878,  578), C:(  583,    1)    P:(   485.3,   414.9)      AP,BP,CP:    425,   425,   425
A:(  189,  214), B:(  709,  120), C:(  605,  269)    P:(   424.7,    32.3)      AP,BP,CP:    297,   297,   297
A:(  430,  388), B:(  229,    8), C:(  675,  998)    P:( -4262.2,  2626.8)      AP,BP,CP:   5198,  5198,  5198
A:(  468,  196), B:(  658,  635), C:(  619,  425)    P:(    42.9,   640.6)      AP,BP,CP:    615,   615,   615
A:(   66,  751), B:(  221,   14), C:(  159,  621)    P:(  -501.3,   246.9)      AP,BP,CP:    758,   758,   758
A:(  910,  444), B:(  623,  636), C:(  392,  617)    P:(   542.2,   204.7)      AP,BP,CP:    438,   438,   438
A:(  211,  396), B:(  139,  192), C:(  362,  346)    P:(   252.0,   266.8)      AP,BP,CP:    135,   135,   135
A:(  613,  752), B:(   26,  536), C:(  960,  602)    P:(   527.7,    78.3)      AP,BP,CP:    679,   679,   679
A:(  824,  320), B:(  444,  639), C:(  859,  266)    P:(    42.9,  -224.6)      AP,BP,CP:    952,   952,   952
A:(  845,  857), B:(  428,  548), C:(  662,  553)    P:(   538.9,   834.2)      AP,BP,CP:    306,   306,   306
A:(  832,  706), B:(    5,  865), C:(  601,  230)    P:(   388.1,   627.4)      AP,BP,CP:    450,   450,   450
A:(  505,   26), B:(  385,  649), C:(  490,  505)    P:(   -11.6,   249.6)      AP,BP,CP:    562,   562,   562
A:(  633,  235), B:(  463,  926), C:(   58,  144)    P:(   293.5,   517.9)      AP,BP,CP:    441,   441,   441
A:(  598,   61), B:(  162,  796), C:(  176,  152)    P:(   467.6,   480.5)      AP,BP,CP:    439,   439,   439
A:(  681,  320), B:(   26,  981), C:(  748,   84)    P:(  -425.8,  -121.7)      AP,BP,CP:   1191,  1191,  1191
A:(  804,  300), B:(  801,  927), C:(   83,  948)    P:(   432.5,   611.7)      AP,BP,CP:    484,   484,   484
A:(  324,  406), B:(   33,  318), C:(  226,  897)    P:(   101.4,   616.9)      AP,BP,CP:    306,   306,   306
A:(   24,  761), B:(  964,  660), C:(  107,  432)    P:(   493.3,   704.4)      AP,BP,CP:    472,   472,   472
A:(  334,   69), B:(  390,  993), C:(  984,  193)    P:(   585.3,   517.5)      AP,BP,CP:    514,   514,   514
A:(  639,  392), B:(  957,  100), C:(  372,  971)    P:(  1706.4,  1235.3)      AP,BP,CP:   1360,  1360,  1360
A:(  603,  824), B:(  679,  887), C:(  970,  997)    P:(  1038.4,   376.1)      AP,BP,CP:    624,   624,   624
A:(  200,  251), B:(  840,  211), C:(  953,  523)    P:(   536.6,   497.3)      AP,BP,CP:    417,   417,   417
A:(  668,  684), B:(   72,   96), C:(   65,  213)    P:(   572.6,   184.7)      AP,BP,CP:    508,   508,   508


3、ライセンスと例外規定及び免責事項

本ソフトウェアは、著作権者およびコントリビューターによって「現状のまま」提供
されており、明示黙示を問わず、商業的な使用可能性、および 特定の目的に対する
適合性に関する暗黙の保証も含め、またそれに限定されない、いかなる保証もない。
著作権者もコントリビューターも、事由のいかんを問わず、損害発生の原因いかんを
問わず、かつ責任の根拠が契約であるか厳格責任であるか(過失その他の)不法行為
であるかを問わず、仮にそのような損害が発生する可能性を知らされていたとしても、
本ソフトウェアの使用によって発生した(代替品または代用サービスの調達、使用の
喪失、データの喪失、利益の喪失、業務の中断も含め、またそれに限定されない)
直接損害、間接損害、偶発的な損害、特別損害、懲罰的損害、又は結果損害について、
一切責任を負わないものとする。
但し下記の制限が課される。
1、人命に危害を与える機器及びソフトウエアでの使用を禁じる。
2、前記1に記載物に連携する、機器、ソフトウエア及びシステムでの使用を禁じる。


4、終わりに

中学や高校の数学、ベクトルや、代数が如何に重要な学習だったかを痛感させられる。
やはり、数学(算数)は面白い。 対称性は美しい