日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

三点共圆公式

發(fā)布時間:2024/8/26 综合教程 31 生活家
生活随笔 收集整理的這篇文章主要介紹了 三点共圆公式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

我們設(shè)一個圓的圓心坐標(biāo)為,半徑為 r 。那么這個圓的方程可以寫為:

在這個圓上隨便取三個點,設(shè)這三個點的坐標(biāo)分別是那么有:

公式(1)(2)相減,(1)(3)相減之后經(jīng)過化簡可以得到:

有唯一解的條件是系數(shù)行列式不為 0 :

簡單變變型也就是:

這樣寫幾何含義就很明顯了,三點不能共線。

設(shè):

那么 :

有了 x 0 和 y 0 的值后,帶入(1) 式就可以得到 r 的值。至此,三點確定圓的問題就解決了。

三點共圓求圓心的模版:

double X, Y;
struct Point
{
    double x, y;
} a[2005];
void solve(Point a, Point b, Point c) //三點共圓圓心公式
{
    double fm1=2 * (a.y - c.y) * (a.x - b.x) - 2 * (a.y - b.y) * (a.x - c.x); // 2 (da - bc)
    double fm2=2 * (a.y - b.y) * (a.x - c.x) - 2 * (a.y - c.y) * (a.x - b.x);  // 2 (bc - ad)

    if (fm1 == 0 || fm2 == 0)
    {
        X = Y = 1e18;
        return;
    }
    double fz1=a.x * a.x - b.x * b.x + a.y * a.y - b.y * b.y;   // e
    double fz2=a.x * a.x - c.x * c.x + a.y * a.y - c.y * c.y;   // f
    X = (fz1 * (a.y - c.y) - fz2 * (a.y - b.y)) / fm1; // x0
    Y = (fz1 * (a.x - c.x) - fz2 * (a.x - b.x)) / fm2; // y0
}

例題:Boundary

題意:
給了n個點,讓你自己隨便定義圓心(圓心不要求是n個點的其中一個)和半徑,要求這n個點有盡可能多的點在圓上,并且該圓經(jīng)過坐標(biāo)原點(0,0)。求滿足的圓上的點最多有多少個。

想法:

由于必須經(jīng)過原點,所以我們可以只枚舉兩個點從而就可以達(dá)到枚舉圓心的目的?!疽驗槿c共圓】

用vector保存下來這些圓心坐標(biāo)。

處理完后,對圓心坐標(biāo)sort一下,判斷有多少個圓心坐標(biāo)是一樣的。

再要尋找有幾個點在圓上,我們可以枚舉圓上的點。

滿足 x * (x - 1 ) / 2 == ans

這個時候的 x 就是我們所求的

#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <ctime>
#include <bitset>
#include <cmath>
#include <sstream>
#include <iostream>
#include <unordered_map>

#define ll long long
#define ull unsigned long long
#define ls nod<<1
#define rs (nod<<1)+1
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define INF 0x3f3f3f3f
#define max(a, b) (a>b?a:b)
#define min(a, b) (a<b?a:b)


const double eps = 1e-8;
const int maxn = 2e5 + 10;
const ll MOD = 99999999999999;
const int mlog=20;

int sgn(double a) { return a < -eps ? -1 : a < eps ? 0 : 1; }

using namespace std;

double X, Y;
struct Point
{
    double x, y;
} a[2005];
void solve(Point a, Point b, Point c) //三點共圓圓心公式
{
    double fm1=2 * (a.y - c.y) * (a.x - b.x) - 2 * (a.y - b.y) * (a.x - c.x); // 2 (da - bc)
    double fm2=2 * (a.y - b.y) * (a.x - c.x) - 2 * (a.y - c.y) * (a.x - b.x);  // 2 (bc - ad)

    if (fm1 == 0 || fm2 == 0)
    {
        X = Y = 1e18;
        return;
    }
    double fz1=a.x * a.x - b.x * b.x + a.y * a.y - b.y * b.y;   // e
    double fz2=a.x * a.x - c.x * c.x + a.y * a.y - c.y * c.y;   // f
    X = (fz1 * (a.y - c.y) - fz2 * (a.y - b.y)) / fm1; // x0
    Y = (fz1 * (a.x - c.x) - fz2 * (a.x - b.x)) / fm2; // y0
}
vector<pair<double,double>> mpp;
int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%lf%lf", &a[i].x, &a[i].y);

    for (int i = 1; i <= n; i++){
        for (int j = i + 1; j <= n; j++){
            solve({0, 0}, a[i], a[j]);
            if (X == Y && sgn(X-1e18) == 0)
                continue;
            mpp.push_back({X,Y});
        }
    }
    if(mpp.size()==0){
        putchar('1');
        return 0;
    }
    sort(mpp.begin(),mpp.end());
    int ma = 1;
    int num = 1;
    pair<double,double> now=mpp[0];
    for(int i=1;i<mpp.size();i++){
        if(mpp[i]==now) ++num;
        else{
            now=mpp[i];
            ma=max(ma,num);
            num=1;
        }
        ma=max(ma,num);
    }
    for (int i = 1; i <= n; i++){
        if (i * (i - 1) == ma * 2){
            printf("%d
", i);
            return 0;
        }
    }
    return 0;
}

總結(jié)

以上是生活随笔為你收集整理的三点共圆公式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。