gctl_toolkits/fractopo/fractopo.cpp
2024-09-10 20:25:18 +08:00

195 lines
7.7 KiB
C++

/********************************************************
* ██████╗ ██████╗████████╗██╗
* ██╔════╝ ██╔════╝╚══██╔══╝██║
* ██║ ███╗██║ ██║ ██║
* ██║ ██║██║ ██║ ██║
* ╚██████╔╝╚██████╗ ██║ ███████╗
* ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
* 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 "FractalTopo.h"
int main(int argc, char* argv[]) try
{
const char* pro_name = "fractopo";
const char* pro_info = "1.5 - Fractal topography generater. \
This program is a toolkit of the GCTL package. The GCTL comes with ABSOLUTE NO WARRANTY. \
Please see instructions or contact the author for more information.";
const char* p_str = "Roughness and maximal changing range of the output topography data. \
Small roughness generates topography with more high frequent changes. Big roughness results \
in long wavelength terrain undulations. The defaults are 1.2/600.";
const char* r_str = "Range of the output topography data. The program can output topography data \
under a rectangular grid or at random positions. The defaults are 0/1000/0/1000/10/10.";
const char* c_str = "Altitudes at the four corner positions. 'dl' represents 'down left' and \
'ur' is 'up right'. The defaults are 0/0/0/0.";
const char* g_str = "Filter parameters. 'cx/cy' are center coordinates of the filter. \
'sigma' is radius of the shorter axis of the 0.5 filter amplitude. \
'ang' is angle between the shorter axis of the filter and the x-axis. \
'lenx/leny' represents length factor the long and short axises of the filter. \
usually we take lenx = 1 to ensure the radius of 0.5 filter amplitude equals \
the distance given by sigma in the direction of the shorter axis of the filter. \
a bigger 'len' value indicates faster changing rate in the corresponding \
direction. For instance 1/0.5 yields an oval which flattening equals 2.0. \
'magnify' is filter amplitude at the center. 'rho' is changing rate of the arctan function. \
This argument is optional if the filer type is set to 'exp'.";
const char* t_str = "Choose weighting function, input 'pow' for power function (default) and 'atan' for arctg function.";
double Para[2] = {1.2, 600};
double Range[6] = {0, 1000, 0, 1000, 10, 10};
double Topo[4] = {0, 0, 0, 0};
double Gauss[8] = {1e+30, 1e+30, 1e+30, 1e+30, 1e+30, 1e+30, 1e+30, 1e+30};
char flType[1024] = "atan";
bool bilinear = false;
// option format
// char* info, char* format, bool manda
static struct gctl::option_info long_opts_help[] =
{
{p_str, "<roughness>/<range>", false},
{r_str, "<xmin>/<xmax>/<ymin>/<ymax>/[<dx>/<dy>|<point-num>]", false},
{c_str, "<dl>/<ul>/<ur>/<dr>", false},
{g_str, "<cx>/<cy>/<sigma>/<ang>/<lenx>/<leny>/<magnify>[/rho]", false},
{t_str, "<type>", false},
{"Instead of a random topography, create a bilinear topography which four corners are define by the -c option.", 0, false},
{"Show help information.", 0, false},
{0, 0, 0}
};
static struct option long_opts[] =
{
{"parameter", required_argument, NULL, 'p'},
{"range", required_argument, NULL, 'r'},
{"corner-value", required_argument, NULL, 'c'},
{"filter-para", required_argument, NULL, 'f'},
{"filter-type", required_argument, NULL, 't'},
{"bilinear", no_argument, NULL, 'b'},
{"help", no_argument, NULL, 'h'},
{0, 0, 0, 0}
};
int curr;
while(1)
{
int optIndex = 0;
curr = getopt_long(argc, argv, "hbp:r:c:f:t:", long_opts, &optIndex);
if (curr == -1) break;
switch (curr)
{
case 'h': //显示帮助信息
gctl::display_logo(std::clog);
gctl::getopt_long_help(long_opts, long_opts_help, pro_name, pro_info, std::clog, " > <outfile>");
return 0;
case 'b':
bilinear = true;
break;
case 'p':
if (2 != sscanf(optarg, "%lf/%lf", &Para[0],&Para[1])) //格式化读入参数
{
GCTL_ShowWhatError("Bad syntax:", GCTL_ERROR_ERROR, optarg, 0, 0);
gctl::getopt_long_option_info('p', long_opts, long_opts_help);
return 0;
}
break;
case 'r':
if (6 != sscanf(optarg, "%lf/%lf/%lf/%lf/%lf/%lf", &Range[0], &Range[1], &Range[2],
&Range[3], &Range[4], &Range[5]))
{
if (5 != sscanf(optarg, "%lf/%lf/%lf/%lf/%lf", &Range[0], &Range[1], &Range[2],
&Range[3], &Range[4]))
{
GCTL_ShowWhatError("Bad syntax:", GCTL_ERROR_ERROR, optarg, 0, 0);
gctl::getopt_long_option_info('r', long_opts, long_opts_help);
return 0;
}
else
{
//确定只有5个范围参数 将最后一个range参数设置为1e+30
Range[5] = 1e+30;
if (Range[0] > Range[1] || Range[2] > Range[3] || Range[4] <= 0)
{
GCTL_ShowWhatError("Bad syntax:", GCTL_ERROR_ERROR, optarg, 0, 0);
gctl::getopt_long_option_info('r', long_opts, long_opts_help);
return 0;
}
}
}
else
{
if (Range[0]>Range[1] || (Range[0]+2*Range[4]) > Range[1] ||
Range[2]>Range[3] || (Range[2]+2*Range[5]) > Range[3])
{
GCTL_ShowWhatError("Bad syntax:", GCTL_ERROR_ERROR, optarg, 0, 0);
gctl::getopt_long_option_info('r', long_opts, long_opts_help);
return 0;
}
}
break;
case 'c':
if (4 != sscanf(optarg,"%lf/%lf/%lf/%lf",&Topo[0],&Topo[1],&Topo[2],&Topo[3]))
{
GCTL_ShowWhatError("Bad syntax:", GCTL_ERROR_ERROR, optarg, 0, 0);
gctl::getopt_long_option_info('c', long_opts, long_opts_help);
return 0;
}
break;
case 'f':
if (8 != sscanf(optarg,"%lf/%lf/%lf/%lf/%lf/%lf/%lf/%lf", &Gauss[0], &Gauss[1],
&Gauss[2], &Gauss[3], &Gauss[4], &Gauss[5], &Gauss[6], &Gauss[7]))
{
if (7 != sscanf(optarg,"%lf/%lf/%lf/%lf/%lf/%lf/%lf", &Gauss[0], &Gauss[1],
&Gauss[2], &Gauss[3], &Gauss[4], &Gauss[5], &Gauss[6]))
{
GCTL_ShowWhatError("Bad syntax:", GCTL_ERROR_ERROR, optarg, 0, 0);
gctl::getopt_long_option_info('f', long_opts, long_opts_help);
return 0;
}
}
break;
case 't':
if (1 != sscanf(optarg,"%s",flType)) //格式化读入参数
{
GCTL_ShowWhatError("Bad syntax:", GCTL_ERROR_ERROR, optarg, 0, 0);
gctl::getopt_long_option_info('t', long_opts, long_opts_help);
return 0;
}
break;
case '?':
gctl::getopt_long_help(long_opts, long_opts_help, pro_name, " - Unknown options. Please see the help information below.");
return 0;
default:
abort();
}
}
FracTopo FT;
FT.run(Range,Topo,Para,Gauss,flType,bilinear);
return 0;
}
catch(std::exception &e)
{
GCTL_ShowWhatError(e.what(), GCTL_ERROR_ERROR, 0, 0, 0);
}