/*
	984 ：デフォルトの名無しさん：2013/10/16(水) 13:06:20.87
	1 授業単元 プログラミング 
	2 問題 高さh、質量m、初速度vを入力して、物体の軌跡を計算し、グラフを描画(SVGファイルを出力)する。 
	例： 
	高さ30mの位置から質量1.0kgの球を鉛直下向きに4.9m/sで投げ下ろした。 
	
	高さ=30 
	質量=1 
	初速度=4.9 
	グラフをSVGファイルに出力 
	
	3 windows8 
	4期限 10月21日まで 
	誰かお願いします。 
*/

#include <iostream>
#include <fstream>
#include <cmath>

// 出力ファイル
static const char* outFileName = "output.svg";

// 重力加速度
static const double g = 9.8;

// 一秒間あたりに打つ点の数
static const int samplesPerSec = 8;

// 描画幅
static const int graphWidth  = 2000;
static const int graphHeight = 1200;

class CalcPoint {
public:
    double h0;
    double m;
    double v0;

    void inputFromConsole(){
        using std::cout;
        using std::cin;

        cout << "高さ(m)=";     cin >> h0;
        cout << "質量(kg)=";    cin >> m;
        cout << "初速度(m/s)="; cin >> v0;
    }

    // 下向きを正、h0を0とする時のy
    double getY(double t){
        return ((v0 * t) + ((double)1/2)*g*t*t);
    }

    // 落下までの時間
    double getTimeToFall(){
        return ( std::sqrt(v0*v0 + 2*g*h0) - v0 ) / g;
    }
};

class SVGOutput {
private:
    std::ofstream out;
public:
    SVGOutput(const char* filename): out(filename) {}

    void putHeader(){
        out <<
            "<?xml version='1.0' standalone='no'?>\n"
            "<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN'\n"
            " 'http://w...content-available-to-author-only...3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>\n"
            "<svg xmlns='http://w...content-available-to-author-only...3.org/2000/svg' version='1.1'>\n"
            "<svg width='90%' height='90%' x='5%' y='5%'>\n";
    }

    void circleStart() { out << "<g fill='black'>\n"; }

    void circlePut(int x, int y, int r){
        out << "<circle cx='" << x << "' cy='" << y << "' r='" << r << "' />\n";
    }

    void circleEnd(){ out << "</g>\n"; }
    void putFooter(){ out << "</svg>\n</svg>\n"; }
};

// double値 -> int座標 変換
class ToDot {
public:
    double factor;
    ToDot( int dots, double max ){
        factor = dots / std::ceil(max);
    }
    int operator() (double actual){ return factor * actual; }
};

int main(){
    CalcPoint calc;

    // 入力
    calc.inputFromConsole();

    // 変換
    double timeFall = calc.getTimeToFall();
    ToDot toDotX( graphWidth, timeFall);
    ToDot toDotY( graphHeight, calc.h0);

    {
        // SVG出力
        SVGOutput svg(outFileName);

        double ps = (double)1/samplesPerSec;
        int last  = ((double)samplesPerSec) * timeFall;

        int r = 5;

        svg.putHeader();
        svg.circleStart();

        // 座標の計算と出力
        for( int i = 0; i <= last; i++ ){
            double t = ((double)i)*ps;
            svg.circlePut( toDotX(t), toDotY( calc.getY(t) ), r );
        }

        svg.circlePut( toDotX(timeFall), toDotY( calc.getY(timeFall) ), r );

        svg.circleEnd();
        svg.putFooter();
    }

    return 0;
}
