Logo yyhs_shihaotian的博客

博客

Galaxy源码

2024-04-02 17:23:54 By yyhs_shihaotian

未经授权,禁止搬运

#include<bits/stdc++.h>
#define int long long
#define fir first
#define sec second
using namespace std;
const double eps=5e-4,phi=3.14159;
const int INF=1e4,mod=1e9+7;
const double bg=1e-3;
static int rdm=1e6,cur=0;
int real_rand(){
    rdm=rdm*rdm+rand();
    rdm=(rdm%mod+mod)%mod;
    return rdm;
}
bool fail(double prob){return (real_rand()%INF)>=prob*INF;}
int limited_rand(int minx,int maxn){return real_rand()%(maxn-minx+1)+minx;}
double double_rand(double minx,double maxn){return (double)limited_rand(minx*INF,maxn*INF)/(double)INF;}
double rand_angle(){return double_rand(0.0,2.0*phi);}
void adjust(double &gen,double noise_val){gen=max(gen,noise_val);}
struct node{
    double x,y,z;
    node(){x=0.0;y=0.0;z=0.0;}
    node(double _x,double _y,double _z){x=_x;y=_y;z=_z;}
    double dis(){return sqrt(pow(x,2)+pow(y-cur,2)+pow(z,2));}
    double dis(node b){return sqrt(pow(x-b.x,2)+pow(y-b.y,2)+pow(z-b.z,2));}
};
struct base{
    node x,y,z;
    base(){
        double ang=rand_angle();x.x=cos(ang);x.y=sin(ang);
        ang=rand_angle();x.x*=cos(ang);x.y*=cos(ang);x.z=sin(ang);
        ang=rand_angle();y.x=cos(ang);y.y=sin(ang);
        ang=atan(-(x.x*y.x+x.y*y.y)/x.z);
        y.x*=cos(ang);y.y*=cos(ang);y.z=sin(ang);
        double k1=(x.z*y.x-x.x*y.z)/(x.y*y.z-x.z*y.y);
        double k2=(x.x*y.y-x.y*y.x)/(x.y*y.z-x.z*y.y);
        z.x=sqrt(1.0/(1.0+k1*k1+k2*k2));z.y=z.x*k1;z.z=z.x*k2;
    }
    pair<double,double> turn(double _x,double _y){
        double _tmp=(x.x*y.y-x.y*y.x);
        double res_x=(_x*y.y-_y*y.x)/_tmp,res_y=(x.x*_y-_x*x.y)/_tmp;
        return make_pair(res_x,res_y);
    }
};
const double nbl_r_min=100.0,nbl_r_max=200.0;
const double nbl_den_min=0.5,nbl_den_max=0.75;
struct nbl_dot{
    node vec;
    double r;
    double den;
    nbl_dot(){
        r=double_rand(nbl_r_min,nbl_r_max);
        vec=node(-2.0*r-10.0,cur,double_rand(-0.8*r,0.0));
        den=double_rand(nbl_den_min,nbl_den_max);
    }
    double dis(){return vec.dis();}
    double den_val(){return min(den,bg*pow(r,2)/pow(dis(),2));}
};
vector<nbl_dot> nbl;
namespace nbl_op{
    void add(){
        if (fail(1e-3)) return;
        nbl.push_back(nbl_dot());
    }
    void adj_den(double &den){for(int i=0;i<nbl.size();i++) adjust(den,nbl[i].den_val());}
    void release(){while(!nbl.empty()&&nbl[0].vec.x>nbl[0].r) nbl.erase(nbl.begin());}
}
const double pln_r_min=10.0,pln_r_max=60.0;
const double pln_den_min=0.2,pln_den_max=0.5;
struct pln_dot{
    node vec;
    double r,den;
    base bas;
    bool had_ring;
    pln_dot(){
        r=double_rand(pln_r_min,pln_r_max);
        vec=node(-2.0*r-10.0,cur,double_rand(-0.8*r,0));
        had_ring=!(rand()%3);
        den=double_rand(pln_den_min,pln_den_max);
    }
    double dis(){return vec.dis();}
    double dis(pln_dot b){return vec.dis(b.vec);}
    double den_val(double rz){
        double _res=0.0;
        double _dis=sqrt(pow(vec.x,2)+pow(vec.y-cur,2));
        if (_dis<=0.8*r) _res=max(_res,(_dis>=0.75*r)?0.95:den);
        if (!had_ring) return _res;
        pair<double,double> _cur=bas.turn(0.0,cur),_vec=bas.turn(vec.x,vec.y);
        _dis=sqrt(pow(_cur.fir-_vec.fir,2)+pow(_cur.sec-_vec.sec,2));
        if (_dis>=1.3*r&&_dis<=1.35*r||_dis>=1.85*r&&_dis<=1.9*r) _res=max(_res,0.95);
        else if (_dis>=1.35*r&&_dis<=1.85*r) _res=max(_res,0.3);
        return _res;
    }
    double sz(){return 2.0*r;}
};
bool pln_touched(pln_dot x1,pln_dot y1){return x1.dis(y1)<=x1.sz()+y1.sz();}
vector<pln_dot> pln;
namespace pln_op{
    void check(){
        for(int i=0;i<pln.size()-1;i++){
            if (!pln_touched(pln[i],pln[pln.size()-1])) continue;
            pln.erase(pln.begin()+pln.size()-1);return;
        }
    }
    void add(){
        if (fail(1e-3)||fail(5e-2)) return;
        pln.push_back(pln_dot());
        check();
    }
    void adj_den(double &den){for(int i=0;i<pln.size();i++) adjust(den,pln[i].den_val(0.0));}
    void release(){while(!pln.empty()&&pln[0].vec.x>pln[0].sz()) pln.erase(pln.begin());}
}
void up(){
    for(int i=0;i<nbl.size();i++) nbl[i].vec.x+=2.0;
    for(int i=0;i<pln.size();i++) pln[i].vec.x+=2.0;
}
void print(double &den){
    putchar(fail(den)?' ':'.');den=bg;
    if (cur^235){++cur;return;}
    putchar('\n');
    cur=0;up();
}
void add(){
    nbl_op::add();
    pln_op::add();
}
void adj_den(double &den){
    nbl_op::adj_den(den);
    pln_op::adj_den(den);
}
void release(){
    nbl_op::release();
    pln_op::release();
}
signed main(){
    srand(time(0));
    for(double den=bg;;release()){
        add();
        adj_den(den);
        print(den);
    }
    return 0;
}

Galaxy by coldicy

2024-04-01 13:26:16 By yyhs_shihaotian

Galaxy by coldicy

源码


更新日志

upd 2024.3.27

增添了行星环

upd 2024.3.29

封装了天体结构,增添了注释

upd 2024.3.30

增添了星云集群生成

upd 2024.4.2

将天体扩展为立体投影。

删除了体量标记,现在行星是否生成星环与大小无关。

(删除了源码注释)

upd 2024.4.3

削薄了行星和星环的外框

yyhs_shihaotian Avatar