sgu283:Mechanics(计算几何)

题目大意:

给你平面上两个圆(x1,y1),(x2,y2),以及它们的质量m1,m2和速度v1,v2。

碰撞过程中不考虑能量损失。

求出在时刻t的两圆坐标和速度。

分析:

首先我们很容易解个方程求出碰撞时间。问题就是如何计算碰撞后的速度。

设碰撞时两圆圆心为A,B,将v1,v2根据AB正交分解为垂直的law1,law2,和共线的x,y,即v1=law1+x,v2=law2+y。那么根据动量守恒和能量守恒,碰撞后只有x,y会改变,我们可以列出两个方程:

{m1x+m2y=m1x′+m2y′m1v21+m2v22=m1(law21+x′2)+m2(law22+y′2)

解出来就是x′=((m1m2?1)x+2y)/(1+m1m2),y′=x+x′?y。

然后就没有然后了...

AC code:

#include <cstdio>
#include <cmath>
#include <algorithm>
#define sqr(x) ((x)*(x))
typedef double DB;
using namespace std;

const DB eps = 1e-9;

struct pot
{
    DB x, y;
    pot() {x = y = 0;}
    pot(DB _x, DB _y):x(_x),y(_y){}
    void read() {scanf("%lf%lf", &x, &y);}
    void print() {printf("%.3lf %.3lf", x, y);}

    friend pot operator + (const pot &a, const pot &b) {return pot(a.x+b.x, a.y+b.y);}
    friend pot operator - (const pot &a, const pot &b) {return pot(a.x-b.x, a.y-b.y);}
    friend pot operator * (const pot &a, DB k) {return pot(a.x*k, a.y*k);}
    friend pot operator / (const pot &a, DB k) {return pot(a.x/k, a.y/k);}
    friend DB operator * (const pot &a, const pot &b) {return a.x*b.x+a.y*b.y;}
    friend DB operator ^ (const pot &a, const pot &b) {return a.x*b.y-a.y*b.x;}
    DB size() {return sqrt(sqr(x)+sqr(y));}

}p1, v1, p2, v2;
DB r1, r2, m1, m2, t;
DB bump_t;

int sign(DB x)
{
    if(x < -eps) return -1;
    else return x > eps;
}

bool bump()
{
    DB a, b, c, d, e;
    DB A, B, C;
    a = p1.x-p2.x, b = v1.x-v2.x;
    c = p1.y-p2.y, d = v1.y-v2.y;e = r1+r2;
    A = sqr(b)+sqr(d), B = 2*(a*b+c*d), C = sqr(a)+sqr(c)-sqr(e);
    if(sign(A) == 0)
    {
        if(sign(-C/B) < 0) return false;
        else
        {
            bump_t = -C/B;
            return true;
        }
    }
    else if(sign(sqr(B)-4*A*C) <= 0) return false;
    else
    {
        DB u, v;
        u = -B/(2*A), v = sqrt(sqr(B)-4*A*C)/(2*A);
        if(sign(u+v) < 0) return false;
        else if(sign(u-v) < 0) bump_t = u+v;
        else bump_t = u-v;
        return true;
    }
}

void solve2(DB t)
{
    p1 = p1+v1*t;
    p2 = p2+v2*t;
    p1.print(), putchar(‘ ‘), v1.print(), puts("");
    p2.print(), putchar(‘ ‘), v2.print(), puts("");
}

void solve1(DB t)
{
    pot A, B, par, x, y, _x, _y;
    pot law1, law2, _v1, _v2;
    A = p1+v1*bump_t, B = p2+v2*bump_t, par = B-A;
    x = par*(v1*par/sqr(par.size())), y = par*(v2*par/sqr(par.size()));
    law1 = v1-x, law2 = v2-y;
    _x = (x*(m1/m2-1)+y*2)/(1+m1/m2), _y = x+_x-y;
    _v1 = law1+_x, _v2 = law2+_y;
    p1 = A, p2 = B, v1 = _v1, v2 = _v2;
    solve2(t-bump_t);
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif

    p1.read(), v1.read(), scanf("%lf%lf", &r1, &m1);
    p2.read(), v2.read(), scanf("%lf%lf", &r2, &m2);
    scanf("%lf", &t);
    if(bump())
    {
        if(sign(t-bump_t) > 0)
            solve1(t);
        else solve2(t);
    }
    else solve2(t);

    #ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
    #endif
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-04 02:43:56

sgu283:Mechanics(计算几何)的相关文章

!HDU 4380 三角屋内有奇数个宝藏的三角形有多少个-计算几何-(向量叉乘&amp;线段与点的关系&amp;暴力枚举)

题意:小明要买三座房子,这三个房子构成一个三角形,已知n个房子的坐标,任何三个房子都不在一条直线上,又已知有m个宝藏的坐标,问房子构成的三角形内有奇数个宝藏的三角形有多少个.数据范围:n(3~100),m(1~1000) 分析: 简单的计算几何.记住这题的做法. 三角形内的点的个数=上面的线段下面的点的个数 -- 下面两条线段下面的点的个数(或者下面一条线段减上面两条线段,看具体位置情况,所以直接取绝对值就好) n个点有n(n-1)/2条线段,不超过1W,枚举每条线段,再枚举每个宝藏的坐标(10

Opengl绘制计算几何库CGAL三角剖分结果的Demo

Ubuntu下改编了一个用CGAL计算输入点的三角剖分,并用OpenGL显示结果的C++程序. 该Demo可作为一个计算几何及绘图的框架. 代码如下: //编译命令:g++ spatial_sort.cpp -lglut -lGL -lGLU -lCGAL -lCGAL_Core -lgmp #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>   #include <CGAL/Triangulation_eucl

Ubuntu下安装cgal4.5.2计算几何库

摘要:cgal是一个开源的计算几何库, 博文记录了其编译.安装和使用方法. 1 库下载 站点:http://www.cgal.org/ 下载:https://gforge.inria.fr/frs/download.php/file/34514/CGAL-4.5.2.zip 2 解压缩.编译与安装 shell下进入解压文件夹 1)库配置文件生成命令: cmake . 提示缺少gmp和mpfr库 安装缺少的库: sudo apt-get install libgmp-dev libmpfr-dev

UVA 11178 Morley&#39;s Theorem 计算几何

计算几何: 最基本的计算几何,差积  旋转 Morley's Theorem Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Submit Status Description Problem D Morley's Theorem Input: Standard Input Output: Standard Output Morley's theorem states that that the line

计算几何导论

计算几何 计算几何是一门兴起于二十世纪七十年代末的计算机科学的一个分支,主要研究解决几何问题的算法.在现代工程和数学领域,计算几何在图形学.机器人技术.超大规模集成电路设计和统计等诸多领域有着十分重要的应用. 计算几何问题的输入一般是关于一组几何对象的描述,如一组点.一组线段,或者一个多边形的按逆时针顺序排列的一组顶点.输出常常是对有关这些对象的问题的回答,如是否直线相交,是否为一个新的几何对象,如顶点集合的凸包. 本文将介绍一些平面上的计算几何算法.在这些算法中,每个输入对象都是一组点{p1,

HDU 6206 Apple ( 高精度 &amp;&amp; 计算几何 &amp;&amp; 三点构圆求圆心半径 )

题意 : 给出四个点,问你第四个点是否在前三个点构成的圆内,若在圆外输出"Accepted",否则输出"Rejected",题目保证前三个点不在一条直线上. 分析 : 简单的计算几何问题,如果能够知道圆心和半径(Radius)以及第四个点和圆心的距离(Distance),我们就能够判断第四个点是否在圆外,例如Distance > Radius则在圆外.三点构圆 的圆心和半径是能够推导出公式的 (参考==> http://blog.csdn.net/dea

【您有新的未分配天赋点】计算几何:从被纸笔支配的恐怖到达被代码支配的恐怖

开坑时间:2017/8/5 21:25 今天呢$lgl$神犇终于打开了坑害了无数英雄好汉的新陷阱的盖子新世界的大门:计算几何.尽管再不愿意但该来的还是要来.于是我就这么踏上了这条贼船--(缓更,勿催) 本文将对现阶段所需的四项知识做出一些主观的感性分析,希望大家能够就此感性理解一下. 一.凸包 凸包,顾名思义就是把给定点围在里面的最小凸多边形.这个东西一般采用扫描方法进行处理,时间瓶颈为排序的$O(nlogn)$. 链接:http://www.cnblogs.com/Loser-of-Life/

计算几何中的精度问题

转自:北岛知寒 计算几何头疼的地方一般在于代码量大和精度问题,代码量问题只要平时注意积累模板一般就不成问题了.精度问题则不好说,有时候一个精度问题就可能成为一道题的瓶颈,简直"画龙点睛".这些年的题目基本是朝着越来越不卡精度的方向发展了,但是也不乏一些奇怪的题,另外有些常识不管题目卡不卡,都是应该知道的.今天我就开膛回顾下见过且还有印象的精度问题,由于本人见识和记忆均有限,望各位大神瞄过后不吝补充.另外,为了弥补我匮乏的文思,我可能乱扯些不太相关或者尽人皆知的东西凑数.那么,现在开始.

[BZOJ 1027][JSOI2007]合金(计算几何+Floyd最小环)

Description 某公司加工一种由铁.铝.锡组成的合金.他们的工作很简单.首先进口一些铁铝锡合金原材料,不同种类的原材料中铁铝锡的比重不同.然后,将每种原材料取出一定量,经过融解.混合,得到新的合金.新的合金的铁铝锡比重为用户所需要的比重. 现在,用户给出了n种他们需要的合金,以及每种合金中铁铝锡的比重.公司希望能够订购最少种类的原材料,并且使用这些原材料可以加工出用户需要的所有种类的合金. Solution 今天考试T3的70分算法似乎是这道原题(然而我没做过QwQ) 思路值得学习一下(