#include <math.h>
#include <iostream>
#include "levelToSpeed.h"

using namespace std;
#define M_PI acos(-1)


class ForestFirePrediction {
public:
    // 构造函数
    ForestFirePrediction(int wind_direction, double wind_level, double slope, double altitude, int cover_type, double fire_size) {
        this->wind_direction = wind_direction;
        this->wind_level = wind_level;
        this->slope = slope;
        this->altitude = altitude;
        this->cover_type = cover_type;
        this->fire_size = fire_size;
    }

    // 计算受阻距离（单位：km）
    double get_distance() {
        double rad_slope = slope * M_PI / 180.0; // 将坡度转化为弧度
        double distance = sin(rad_slope) * altitude / 1000.0; // 计算受阻距离
        return distance;
    }

    // 预测火灾蔓延范围
    void predict_range() {
        double impact_factor;   // 植被类型影响系数
        double correction_coef; // 风速补正系数
        double distance;        // 受阻距离
        double composite_index; // 综合指数

        // 根据植被类型获取影响系数
        switch (cover_type) {
        case 1: // 针叶林
            impact_factor = 0.7;
            break;
        case 2: // 落叶林
            impact_factor = 0.5;
            break;
        case 3: // 灌木林
            impact_factor = 0.4;
            break;
        default:
            cout << "植被类型输入错误！" << endl;
            return;
        }

        // 计算风速补正系数
        int angle = abs(wind_direction - 180); // 计算风向与火灾扩散方向之间的夹角
        if (angle <= 45 || angle >= 315) {     // 如果夹角较小，则不需要进行风速补正
            correction_coef = 1;
        }
        else {
            correction_coef = 0.65 + 0.35 * cos((angle - 45) * M_PI / 270.0); // 使用公式计算风速补正系数
        }

        // 计算受阻距离
        distance = get_distance();

        // 计算综合指数
        composite_index = correction_coef * (1 + distance) * impact_factor;

        // 计算火灾蔓延半径
        double radius = sqrt(fire_size * 1000000 * composite_index) / M_PI;
        double range = radius * pow(10, 1.5 * levelToSpeed(wind_level) / 30.0);

        // 输出预测结果
        cout << "火灾蔓延范围预测结果：" << endl;
        cout << "火源最可能在" << radius << "米范围内发生。" << endl;
        cout << "在风速为 " << wind_level << "级风的情况下，火源最可能的蔓延范围为 " << range << " 米。" << endl;
    }

    // 预测火灾蔓延速度
    void predict_speed(int level) {
        double slope_factor; // 坡度影响因子
        double speed_factor; // 风速影响因子
        double size_factor;  // 火源面积影响因子

        // 计算坡度影响因子
        if (slope > 0) {
            slope_factor = pow(3.33, sqrt(slope));
        }
        else {
            slope_factor = 1;
        }

        // 计算风速影响因子
        double wind_speed = levelToSpeed(wind_level);
        speed_factor = 5.15 * pow(wind_speed, 0.39);

        // 计算火源面积影响因子
        size_factor = pow(fire_size, 0.77);

        // 计算火灾蔓延速度
        double speed = 0.348 * sqrt(size_factor * slope_factor * speed_factor);

        // 输出预测结果
        cout << "火灾蔓延速度预测结果：" << endl;
        cout << "火灾蔓延速度可能为" << speed << "km/h。" << endl;
    }

private:
    int wind_direction; // 风向（单位：度）
    double wind_level;  // 风力等级
    double slope;       // 坡度（单位：度）
    double altitude;    // 海拔高度（单位：m）
    int cover_type;     // 植被类型（1：针叶林；2：落叶林；3：灌木林）
    double fire_size;   // 火源面积（单位：平方米）
};

int main() {
    // 读取参数
    int wind_direction;
    int wind_level;
    double slope;
    double altitude;
    int cover_type;
    double fire_size;
    cout << "请输入风向（0-360度）：" << endl;
    cin >> wind_direction;
    cout << "请输入风力等级（级）：" << endl;
    cin >> wind_level;
    cout << "请输入坡度（度）：" << endl;
    cin >> slope;
    cout << "请输入海拔高度（m）：" << endl;
    cin >> altitude;
    cout << "请输入植被类型（1：针叶林；2：落叶林；3：灌木林）：" << endl;
    cin >> cover_type;
    cout << "请输入火源面积（m^2）：" << endl;
    cin >> fire_size;

    // 预测火灾蔓延范围和速度
    ForestFirePrediction ffp(wind_direction, wind_level, slope, altitude, cover_type, fire_size);
    ffp.predict_range();
    ffp.predict_speed(wind_level);

    return 0;
}