initial upload
This commit is contained in:
371
handyman/handyman.cpp
Normal file
371
handyman/handyman.cpp
Normal file
@@ -0,0 +1,371 @@
|
||||
/********************************************************
|
||||
* ██████╗ ██████╗████████╗██╗
|
||||
* ██╔════╝ ██╔════╝╚══██╔══╝██║
|
||||
* ██║ ███╗██║ ██║ ██║
|
||||
* ██║ ██║██║ ██║ ██║
|
||||
* ╚██████╔╝╚██████╗ ██║ ███████╗
|
||||
* ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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()
|
||||
{
|
||||
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;
|
||||
|
||||
std::vector<double> R, G, B;
|
||||
gctl::read_text2vectors(rgb_file, "0,1,2", ' ', '#', 0, R, G, B);
|
||||
int c_size = R.size();
|
||||
|
||||
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, d_name;
|
||||
std::cout << "Name of the .txt input file appended by the index of the data column (<name>+<col>).\n>> ";
|
||||
std::cin >> in_str;
|
||||
|
||||
gctl::parse_string_to_value(in_str, '+', true, f_name, d_name);
|
||||
|
||||
std::vector<double> D, D_ori;
|
||||
gctl::read_text2vectors(f_name, d_name, ' ', '#', 0, D_ori);
|
||||
|
||||
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<double> 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);
|
||||
}
|
Reference in New Issue
Block a user