SGU 283. Mechanics

Link To The Problem


Solution : 先判斷是否碰撞、然後模擬。


Code:

// SGU 283 Mechanics
// Solution : 模擬
//

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>

using namespace std;
#define FOR(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define DOR(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)

#define oo 1e6
#define eps 1e-8
#define nMax 1010

//{ 
#define pb push_back
#define dbg(x) cerr << __LINE__ << ": " << #x << " = " << x << endl

#define F first
#define S second

#define bug puts("OOOOh.....");
#define zero(x) (((x)>0?(x):-(x))<eps)

#define LL long long
#define DB double 

#define sf scanf
#define pf printf
#define rep(i,n) for(int (i)=0;(i)<(n);(i)++)

double const pi = acos(-1.0);
double const inf = 1e9;
double inline sqr(double x) { return x*x; }

int dcmp(double x){
    if(fabs(x)<=eps) return 0;
    return x>0?1:-1;
}
//}

// Describe of the 2_K Geomtry
// First Part : Point and Line
// Second Part Cicle
// Third Part Polygan

// First Part:
// ****************************** Point and Line *******************************\\
//  {  

class point {
public:
    double x,y;
    point (double x=0,double y=0):x(x),y(y) {}
    void make(double _x,double _y) {x=_x;y=_y;}
    void read() { scanf("%lf%lf",&x,&y); }
    void out() { printf("%.3lf %.3lf\n",x,y);}
    double len() { return sqrt(x*x+y*y); }

    point friend operator - (point const& u,point const& v) { return point(u.x-v.x,u.y-v.y); }
    point friend operator + (point const& u,point const& v) { return point(u.x+v.x,u.y+v.y); }
    double friend operator * (point const& u,point const& v){ return u.x*v.y-u.y*v.x; }
    double friend operator ^ (point const& u,point const& v) { return u.x*v.x+u.y*v.y; }
    point friend operator * (point const& u,double const& k) { return point(u.x*k,u.y*k); }
	point friend operator / (point const& u,double const& k) { return point(u.x/k,u.y/k); }
	point friend operator * (double const& k,point const& u) { return point(k*u.x,k*u.y); }
	
	friend bool operator < (point const& u,point const& v){
		if(dcmp(v.x-u.x)==0) return dcmp(u.y-v.y)<0;
		return dcmp(u.x-v.x)<0;
	}
	friend bool operator != (point const& u,point const& v){
		return dcmp(u.x-v.x) || dcmp(u.y-v.y);
	}

	point rotate(double s) {
		return point(x*cos(s) - y*sin(s),\
					x*sin(s) + y*cos(s));
	}
};
typedef point Vector;
typedef class line{
public:
    point a,b;
    line() {}
    line (point a,point b):a(a),b(b){}
    void make(point u,point v) {a=u;b=v;}
    void read() { a.read(),b.read(); }
}segment;

double det(point u,point v) {
	return u.x*v.y - u.y*v.x;
}
double dot(point u,point v) {
	return u.x*v.x + u.y*v.y;
}

// Weather P is On the Segment (uv) 
int dot_on_seg(point p,point u,point v){
	return dcmp(det(p-u,v-p))==0 && dcmp(dot(p-u,p-v)) <= 0; // '>=' means P is u or v
}
// The distance from point p to line l
double PToLine(point p,line l) {
	return fabs((p-l.a)*(l.a-l.b))/(l.a-l.b).len();
}
// The ProJect Of Point(p) To Line(l)
point PointProjectLine(point p,line l) {
	double t = dot(l.b-l.a,p-l.a)/dot(l.b-l.a,l.b-l.a);
	return l.a + (l.b-l.a)*t;
}
// Weather line u parallel line v
int parallel(line u,line v) {
	return dcmp(det(u.a-u.b,v.a-v.b))==0;
}
// The Intersection Point Of Line u and Line v
point intersection(line u,line v) {
	point ret = u.a;
	double t = det(u.a-v.a,v.a-v.b)/det(u.a-u.b,v.a-v.b);
	return ret + (u.b-u.a)*t;
}

//}
// ****************************** First Part end ********************************\\

// Second Part:
// ********************************* Circle *************************************\\
// {

struct circle {
	point O;
	double r;
	circle() {};
	circle(point O,double r):O(O),r(r){};
};


//}
// ****************************** Second Part End *******************************\\

// Third Part :
// ********************************* Polygan *************************************\\
// {


int ConvexHull(vector<point>& p){
	int n=p.size();
	int m=0;
	sort(p.begin(),p.end());
	vector<point> q;
	q.resize(2*n+5);
	rep(i,n) {
		while(m>1 && dcmp((q[m-1]-q[m-2])*(p[i]-q[m-2])) <= 0) m--;
		q[m++] = p[i];
	}
	int k = m;
	for(int i=n-2;i>=0;i--) {
		while(m>k && dcmp((q[m-1]-q[m-2])*(p[i]-q[m-2])) <= 0) m--;
		q[m++] = p[i];
	}
	q.resize(m) ;
	if(m>1) q.resize(m-1);
	// p = q;    // 是否修改原來的多邊形
	return q.size();
}
// 三角形重心
point Center(point a,point b,point c){
	return (a+b+c)/3.0;
}
// Centroid of Polygan
point Centroid(vector<point> p){
	point O(0,0),ret(0,0);
	int n = p.size();
	p.pb(p[0]);
	double area = 0.0;
	rep(i,n) {
		ret = ret + Center(O,p[i],p[i+1])*dot(p[i]-O,p[i+1]-O);
		area += dot(p[i]-O,p[i+1]-O);
	}
	if(dcmp(area)==0) {
		pf("There maybe something wrong\n");
		return p[0];
	}
	return ret / area;
}


struct Polygan{
	vector<point> g;
	Polygan() {};
	Polygan(vector<point> g):g(g){};
	Polygan(point p[],int n) {g.clear();rep(i,n) g.pb(p[i]); };
	int convex() { return ConvexHull(g); }
	point center() { return Centroid(g);  } // 多邊形的重心
};

//}
// ******************************* Third Part End ********************************\\





// Solution Part:
//
void Rush(point o[],point v[],double t) {
	o[0]=o[0]+v[0]*t;
	o[1]=o[1]+v[1]*t;
	rep(i,2) {
		pf("%.10lf %10lf %10lf %10lf\n",o[i].x,o[i].y,v[i].x,v[i].y);
	}
}

point o[2],v[2];
double r[2],m[2];
double t;
int calculate(double a,double b,double c,double &T) {
	if(dcmp(a)==0) {
		if(dcmp(b)==0) return 0;
		T = -c/b;
		if(dcmp(T)<=0 || dcmp(T*10-t)>=0) return 0;
		return 1;
	}

	double delta = b*b-4*a*c;
	if(dcmp(delta) < 0) return 0;
	delta = sqrt(delta);
	T = inf;
	double x = (-b+delta)/2.0/a;
	if(dcmp(x) > 0) T = x;
	x = (-b-delta)/2.0/a;
	if(dcmp(x) > 0) T = min(T,x);
	if(dcmp(T)<=0 || dcmp(T-t)>=0) return 0;
	return 1;
}

typedef point P;

void work() {
	double a=sqr((v[0]-v[1]).len());
	double b = (o[1]-o[0])^(v[1]-v[0]);b*=2;
	double c = sqr((o[1]-o[0]).len())-sqr(r[0]+r[1]);
	double T;
	if( !calculate(a,b,c,T) ) { Rush(o,v,t);return ;} 
	//T *= 10;
	dbg(T);
	o[0] = o[0]+v[0]*T;
	o[1] = o[1]+v[1]*T;
	t-=T;

	point vx = (o[1]-o[0]);
	vx = vx/vx.len();
	point vy = vx.rotate(pi/2.0);

	point vax = (v[0]^vx)*vx;
	point vay = (v[0]^vy)*vy;
	point vbx = (v[1]^vx)*vx;
	point vby = (v[1]^vy)*vy;

	double lena = vax.len(),
		   lenb = vbx.len();

	if(dcmp(vax^vx)<0) lena = -lena;
	if(dcmp(vbx^vx)<0) lenb = -lenb;

	dbg(lena);
	dbg(lenb);

	double dx0 = 2.0*m[1]/(m[0]+m[1])*lenb + (m[0]-m[1])/(m[0]+m[1])*lena,
		   dx1 = 2.0*m[0]/(m[0]+m[1])*lena + (m[1]-m[0])/(m[0]+m[1])*lenb;
	
	vax = vx * dx0;
	vbx = vx * dx1;

	v[0] = vax + vay;
	v[1] = vbx + vby;

	Rush(o,v,t);
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
#endif
	
	rep(i,2) { o[i].read(),v[i].read(),sf("%lf%lf",&r[i],&m[i]); }
	sf("%lf",&t);

	work() ;

	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章