Re: [問題] 線與圓 聯立方程式

看板C_and_CPP作者 (藍影)時間14年前 (2010/08/28 15:23), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串4/4 (看更多)
(x-h)^2 + (y-k)^2 = r^2 ... (1) ax + by + c = 0 ... (2) (一).若 |ah-bk+c| / sqrt(a^2 + b^2) > r , 則不相交 (二).若 |ah-bk+c| / sqrt(a^2 + b^2) = r , 相切 (三).若 |ah-bk+c| / sqrt(a^2 + b^2) < r , 相割 (如果是 case (二)、(三),進行以下運算) 化簡 (2) x = (-1/a)(by+c) ... (3) (3) 代入 (1) [-(by+c)/a - h]^2 + (y-h)^2 = r^2 => (by/a)^2 + 2(b/a)(c/a+h)y + (c/a+h)^2 + (y^2-2yk+k^2) = r^2 => ( (b^2/a^2)y^2 + (2bc/(a^2) + 2bc/a)y + (c/a+h)^2 + (y^2-2yk+k^2) = r^2 => [ (b^2)/(a^2) + 1 ] y^2 + [2bc/(a^2) + (2bh)/a - 2k] y + [(c/a+h)^2 +k^2 - r^2] = 0 ... (4) 令 [ (b^2)/(a^2) + 1 ] = a1 [2bc/(a^2) + (2bh)/a - 2k] = a2 [(c/a+h)^2 +k^2 - r^2] = a3 則 (4) 可變為 a1*y^2 + b1*y + c1 = 0 ... (5) 解 (5) 之方程式解,可得 y1 = (-b1 + sqrt(b1*b1-4ac)) / (2a1), 代入 (3), 得 x1 = /(b1y1+c)/a1 y2 = (-b1 - sqrt(b1*b1-4ac)) / (2a1), 代入 (3), 得 x2 = /(b1y2+c)/a1 ========================================== 之前有寫過一份 code, 重點部份如下所示 int Circle_Line(const double h, const double k, const double r, const double a, const double b, const double c, double *x1, double *y1, double *x2, double *y2) { const double a1 = (b*b/a/a+1.0); const double b1 = 2.0*b*c/a/a + 2.0*b*h/a - 2.0*k; const double c1 = (c/a+h)*(c/a+h) + k*k - r*r; double delta = fabs(a*h+b*k+c) / sqrt(a*a+b*b); if(delta > r) { // 不相交, 無解 return 1; } else if (delta == r) { // 相切, 唯一解 *y1 = -b1/2.0/a1 + sqrt(b1*b1-4*a1*c1)/2.0/a1; *x1 = -b1*(*y1)/a1 - c1/a1; *y2 = -b1/2.0/a1 - sqrt(b1*b1-4*a1*c1)/2.0/a1; *x2 = -b1*(*y1)/a1 + c1/a1; return 2; } else if(delta < r) { // 相割, 有二解 *y1 = -b1/2.0/a1 + sqrt(b1*b1-4*a1*c1)/2.0/a1; *x1 = -b1*(*y1)/a1 - c1/a1; *y2 = -b1/2.0/a1 - sqrt(b1*b1-4*a1*c1)/2.0/a1; *x2 = -b1*(*y1)/a1 + c1/a1; return 3; } else { // 保留錯誤 return 0; } } // =================================================== 翻寫過的測試程式碼如下連結 http://ppt.cc/X@7O 使用此程式請注意以下問題: (1) 沒考慮浮點數精度問題 (這點很重要!!) (2) 輸入之圓一定要是標準式 (如果只有一般式,請先寫個程式轉標準式..) (3) 如果你會數值分析的話,其實 [-(by+c)/a - h]^2 + (y-h)^2 = r^2 在這個式子裡面你就可以用數值分析法去求 y 值了, 只是化簡完會比較快 ( 有關方程式求解的數值分析法, 可以參考這裡 http://ppt.cc/SjKa ) (4) code 只是簡單的範例, 其它的要擴請自行擴, 要封請加油 ^^ (5) 用 NTUxp 大大的方式解得更快, x = h+r*cosΘ, y=k+r*sinΘ, a*(h+r*cosΘ) + b*(k+r*sinΘ) + c = 0 可利用 sinΘ = sqrt(1-cosΘ*costΘ) 方式 再次代入求解, 如有興趣, 可比較這二種方法之精度何種較正確. -- 我期待 我等待 肩狹骨上的翅膀早些長出來 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.76.142 ※ 編輯: tropical72 來自: 180.177.76.142 (08/28 15:30) ※ 編輯: tropical72 來自: 180.177.76.142 (08/28 15:35)
文章代碼(AID): #1CUBcAoq (C_and_CPP)
文章代碼(AID): #1CUBcAoq (C_and_CPP)