Files

253 lines
8.0 KiB
C++
Raw Permalink Normal View History

2026-01-23 17:03:45 +08:00
/*
* File: fmr.cpp
* Author: Florian Heinz <fh@sysv.de>
*
* Created on October 12, 2016, 3:08 PM
//paragraph [1] Title: [{\Large \bf \begin {center}] [\end {center}}]
//[TOC] [\tableofcontents]
[1] Example binary to demonstrate the usage of libfmr
[TOC]
1 Overview
*/
#include "fmr_FMRegion.h"
#include "fmr_Region.h"
#include "fmr_RList.h"
#include "fmr_Interval.h"
#include "satof.h"
#include <iostream>
using namespace std;
using namespace fmr;
static void usage ();
static double instant (std::string inst);
static RList readObjectFile (string filename, string objecttype);
static void atinstant (string fmregion, string inst) {
RList fmrrl = readObjectFile(fmregion, "fmregion"); FMRegion fmr(fmrrl);
cout << fmr.atinstant(instant(inst))
.toRList().SecondoObject("region", "region")
.ToString() << "\n";
}
static void inside (string fmregion, string mpoint) {
RList fmrrl = readObjectFile(fmregion, "fmregion"); FMRegion fmr(fmrrl);
RList mprl = readObjectFile(mpoint, "mpoint"); MPoint mp(mprl);
cout << fmr.inside(mp)
.toRList().SecondoObject("mbool", "mbool")
.ToString() << "\n";
}
static void intersection (string fmregion, string mpoint) {
RList fmrrl = readObjectFile(fmregion, "fmregion"); FMRegion fmr(fmrrl);
RList mprl = readObjectFile(mpoint, "mpoint"); MPoint mp(mprl);
cout << mp.intersection(fmr)
.toRList().SecondoObject("mpoint", "mpoint")
.ToString() << "\n";
}
static void setcenter (string fmregion, string _x, string _y) {
double x = satof(_x.c_str());
double y = satof(_y.c_str());
RList fmrrl = readObjectFile(fmregion, "fmregion"); FMRegion fmr(fmrrl);
Point c(x, y);
fmr.setCenter(c);
cout << fmr.toRList().SecondoObject("fmregion", "fmregion")
.ToString() << "\n";
}
static void traversedarea (string fmregion) {
RList fmrrl = readObjectFile(fmregion, "fmregion"); FMRegion fmr(fmrrl);
cout << fmr.traversedArea()
.toRList().SecondoObject("cregion", "cregion")
.ToString() << "\n";
}
static void inside2 (string cregion, string point) {
RList cregrl = readObjectFile(cregion, "cregion"); CRegion creg(cregrl);
double x, y;
if (sscanf(point.c_str(), "%lf/%lf", &x, &y) != 2) {
cerr << "Error parsing point! Format: <x>/<y>\n";
exit(EXIT_FAILURE);
}
Point p(x, y);
cout << (creg.inside(p) ? "TRUE" : "FALSE") << "\n";
}
static void intersects (string cregion, string region) {
RList cregrl = readObjectFile(cregion, "cregion"); CRegion creg(cregrl);
RList regrl = readObjectFile( region, "region"); Region reg( regrl);
cout << (creg.intersects(reg) ? "TRUE" : "FALSE") << "\n";
}
static void interpolate (string region1, string region2) {
RList reg1rl = readObjectFile(region1, "region"); Region reg1(reg1rl);
RList reg2rl = readObjectFile(region2, "region"); Region reg2(reg2rl);
cout <<
reg1.interpolate(reg2, Interval())
.toRList().SecondoObject("fmregion", "fmregion")
.ToString() << "\n";
}
static void toregion (string cregion, string nrsamples) {
int nr = atoi(nrsamples.c_str());
RList cregrl = readObjectFile(cregion, "cregion"); CRegion creg(cregrl);
cout <<
creg.toRegion(nr)
.toRList().SecondoObject("region", "region")
.ToString() << "\n";
}
static void mkcad (string region, string rotations) {
double rots = ((double)atoi(rotations.c_str()))/360.0;
RList srcregrl = readObjectFile(region, "region"); Region srcreg(srcregrl);
Point c = srcreg.centroid();
BoundingBox srcbb = srcreg.boundingBox();
Point p = srcbb.upperRight - srcbb.lowerLeft;
double dist = (p.x > p.y) ? p.x : p.y;
FMRegion fmr(srcreg,
TransformationUnit(c, Point(dist*M_PI*rots, 0), -2*M_PI*rots));
Region reg = fmr.traversedArea().toRegion(200);
RList ta = reg.toRList();
RList face = ta[0][0];
std::stringstream ss;
BoundingBox bb = reg.boundingBox();
Point d = bb.upperRight - bb.lowerLeft;
double sc = 180/d.x;
double sc2 = 180/d.y;
if (sc2 < sc)
sc = sc2;
Point o = bb.lowerLeft - c;
ss << "linear_extrude(5) {\n"
<< " difference() {\n"
<< " translate([" << (o.x*sc - 5.0) << "," << (o.y*sc - 5.0) << "])\n"
<< " square([" << d.x*sc+10.0 << "," << d.y*sc+10.0 << "]);\n"
<< " polygon([";
for (unsigned int i = 0; i < face.size(); i++) {
RList pt = face[i];
ss << "["<<(pt[0].getNr()-c.x)*sc<<"," << (pt[1].getNr()-c.y)*sc << "]";
if (i < face.size()-1)
ss << ",";
}
double doff = -d.y*sc-5;
ss << "]);\n"
<< " }\n"
<< " translate([0, " << doff << ", 0])\n"
<< " polygon([";
sc = sc/1.02;
face = srcregrl[0][0];
for (unsigned int i = 0; i < face.size(); i++) {
RList pt = face[i];
ss << "["<<(pt[0].getNr()-c.x)*sc<<"," << (pt[1].getNr()-c.y)*sc << "]";
if (i < face.size()-1)
ss << ",";
}
ss << "]);\n"
<< "}\n"
<< "$fn=20;\n"
<< " translate([0, " << doff << ",0])\n"
<< "cylinder(d=2, h=20);\n";
cout << ss.str();
}
int main (int argc, char **argv) {
if (argc < 2)
usage();
string cmd = argv[1];
if (cmd == string("atinstant")) {
if (argc != 4) usage();
atinstant(argv[2], argv[3]);
} else if (cmd == string("inside")) {
if (argc != 4) usage();
inside(argv[2], argv[3]);
} else if (cmd == string("intersection")) {
if (argc != 4) usage();
intersection(argv[2], argv[3]);
} else if (cmd == string("setcenter")) {
if (argc != 5) usage();
setcenter(argv[2], argv[3], argv[4]);
} else if (cmd == string("traversedarea")) {
if (argc != 3) usage();
traversedarea(argv[2]);
} else if (cmd == string("inside2")) {
if (argc != 4) usage();
inside2(argv[2], argv[3]);
} else if (cmd == string("intersects")) {
if (argc != 4) usage();
intersects(argv[2], argv[3]);
} else if (cmd == string("interpolate")) {
if (argc != 4) usage();
interpolate(argv[2], argv[3]);
} else if (cmd == string("toregion")) {
if (argc != 4) usage();
toregion(argv[2], argv[3]);
} else if (cmd == string("mkcad")) {
if (argc != 4) usage();
mkcad(argv[2], argv[3]);
} else {
usage();
}
exit(EXIT_SUCCESS);
}
static void usage () {
cerr <<
"Usage: fmr <command> [<param1> ... <paramn>]\n" <<
" where command is:\n"
" atinstant <fmregion> #<instant>\n"
" inside <fmregion> <mpoint>\n"
" intersection <fmregion> <mpoint>\n"
" setcenter <fmregion> <x> <y>\n"
" traversedarea <fmregion>\n"
" inside2 <cregion> #<point>\n"
" intersects <cregion> <region>\n"
" interpolate <region> <region>\n"
" toregion <cregion> <nrsamples>\n"
" mkcad <region> <rotations>\n"
"# denotes a literal argument, others are files with nested lists.\n"
"Format instant: YYYY-MM-DD[-HH[:MM[:SS[.sss]]]], e.g. 2016-10-01\n"
"Format point: <x>/<y>, e.g. 10.45/20.77\n";
exit(EXIT_FAILURE);
}
static RList readObjectFile (string filename, string objecttype) {
RList rl = RList::parseFile(filename);
if (rl[3].getSym() != objecttype) {
cerr << "File '" << filename << "' parse error: No "
<< objecttype << " object\n";
exit(EXIT_FAILURE);
}
return rl[4];
}
static double instant (string inststr) {
double inst = Interval::parsetime(inststr);
if (isnan(inst)) {
cerr << "Instant '" << inststr << "' could not be parsed!\n";
exit(EXIT_FAILURE);
}
return inst;
}