/******************************************************** * ██████╗ ██████╗████████╗██╗ * ██╔════╝ ██╔════╝╚══██╔══╝██║ * ██║ ███╗██║ ██║ ██║ * ██║ ██║██║ ██║ ██║ * ╚██████╔╝╚██████╗ ██║ ███████╗ * ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝ * Geophysical Computational Tools & Library (GCTL) * * Copyright (c) 2022 Yi Zhang (yizhang-geo@zju.edu.cn) * * GCTL is distributed under a dual licensing scheme. You can redistribute * it and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either version 2 * of the License, or (at your option) any later version. You should have * received a copy of the GNU Lesser General Public License along with this * program. If not, see . * * If the terms and conditions of the LGPL v.2. would prevent you from using * the GCTL, please consider the option to obtain a commercial license for a * fee. These licenses are offered by the GCTL's original author. As a rule, * licenses are provided "as-is", unlimited in time for a one time fee. Please * send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget * to include some description of your company and the realm of its activities. * Also add information on how to contact you by electronic and paper mail. ******************************************************/ #include "gctl/core.h" #include "gctl/geometry.h" #include "gctl/io.h" #include "gctl/utility.h" class HandyMan { public: HandyMan(); virtual ~HandyMan(); void Routine(); // Caller of all sub-routines. void SR_CalPlaneCoeff(); // Galculate 3D planes' coefficents. void SR_RGB2CPT(); // Convert RGB series to color palette tables (.cpt) file. void SR_MgNumber(); // Calculate the magnesium number (Mg#). void SR_Sequent(); // Output sequent arrays in column formats. void SR_GeoAngle(); // Calculate the geo-centric angle of two points on the sphere. }; HandyMan::HandyMan(){} HandyMan::~HandyMan(){} void HandyMan::Routine() { int c; std::cout << "What do you want to do?\n\ (0) Quit.\n\ (1) Calculate coefficients of a 3-D plane.\n\ (2) Convert RGB series to .cpt file.\n\ (3) Calculate the magnesium number (Mg#).\n\ (4) Output sequent arrays in column formats.\n\ (5) Calculate the geo-centric angle of two points on the sphere.\n"; std::cout << ">> "; std::cin >> c; switch (c) { case 1: SR_CalPlaneCoeff(); break; case 2: SR_RGB2CPT(); break; case 3: SR_MgNumber(); break; case 4: SR_Sequent(); break; case 5: SR_GeoAngle(); break; default: throw std::runtime_error("Invalid choice. From gctl::handyman."); break; } return; } void HandyMan::SR_CalPlaneCoeff() { int c; std::cout << "Known points?\n\ (1) Three points in the Cartesian coordinates.\n\ (2) Two points on a spherical surface.\n"; std::cout << ">> "; std::cin >> c; double A, B, C, D; if (c == 1) { std::cout << "Input x, y, and z coordinates of the points.\n"; gctl::point3dc c[3]; for (size_t i = 0; i < 3; i++) { std::cout << ">> "; std::cin >> c[i]; } gctl::geometry3d::get_plane_coeff(c[0].x, c[1].x, c[2].x, c[0].y, c[1].y, c[2].y, c[0].z, c[1].z, c[2].z, A, B, C, D); } else if (c == 2) { std::cout << "Input radius, longitude, and latitude coordinates of the points.\n"; gctl::point3ds c[2]; for (size_t i = 0; i < 2; i++) { std::cout << ">> "; std::cin >> c[i]; } gctl::geometry3d::get_plane_coeff(c[0], c[1], A, B, C, D); } else throw std::runtime_error("Invalid choice. From gctl::handyman."); if (A != 0.0) { B /= A; C /= A; D /= A; A = 1.0; } else if (B != 0.0) { A /= B; C /= B; D /= B; B = 1.0; } else if (C != 0.0) { A /= C; B /= C; D /= C; C = 1.0; } else throw std::runtime_error("Invalid plane's coefficients. From gctl::handyman."); std::cout << "Plane's equation:\n"; std::cout << std::fixed << std::setprecision(3) << A << "*x + " << B << "*y + " << C << "*z + " << D << " = 0\n"; return; } void HandyMan::SR_RGB2CPT() { gctl::dsv_io tc; std::string rgb_file, cpt_file; std::cout << "Name of the RGB series file (Each line of file contains a R G B group).\n>> "; std::cin >> rgb_file; std::cout << "Name of the output .cpt file.\n>> "; std::cin >> cpt_file; tc.load_text(rgb_file); int c_size = tc.row_number(); gctl::array R, G, B; tc.get_column(R, 0); tc.get_column(G, 1); tc.get_column(B, 2); int i_type; std::cout << "Interpolation type of the interval values.\n(1) linear\n(2) data\n>> "; std::cin >> i_type; int sym_zero = 0; std::cout << "symmetric w.r.t. zero value (1 for yes and 0 for no).\n>> "; std::cin >> sym_zero; std::ofstream ofile; gctl::open_outfile(ofile, cpt_file, ".cpt"); double dn_val, up_val; double mini, maxi; if (i_type == 1) { if (sym_zero) { std::cout << "Maximal absolute value of the output .cpt file.\n>> "; std::cin >> maxi; mini = -1.0*maxi; } else { std::cout << "Minimal and maximal values of the output .cpt file.\n>> "; std::cin >> mini >> maxi; } ofile << "# This file is generated by the tool 'handyman' of the GCTL package.\n"; ofile << "# Input file: " << rgb_file << "\n"; ofile << "# Interpolation type: linear\n"; ofile << "# symmetric w.r.t. zero value: " << sym_zero << "\n"; for (size_t i = 0; i < c_size - 1; i++) { dn_val = (maxi - mini)*i/(c_size - 1.0) + mini; up_val = (maxi - mini)*(i + 1.0)/(c_size - 1.0) + mini; ofile << dn_val << " " << R[i] << "/" << G[i] << "/" << B[i] << " "; ofile << up_val << " " << R[i+1] << "/" << G[i+1] << "/" << B[i+1] << " L\n"; } ofile << "B black\nF white\nN 128\n"; } else if (i_type == 2) { std::string in_str, f_name; std::cout << "Name of the .txt input file.\n>> "; std::cin >> in_str; gctl::parse_string_to_value(in_str, '+', true, f_name); tc.clear(); tc.load_text(f_name); gctl::array D_ori; tc.get_column(D_ori, 0); std::vector D; D.reserve(D_ori.size()); for (size_t i = 0; i < D_ori.size(); i++) { if (!std::isnan(D_ori[i])) { D.push_back(D_ori[i]); } } int d_size = D.size(); int box_size = ceil(d_size/(c_size - 1.0)); // 排序 std::sort(D.begin(), D.end()); mini = D.front(); maxi = D.back(); if (sym_zero) { if (abs(maxi) > abs(mini)) { mini = -1.0*maxi; D.insert(D.begin(), mini); } else if (abs(maxi) < abs(mini)) { maxi = -1.0*mini; D.push_back(maxi); } d_size = D.size(); box_size = ceil(d_size/(c_size - 1.0)); } ofile << "# This file is generated by the tool 'handyman' of the GCTL package.\n"; ofile << "# Input file: " << rgb_file << "\n"; ofile << "# Interpolation type: data\n"; ofile << "# symmetric w.r.t. zero value: " << sym_zero << "\n"; ofile << "# data name: " << in_str << "\n"; int d_id; dn_val = mini; for (size_t i = 0; i < c_size - 1; i++) { d_id = box_size*(i+1) - 1; if (d_id >= d_size) d_id = d_size - 1; up_val = D[d_id]; ofile << dn_val << " " << R[i] << "/" << G[i] << "/" << B[i] << " "; ofile << up_val << " " << R[i+1] << "/" << G[i+1] << "/" << B[i+1] << " L\n"; dn_val = up_val; } ofile << "B black\nF white\nN 128\n"; } else throw std::runtime_error("Invalid choice. From gctl::handyman."); ofile.close(); return; } void HandyMan::SR_MgNumber() { double feo, fe2o3, mgo; std::cout << "Weight precents (wt%) of MgO (> 0), FeO (>= 0) and Fe2O3 (>= 0).\n>> "; std::cin >> mgo >> feo >> fe2o3; if (mgo <= 0.0 || feo < 0.0 || fe2o3 < 0.0) { throw std::runtime_error("Invalid inputs."); } feo += 0.8998*fe2o3; std::cout << "Mg# = " << (mgo/40.3044)/(mgo/40.3044 + feo/71.8444) << "\n"; return; } void HandyMan::SR_Sequent() { double st, ed, inter; std::vector starts, ends, intervals; std::cout << "Input column's start, end and interval values (one group per line, enter empty line to finish).\n"; std::string line; std::getline(std::cin, line); while (std::getline(std::cin, line)) { if (line.empty()) break; else { gctl::parse_string_to_value(line, ' ', true, st, ed, inter); starts.push_back(st); ends.push_back(ed); intervals.push_back(inter); } } int l = 0; bool valid; do { valid = false; for (size_t i = 0; i < starts.size(); i++) { st = starts[i] + l*intervals[i]; if (starts[i] != ends[i] && st <= ends[i]) { std::cout << st << " "; valid = true; } else if (starts[i] == ends[i] && valid == true) { std::cout << st << " "; } } std::cout << "\n"; l++; } while (valid); return; } void HandyMan::SR_GeoAngle() { std::cout << "Input longitude, and latitude coordinates of the two points.\n"; gctl::point3ds c[2]; for (size_t i = 0; i < 2; i++) { std::cout << ">> "; c[i].rad = 1.0; std::cin >> c[i].lon >> c[i].lat; } std::cout << "The geo-centric angle is: " << gctl::geometry3d::angle(c[0].s2c(), c[1].s2c())*180.0/M_PI << " deg.\n"; return; } int main(int argc, char const *argv[]) try { HandyMan hm; gctl::display_logo(); bool quit = false; while (!quit) { hm.Routine(); std::cout << "Quit? (1 for yes and 0 for no)\n"; std::cout << ">> "; std::cin >> quit; } return 0; } catch (std::exception &e) { GCTL_ShowWhatError(e.what(), GCTL_ERROR_ERROR, 0, 0, 0); }