#include<iostream>
#include<math.h>
#include<sstream>
#include<time.h>
#define ss stringstream
using namespace std;
int gcd( int m, int n) { // 最大公因數
if ( n == 0 )
return m;
else
return gcd( n, m % n) ;
}
bool Tangent_exist( float x, float y, float h, float k, float rsq) { //判斷切線存在
if ( ( float ) ( pow ( x- h,2 ) + pow ( y- k,2 ) - rsq) >= 0 )
return true ;
else
return false ;
}
void solve( float x, float y, float h, float k ,float rsq) { // 解方程式
float OPx = x- h, OPy = y- k, PA = sqrt ( pow ( x- h,2 ) + pow ( y- k,2 ) - rsq) , r = sqrt ( rsq) ;
float OPxO = OPx + ( PA/ r) * - ( OPy) , OPyO = OPy + ( PA/ r) * OPx, OPxN = OPx - ( PA/ r) * - ( OPy) , OPyN = OPy - ( PA/ r) * OPx;
OPxO * = 1e5 ; OPyO * = 1e5 ; OPxN * = 1e5 ; OPyN * = 1e5 ; //避免小數
ss S_OPxO, S_OPyO, S_OPxN, S_OPyN;
string operator1 = "" ,operator2= "" ;
if ( OPyO > 0 )
operator1 = "+" ;
if ( OPyN > 0 )
operator2 = "+" ;
int factor1 = gcd( abs ( OPxO) ,abs ( OPyO) ) , factor2 = gcd( abs ( OPxN) , abs ( OPyN) ) ;
OPxO / = factor1; OPyO / = factor1; OPxN / = factor2; OPyN / = factor2; //約分
string tempx1 = OPxO == 0 ? "" : "x" , tempx2 = OPxN == 0 ? "" : "x" , tempy1 = OPyO == 0 ? "" : "y" , tempy2 = OPyN == 0 ? "" : "y" ;
int ans1= OPxO* x + OPyO* y, ans2 = OPxN * x + OPyN * y;
S_OPxO << OPxO; S_OPyO << OPyO; S_OPxN << OPxN; S_OPyN << OPyN; //int -> string 以方便修改運算子、係數
if ( OPxO == 0 || OPxO == 1 )
S_OPxO.str ( "" ) ; S_OPxO.clear ( ) ;
if ( OPyO == 0 || OPyO == 1 )
S_OPyO.str ( "" ) ; S_OPyO.clear ( ) ;
if ( OPxN == 0 || OPxN == 1 )
S_OPxN.str ( "" ) ; S_OPxN.clear ( ) ;
if ( OPyN == 0 || OPyN == 1 )
S_OPyN.str ( "" ) ; S_OPyN.clear ( ) ;
if ( OPxO == OPxN) {
cout << "1條" << endl;
cout << S_OPxO.str ( ) << tempx1 << operator1 << S_OPyO.str ( ) << tempy1 << "=" << ans1 << endl;
}
else {
cout << "2條" << endl;
cout << S_OPxO.str ( ) << tempx1 << operator1 << S_OPyO.str ( ) << tempy1 << "=" << ans1 << endl;
cout << S_OPxN.str ( ) << tempx2 << operator2 << S_OPyN.str ( ) << tempy2 << "=" << ans2 << endl;
}
}
int main( ) {
double START,END;
START = clock ( ) ;
std:: ios :: sync_with_stdio ( false ) ;
std:: cin .tie ( 0 ) ;
float type, h, k, rsq, d, e, f, x, y;
cout << "請選擇圓方程式類式\n 1.一般式 x^2+y^2+dx+ey+f=0\n 2.標準式(x-h)^2+(y-k)^2=r^2" << endl;
cin >> type;
if ( type == 1 ) {
cout << "請輸入 x^2+y^2+dx+ey+f=0 之 (d,e,f)" << endl;
cout << "d : " ; cin >> d;
cout << "e : " ; cin >> e;
cout << "f : " ; cin >> f;
h = - ( d/ 2 ) ;
k = - ( e/ 2 ) ;
rsq = ( pow ( d,2 ) + pow ( e,2 ) - 4 * f) / 4 ; // R^2 rsquare
}
else {
cout << "請輸入 (x-h)^2+(y-k)^2=r^2 之 (h,k,r^2)" << endl;
cout << "h : " ; cin >> h;
cout << "k : " ; cin >> k;
cout << "r^2 : " ; cin >> rsq;
}
cout << "請輸入點座標(x,y)" << endl;
cout << "x : " ; cin >> x;
cout << "y : " ; cin >> y;
if ( Tangent_exist( x,y,h,k,rsq) ) {
cout << "切線為:" ;
solve( x,y,h,k,rsq) ;
}
else {
cout << "切線不存在" << endl;
}
END = clock ( ) ;
cout << "執行時間 : " << ( END - START) / CLOCKS_PER_SEC << "s" << endl;
}
I2luY2x1ZGU8aW9zdHJlYW0+CiNpbmNsdWRlPG1hdGguaD4KI2luY2x1ZGU8c3N0cmVhbT4KI2luY2x1ZGU8dGltZS5oPgojZGVmaW5lIHNzIHN0cmluZ3N0cmVhbQp1c2luZyBuYW1lc3BhY2Ugc3RkOwppbnQgZ2NkKGludCBtLCBpbnQgbikgeyAgLy8g5pyA5aSn5YWs5Zug5pW4CglpZihuID09IDApIAoJCXJldHVybiBtOyAKCWVsc2UgCgkJcmV0dXJuIGdjZChuLCBtICUgbik7IAp9CmJvb2wgVGFuZ2VudF9leGlzdChmbG9hdCB4LCBmbG9hdCB5LCBmbG9hdCBoLCBmbG9hdCBrLCBmbG9hdCByc3EpeyAgLy/liKTmlrfliIfnt5rlrZjlnKgKCWlmKChmbG9hdCkocG93KHgtaCwyKStwb3coeS1rLDIpIC0gcnNxKSA+PSAwKQoJCXJldHVybiB0cnVlOwoJZWxzZQoJCXJldHVybiBmYWxzZTsKfQp2b2lkIHNvbHZlKGZsb2F0IHgsIGZsb2F0IHksIGZsb2F0IGgsIGZsb2F0IGsgLGZsb2F0IHJzcSl7IC8vIOino+aWueeoi+W8jwoJZmxvYXQgT1B4ID0geC1oLCBPUHkgPSB5LWssIFBBID0gc3FydChwb3coeC1oLDIpICsgcG93KHktaywyKSAtIHJzcSksIHIgPSBzcXJ0KHJzcSk7CglmbG9hdCBPUHhPID0gT1B4ICsgKFBBL3IpICogLShPUHkpLCBPUHlPID0gT1B5ICsgKFBBL3IpICogT1B4LCBPUHhOID0gT1B4IC0gKFBBL3IpICogLShPUHkpLCBPUHlOID0gT1B5IC0gKFBBL3IpICogT1B4OwoJT1B4TyAqPSAxZTU7IE9QeU8gKj0gMWU1OyBPUHhOICo9IDFlNTsgT1B5TiAqPSAxZTU7IC8v6YG/5YWN5bCP5pW4CglzcyBTX09QeE8sIFNfT1B5TywgU19PUHhOLCBTX09QeU47CglzdHJpbmcgb3BlcmF0b3IxID0gIiIsb3BlcmF0b3IyPSAiIjsKCWlmKE9QeU8gPiAwKQoJCW9wZXJhdG9yMSA9ICIrIjsKCWlmKE9QeU4gPiAwKQoJCW9wZXJhdG9yMiA9ICIrIjsKCWludCBmYWN0b3IxID0gZ2NkKGFicyhPUHhPKSxhYnMoT1B5TykpLCBmYWN0b3IyID0gZ2NkKGFicyhPUHhOKSwgYWJzKE9QeU4pKTsKCU9QeE8gLz0gZmFjdG9yMTsgT1B5TyAvPSBmYWN0b3IxOyBPUHhOIC89IGZhY3RvcjI7IE9QeU4gLz0gZmFjdG9yMjsvL+e0hOWIhgoJc3RyaW5nIHRlbXB4MSA9IE9QeE8gPT0gMD8gIiI6ICJ4IiwgdGVtcHgyID0gT1B4TiA9PSAwPyAiIjoieCIsIHRlbXB5MSA9IE9QeU8gPT0gMD8gIiI6InkiLCB0ZW1weTIgPSBPUHlOID09IDA/ICIiOiJ5IjsKCWludCBhbnMxPSBPUHhPKnggKyBPUHlPKnksIGFuczIgPSBPUHhOICogeCArIE9QeU4gKiB5OwoJU19PUHhPIDw8IE9QeE87IFNfT1B5TyA8PCBPUHlPOyBTX09QeE4gPDwgT1B4TjsgU19PUHlOIDw8IE9QeU47Ly9pbnQgLT4gc3RyaW5nIOS7peaWueS+v+S/ruaUuemBi+eul+WtkOOAgeS/guaVuAoJaWYoT1B4TyA9PSAwIHx8IE9QeE8gPT0gMSkKCQlTX09QeE8uc3RyKCIiKTsgU19PUHhPLmNsZWFyKCk7CglpZihPUHlPID09IDAgfHwgT1B5TyA9PSAxKQoJCVNfT1B5Ty5zdHIoIiIpOyBTX09QeU8uY2xlYXIoKTsKCWlmKE9QeE4gPT0gMCB8fCBPUHhOID09IDEpCgkJU19PUHhOLnN0cigiIik7IFNfT1B4Ti5jbGVhcigpOwoJaWYoT1B5TiA9PSAwIHx8IE9QeU4gPT0gMSkKCQlTX09QeU4uc3RyKCIiKTsgU19PUHlOLmNsZWFyKCk7CglpZihPUHhPID09IE9QeE4pewoJCWNvdXQgPDwgIjHmop0iIDw8IGVuZGw7CgkJY291dCA8PCBTX09QeE8uc3RyKCkgPDwgdGVtcHgxIDw8IG9wZXJhdG9yMSA8PCBTX09QeU8uc3RyKCkgPDwgdGVtcHkxIDw8ICI9IiA8PCBhbnMxIDw8IGVuZGw7Cgl9CgllbHNlewoJCWNvdXQgPDwgIjLmop0iIDw8IGVuZGw7CgkJY291dCA8PCBTX09QeE8uc3RyKCkgPDwgdGVtcHgxIDw8IG9wZXJhdG9yMSA8PCBTX09QeU8uc3RyKCkgPDwgdGVtcHkxIDw8ICI9IiA8PCBhbnMxIDw8IGVuZGw7CgkJY291dCA8PCBTX09QeE4uc3RyKCkgPDwgdGVtcHgyIDw8IG9wZXJhdG9yMiA8PCBTX09QeU4uc3RyKCkgPDwgdGVtcHkyIDw8ICI9IiA8PCBhbnMyIDw8IGVuZGw7Cgl9Cn0KaW50IG1haW4oKXsKCWRvdWJsZSBTVEFSVCxFTkQ7CiAgICBTVEFSVCA9IGNsb2NrKCk7CglzdGQ6Omlvczo6c3luY193aXRoX3N0ZGlvKGZhbHNlKTsKICAgIHN0ZDo6Y2luLnRpZSgwKTsKCWZsb2F0IHR5cGUsIGgsIGssIHJzcSwgZCwgZSwgZiwgeCwgeTsKCWNvdXQgPDwgIuiri+mBuOaTh+Wck+aWueeoi+W8j+mhnuW8j1xuMS7kuIDoiKzlvI8geF4yK3leMitkeCtleStmPTBcbjIu5qiZ5rqW5byPKHgtaCleMisoeS1rKV4yPXJeMiIgPDwgZW5kbDsKCWNpbiA+PiB0eXBlOwoJaWYodHlwZSA9PSAxKXsKCQljb3V0IDw8ICLoq4vovLjlhaUgeF4yK3leMitkeCtleStmPTAg5LmLIChkLGUsZikiIDw8IGVuZGw7CgkJY291dCA8PCAiZCA6ICI7IGNpbiA+PiBkOwoJCWNvdXQgPDwgImUgOiAiOyBjaW4gPj4gZTsKCQljb3V0IDw8ICJmIDogIjsgY2luID4+IGY7CgkJaCA9IC0oZC8yKTsKCQlrID0gLShlLzIpOwoJCXJzcSA9IChwb3coZCwyKSArIHBvdyhlLDIpIC0gNCAqIGYpIC8gNDsgLy8gUl4yIHJzcXVhcmUKCX0KCWVsc2V7CgkJY291dCA8PCAi6KuL6Ly45YWlICh4LWgpXjIrKHktayleMj1yXjIg5LmLIChoLGsscl4yKSIgPDwgZW5kbDsKCQljb3V0IDw8ICJoIDogIjsgY2luID4+IGg7CgkJY291dCA8PCAiayA6ICI7IGNpbiA+PiBrOwoJCWNvdXQgPDwgInJeMiA6ICI7IGNpbiA+PiByc3E7CQkKCX0KCWNvdXQgPDwgIuiri+i8uOWFpem7nuW6p+aomSh4LHkpIiA8PCBlbmRsOwoJY291dCA8PCAieCA6ICI7IGNpbiA+PiB4OwoJY291dCA8PCAieSA6ICI7IGNpbiA+PiB5OwoJaWYoVGFuZ2VudF9leGlzdCh4LHksaCxrLHJzcSkpewoJCWNvdXQgPDwgIuWIh+e3mueCuu+8miI7CgkJc29sdmUoeCx5LGgsayxyc3EpOwoJfQoJZWxzZXsKCQljb3V0IDw8ICLliIfnt5rkuI3lrZjlnKgiIDw8IGVuZGw7Cgl9CglFTkQgPSBjbG9jaygpOwoJY291dCA8PCLln7fooYzmmYLplpMgOiAiIDw8IChFTkQgLSBTVEFSVCkgLyBDTE9DS1NfUEVSX1NFQyA8PCAicyI8PCBlbmRsOwp9