sponsored links

完美級的貝塞爾曲線演算法「空間有影片講解,你應該想不到更好的」

基本原理就是分成2部分和一點,然後遞迴。

比如4點曲線的基本原理:

圖1的藍線=圖3的綠線+曲線點【紅綠交點】+圖3的紅線;

圖3的綠線=>圖1的藍線;

圖3的紅線=>圖1的藍線;

完美級的貝塞爾曲線演算法「空間有影片講解,你應該想不到更好的」

完美級的貝塞爾曲線演算法「空間有影片講解,你應該想不到更好的」


struct xyf;
struct xy{
    int x;
    int y;

    xy(){
    }
    xy(int m){
        x=m;
        y=m;
    }
    xy(int x,int y){
        this->x=x;
        this->y=y;
    }
    xy(xyf m);
xy operator  *(xy&m){return xy(x *m.x,y *m.y);}
xy operator  /(xy&m){return xy(x /m.x,y /m.y);}
xy operator  %(xy&m){return xy(x %m.x,y %m.y);}
xy operator  +(xy&m){return xy(x +m.x,y +m.y);}
xy operator  -(xy&m){return xy(x -m.x,y -m.y);}
xy operator <<(xy&m){return xy(x<<m.x,y<<m.y);}
xy operator >>(xy&m){return xy(x>>m.x,y>>m.y);}
xy operator  &(xy&m){return xy(x &m.x,y &m.y);}
xy operator  |(xy&m){return xy(x |m.x,y |m.y);}
xy operator  ^(xy&m){return xy(x ^m.x,y ^m.y);}
xy operator  *=(xy&m){x *=m.x;y *=m.y;return *this;}
xy operator  /=(xy&m){x /=m.x;y /=m.y;return *this;}
xy operator  %=(xy&m){x %=m.x;y %=m.y;return *this;}
xy operator  +=(xy&m){x +=m.x;y +=m.y;return *this;}
xy operator  -=(xy&m){x -=m.x;y -=m.y;return *this;}
xy operator <<=(xy&m){x<<=m.x;y<<=m.y;return *this;}
xy operator >>=(xy&m){x>>=m.x;y>>=m.y;return *this;}
xy operator  &=(xy&m){x &=m.x;y &=m.y;return *this;}
xy operator  |=(xy&m){x |=m.x;y |=m.y;return *this;}
xy operator  ^=(xy&m){x ^=m.x;y ^=m.y;return *this;}
xy operator  *(int m){return xy(x *m,y *m);}
xy operator  /(int m){return xy(x /m,y /m);}
xy operator  %(int m){return xy(x %m,y %m);}
xy operator  +(int m){return xy(x +m,y +m);}
xy operator  -(int m){return xy(x -m,y -m);}
xy operator <<(int m){return xy(x<<m,y<<m);}
xy operator >>(int m){return xy(x>>m,y>>m);}
xy operator  &(int m){return xy(x &m,y &m);}
xy operator  |(int m){return xy(x |m,y |m);}
xy operator  ^(int m){return xy(x ^m,y ^m);}
xy operator  *=(int m){x *=m;y *=m;return *this;}
xy operator  /=(int m){x /=m;y /=m;return *this;}
xy operator  %=(int m){x %=m;y %=m;return *this;}
xy operator  +=(int m){x +=m;y +=m;return *this;}
xy operator  -=(int m){x -=m;y -=m;return *this;}
xy operator <<=(int m){x<<=m;y<<=m;return *this;}
xy operator >>=(int m){x>>=m;y>>=m;return *this;}
xy operator  &=(int m){x &=m;y &=m;return *this;}
xy operator  |=(int m){x |=m;y |=m;return *this;}
xy operator  ^=(int m){x ^=m;y ^=m;return *this;}
bool operator  <(xy&m){return((unsigned(x) <unsigned(m.x))&&(unsigned(y) <unsigned(m.y)));}
bool operator  >(xy&m){return((unsigned(x) >unsigned(m.x))&&(unsigned(y) >unsigned(m.y)));}
bool operator <=(xy&m){return((unsigned(x)<=unsigned(m.x))&&(unsigned(y)<=unsigned(m.y)));}
bool operator >=(xy&m){return((unsigned(x)>=unsigned(m.x))&&(unsigned(y)>=unsigned(m.y)));}
bool operator ==(xy&m){return((unsigned(x)==unsigned(m.x))&&(unsigned(y)==unsigned(m.y)));}
bool operator  <(int m){return((unsigned(x) <unsigned(m))&&(unsigned(y) <unsigned(m)));}
bool operator  >(int m){return((unsigned(x) >unsigned(m))&&(unsigned(y) >unsigned(m)));}
bool operator <=(int m){return((unsigned(x)<=unsigned(m))&&(unsigned(y)<=unsigned(m)));}
bool operator >=(int m){return((unsigned(x)>=unsigned(m))&&(unsigned(y)>=unsigned(m)));}
bool operator ==(int m){return((unsigned(x)==unsigned(m))&&(unsigned(y)==unsigned(m)));}
xy operator  !(){return xy( !x, !y);}
xy operator  ~(){return xy( ~x, ~y);}
xy operator  +(){return xy( +x, +y);}
xy operator  -(){return xy( -x, -y);}

    xy get_number(){
        xy m=0;
        if(x>0)m.x=+x;if(x<0)m.x=-x;
        if(y>0)m.y=+y;if(y<0)m.y=-y;
        return m;
    }
    xy get_flag(){
        xy m=0;
        if(x>0)m.x=+1;if(x<0)m.x=-1;
        if(y>0)m.y=+1;if(y<0)m.y=-1;
        return m;
    }

    void x_y(){
        int v=x;x=y;y=v;
    }
    int xx(){return x*x;}
    int yy(){return y*y;}
    int xx_yy(){
        return (x*x+y*y);
    }

    xy operator =(xy&m){
        x=m.x;
        y=m.y;
        return *this;
    }
    xy operator =(int m){
        x=m;
        y=m;
        return *this;
    }
    xy operator ++(int){
        xy temp=*this;
        ++x;
        ++y;
        return temp;
    }
    xy operator ++(){
        x++;
        y++;
        return *this;
    }

    xy operator --(int){
        xy temp=*this;
        --x;
        --y;
        return temp;
    }
    xy operator --(){
        x--;
        y--;
        return *this;
    }

};

struct xyf{
    double x;
    double y;

    xyf(){
    }
    xyf(double m){
        x=m;
        y=m;
    }
    xyf(double x,double y){
        this->x=x;
        this->y=y;
    }
    xyf(xy m){
        this->x=m.x;
        this->y=m.y;
    }
xyf operator  *(xyf&m){return xyf(x *m.x,y *m.y);}
xyf operator  /(xyf&m){return xyf(x /m.x,y /m.y);}
xyf operator  +(xyf&m){return xyf(x +m.x,y +m.y);}
xyf operator  -(xyf&m){return xyf(x -m.x,y -m.y);}
xyf operator  *=(xyf&m){x *=m.x;y *=m.y;return *this;}
xyf operator  /=(xyf&m){x /=m.x;y /=m.y;return *this;}
xyf operator  +=(xyf&m){x +=m.x;y +=m.y;return *this;}
xyf operator  -=(xyf&m){x -=m.x;y -=m.y;return *this;}
xyf operator  *(double m){return xyf(x *m,y *m);}
xyf operator  /(double m){return xyf(x /m,y /m);}
xyf operator  +(double m){return xyf(x +m,y +m);}
xyf operator  -(double m){return xyf(x -m,y -m);}
xyf operator  *=(double m){x *=m;y *=m;return *this;}
xyf operator  /=(double m){x /=m;y /=m;return *this;}
xyf operator  +=(double m){x +=m;y +=m;return *this;}
xyf operator  -=(double m){x -=m;y -=m;return *this;}

    xyf get_number(){
        xyf m=0;
        if(x>0)m.x=+x;if(x<0)m.x=-x;
        if(y>0)m.y=+y;if(y<0)m.y=-y;
        return m;
    }
    xyf get_flag(){
        xyf m=0;
        if(x>0)m.x=+1;if(x<0)m.x=-1;
        if(y>0)m.y=+1;if(y<0)m.y=-1;
        return m;
    }

    void x_y(){
        double v=x;x=y;y=v;
    }
    double xx(){return x*x;}
    double yy(){return y*y;}
    double xx_yy(){
        return (x*x+y*y);
    }

    xyf operator =(xy&m){
        x=m.x;
        y=m.y;
        return *this;
    }
    xyf operator =(xyf&m){
        x=m.x;
        y=m.y;
        return *this;
    }
    xyf operator =(double m){
        x=m;
        y=m;
        return *this;
    }
    xyf operator ++(int){
        xyf temp=*this;
        ++x;
        ++y;
        return temp;
    }
    xyf operator ++(){
        x++;
        y++;
        return *this;
    }

    xyf operator --(int){
        xyf temp=*this;
        --x;
        --y;
        return temp;
    }
    xyf operator --(){
        x--;
        y--;
        return *this;
    }

};

xy::xy(xyf m){
        x=m.x;
        y=m.y;
    }

int paint_line(xy r,xy *da){
    // float->int (f+0.5)
    // [-0.5,+0.5)=0
    // [+0.5,+1.5)=1
    // [+1.5,+2.5)=2
    // x*a+b*y=0;
    // (x+v)*a=x*a+v*a;
    // (y+v)*a=y*a+v*a;
    xy n=r.get_number();
    xy f=r.get_flag();
    xy nn=n*2;
    xy d=0;
    xy*db=da;
    *db++=d;
    if(n.y<n.x){
        int v=n.x;
        while(d.x!=r.x){
            d.x+=f.x;
            v-=nn.y;
            if(v<0){
                v+=nn.x;
                d.y+=f.y;
            }
            *db++=d;
        }
    }else{
        int v=n.y;
        while(d.y!=r.y){
            d.y+=f.y;
            v-=nn.x;
            if(v<0){
                v+=nn.y;
                d.x+=f.x;
            }
            *db++=d;
        }
    }
    return (db-da);
}
int paint_line(xy a,xy b,xy *da){
    int dn=paint_line(b-a,da);
    for(int i=0;i<dn;i++)da[i]+=a;
    return dn;
}

const int curve_max=10;
const int curve_bit=16;
const int curve_bit_add=1<<(curve_bit-1);
xy curve_get(xy m){
    m+=curve_bit_add;
    m>>=curve_bit;
    return m;
}
xy*curve_call3(xy s1,xy s2,xy s3,xy*da){
    xy y1=(s1+s2)>>1;
    xy y2=(s2+s3)>>1;
    xy zz=(y1+y2)>>1;
    xy z=curve_get(zz);
    if(z==curve_get(s1))return da;
    if(z==curve_get(s3))return da;
    da=curve_call3(s1,y1,zz,da);
    *da++=z;
    da=curve_call3(s3,y2,zz,da);
    return da;
}
xy*curve_call4(xy s1,xy s2,xy s3,xy s4,xy*da){
    xy x1=(s1+s2)>>1;
    xy x2=(s2+s3)>>1;
    xy x3=(s3+s4)>>1;
    xy y1=(x1+x2)>>1;
    xy y2=(x2+x3)>>1;
    xy zz=(y1+y2)>>1;
    xy z=curve_get(zz);
    if(z==curve_get(s1))return da;
    if(z==curve_get(s4))return da;
    da=curve_call4(s1,x1,y1,zz,da);
    *da++=z;
    da=curve_call4(s4,x3,y2,zz,da);
    return da;
}
xy*curve_call(xy*sa,int sn,xy*da){
    xy a[curve_max];
    xy b[curve_max];
    xy s[curve_max];
    for(int i=0;i<sn;i++)s[i]=sa[i];
    for(int n=sn,j=0;0<n;n--,j++){
        a[j]=s[0];
        b[j]=s[n-1];
        for(int i=1;i<n;i++)s[i-1]=(s[i-1]+s[i])>>1;;
    }
    xy z=curve_get(s[0]);
    if(z==curve_get(sa[0]))return da;
    if(z==curve_get(sa[sn-1]))return da;
    da=curve_call(a,sn,da);
    *da++=z;
    da=curve_call(b,sn,da);
    return da;
}

int curve(xy*sa__,int sn,xy*da){
    if(sn==2)return paint_line(sa__[0],sa__[1],da);

    if(3<=sn&&sn<=curve_max){}else return 0;
    xy sa[curve_max];
    for(int i=0;i<sn;i++)sa[i]=sa__[i]<<curve_bit;
    xy*db=da;
    *db++=curve_get(sa[0]);
    db=curve_call(sa,sn,db);
    /*
    if(0){
    }else if(3==sn){db=curve_call3(sa[0],sa[1],sa[2],db);
    }else if(4==sn){db=curve_call4(sa[0],sa[1],sa[2],sa[3],db);
    }else return 0;
    */
    *db++=curve_get(sa[sn-1]);

    return db-da;
}

分類: 數碼
時間: 2022-02-05

相關文章

三星正式開啟Galaxy Z Fold/Flip3旗艦摺疊屏手機12期免息支付

三星正式開啟Galaxy Z Fold/Flip3旗艦摺疊屏手機12期免息支付
筆歌科技獨家報道:三星方面訊息,其年度旗艦摺疊屏手機Galaxy Z Fold/Flip3正式向中國區消費者開啟12期免息支付,給到消費者更多的便利和多種靈活的支付方式,而且還對SAMSUNG Car ...

榮耀30pro使用感受,華為最後的榮耀

榮耀30pro使用感受,華為最後的榮耀
去年雙十一入手的一部榮耀30pro8+128G,3699元24期免息.現在看來是真香啊. 外觀部分:鈦空銀配色,6.57英寸oled雙曲面屏,解析度2340×1080.曲面屏還是有點偏綠,平時使用也並 ...

開上街回頭率100%,頂配都不到14萬!這兩款SUV真讓人糾結
[太平洋汽車網 導購頻道]相信大多數年輕女性購車的首要素都會先看車輛外觀,一款高顏值.高配置的車型更能吸引她們的注意.而在新能源這個細分市場上,就有兩臺專門面向年輕女性使用者群體的車型,分別是比亞迪元 ...

Windows京東超級品牌日新品集結 爆款筆記本直降千元點燃京東11.11

Windows京東超級品牌日新品集結 爆款筆記本直降千元點燃京東11.11
對於辦公一族來說,微軟Windows 11正式推送,不僅吸引了許多Windows 10 的"鐵桿兒"粉絲第一時間完成升級,更有一大批使用者對預裝了Windows 11的PC新品躍躍 ...

中國摩博會┃29980元起!力帆KPT400新車釋出

中國摩博會┃29980元起!力帆KPT400新車釋出
國內外摩托車資訊! 2021年重慶摩展,力帆摩托時隔多年後再次亮相.品牌以"全面進化論"為主題,釋出全新中大排KPT400.KP家族十週年新品KPS150以及KPM150 cafe ...

中秋換機指南 安卓旗艦換機最高抵扣6000元

中秋換機指南 安卓旗艦換機最高抵扣6000元
中秋將至,與家人歡聚團圓的同時,有沒有想給自己換一臺手機的想法? 下半年值得買的安卓旗艦好機都在這了.總有一款適合你. vivoX70 Pro+,它搭載後置四攝,分別是5000W主攝.4800W畫素微 ...

艾瑞澤e限時優惠 店內讓利達8000元

艾瑞澤e限時優惠 店內讓利達8000元
[奇瑞新能源合肥君之泰小螞蟻汽車銷售4S店]艾瑞澤e新能源車正在銷售中,顏色可選,目前購車享8000元現金優惠,感興趣的朋友可以到店諮詢購買. 小螞蟻20萬蟻粉款五重豪禮來襲,讓我們一起來康康吧! 一 ...

5個月下跌900元,2k+5000mAh+IP68,優質旗艦頻降價

5個月下跌900元,2k+5000mAh+IP68,優質旗艦頻降價
手機市場‍ 手機市場上的高階手機產品也是佔據著非常大的一部分市場份額的,但是國內的高階大家產品在國外往往並不好銷售. 隨著國內手機市場的逐漸發展啊,如今國內手機市場上的高階旗艦手機產品也並不少,並且現 ...

凡爾賽C5X:預售期收取訂單20個,只有一臺現車還被拉去做外展

凡爾賽C5X:預售期收取訂單20個,只有一臺現車還被拉去做外展
大家好,我是東風標緻/雪鐵龍的銷售顧問,你沒看錯,確實是併網銷售.今天為大家帶來的是一款新車搶拍:凡爾賽C5X. 新車是哪天到店的? 8月上旬就有一臺展車到店了,是鎏金綠次頂配,後續車輛原本預計要等到 ...

京東電腦數碼大勢新品賞 一站式解鎖潮流趨勢新品

京東電腦數碼大勢新品賞 一站式解鎖潮流趨勢新品
當生活一成不變時,你會如何應對?不如來點新的變化!近日,京東電腦數碼聯手京東小魔方為年輕人打造了一場大勢新品賞,推出高效能輕薄本.家用投影儀.降噪耳機.運動相機.學習機等各類趨勢新品,加上限量搶24期 ...

雙11競裝怎麼選 華碩主機板實力暢遊《孤島驚魂6》
令玩家們期待已久的<孤島驚魂6>近日正式上線,這是由育碧製作的第一人稱射擊遊戲<孤島驚魂>系列新作.遊戲將玩家帶到美麗但又動盪不安的熱帶島嶼雅拉,在這裡玩家將體驗游擊戰的緊張刺 ...

雙11必備競裝 華碩吹雪主機板玩轉《喋血復仇》

雙11必備競裝 華碩吹雪主機板玩轉《喋血復仇》
合作生存類遊戲<喋血復仇>於10月13日正式發售.這款遊戲的玩法模式與<求生之路>系列非常相似,但在畫質方面相對於<求生之路>來說有了跨時代的升級,槍械種類.揹包物 ...

同價位入手 天籟和帕薩特誰更值得推薦?

同價位入手 天籟和帕薩特誰更值得推薦?
[太平洋汽車網 導購頻道]手握20萬你會選什麼車?很多人的答案都不太一樣,可能會選中型轎車,也有可能是緊湊型SUV.不過無論你選什麼,絕大部分的人都希望可以選上價效比最高的那一款.那麼問題來了,若是選 ...

京東家電“新風補給站”來了 手把手教你挑選適合自己的新風空調

京東家電“新風補給站”來了 手把手教你挑選適合自己的新風空調
9月17日-21日,京東家電在北京啟動"新風補給站"活動,為消費者科普新風空調的相關知識,並且在現場及線上同步推出優惠--空調以舊換新至高補貼2000元,指定型號365天只換不修等 ...

購買 iPhone 13 是選擇首發,還是等雙十一?

購買 iPhone 13 是選擇首發,還是等雙十一?
首先iPhone每年都有買首發的剛需,不為了別的,只為了在朋友圈第一個展示最新款的iPhone. 首銷的時候滿頭大汗地搶購,搶到之後心裡暗暗高興,看著朋友圈滿螢幕的沒搶到的遺憾之音,不由得想要炫耀. ...

媽媽要螢幕大一點,電池久一點:紅米 Note 9 5G輕測評

媽媽要螢幕大一點,電池久一點:紅米 Note 9 5G輕測評
創作立場宣告:本機是自己在某東購入,和大家分享一下我的購買和使用體驗. 購買理由 前段時間老媽跟我說她的iPhone續航確實不太好,需要一個手機在出門的時候看看新聞.刷刷抖音之類的.需求就是電池耐用一 ...

年中盤點,千元機價位,這幾款買到就是賺到

年中盤點,千元機價位,這幾款買到就是賺到
隨著社會的發展,人們的工作和娛樂方式得以改變,手機從通訊工具逐漸變成了我們日常生活中不可缺少的存在,人們對於手機的效能需求也逐漸的日益迫切起來,伴隨而來的是各大手機廠商開始著重於高階機的發展,卻忽略了 ...

太瘋狂!iPhone13賣爆了,蘋果官網被買到崩,加量不加價底氣何在?新機備貨資料遭洩密 #熱點覆盤#
如果蘋果釋出會是果粉的"春晚",那麼發售階段的火爆程度則等同於"春運". 9月17日,iPhone 13系列正式開啟預售,"加量不加價"的新 ...

盤點那些釋出了但又沒完全釋出的概念手機

盤點那些釋出了但又沒完全釋出的概念手機
說起概念機,我最早的印象可能是刷爆朋友圈的iPhone 5s,那夢幻般的渲染圖,即使是8年後的現在來看,也是相當驚豔的產品.不過網上流傳的這些圖片,大多也都是網友憑空想象然後透過Ps等技術製作出來的. ...

為什麼要買蘋果手機

為什麼要買蘋果手機
原因一:自從買過蘋果6S後就沒買過新手機,6s後用的是孩子淘汰下來的蘋果7,iphone7太垃圾,電池不耐用,微信總卡機,還不如6s,但是6s壞了. 原因二:目前家裡人都用華為,一部是今年年初上市的m ...