/*
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;
}