Add a geometry syntax using angle and length (2D only)
Draw a line with an angle of 30 degrees and a lenght of 200: --drawline <x>,<y>@30+200
This commit is contained in:
parent
a09819285a
commit
00920947af
@ -570,6 +570,11 @@ Detailed Description of Options
|
|||||||
as world-coordinates, but the dimensions will be interpreted relative
|
as world-coordinates, but the dimensions will be interpreted relative
|
||||||
to the image. I.e. they won't scale with the map.
|
to the image. I.e. they won't scale with the map.
|
||||||
|
|
||||||
|
* If the geometry is specified using an angle and length, and if the
|
||||||
|
length is specified in nodes (e.g. '20n'), the size will scale. If
|
||||||
|
the length is specified in pixels (e.g. '20p') or if no unit is
|
||||||
|
specified, then the size will not scale.
|
||||||
|
|
||||||
In practise this means that two identically-sized figures in a full-scale
|
In practise this means that two identically-sized figures in a full-scale
|
||||||
map, may have different sizes after scaling, depending on how their
|
map, may have different sizes after scaling, depending on how their
|
||||||
geometry was specified. The jury is still out as to whether this is
|
geometry was specified. The jury is still out as to whether this is
|
||||||
@ -1384,6 +1389,7 @@ Geometry Syntax
|
|||||||
* As the corners of the area
|
* As the corners of the area
|
||||||
* As the lower-left corner, and the area's dimensions
|
* As the lower-left corner, and the area's dimensions
|
||||||
* As the center of the are, and the area's dimensions
|
* As the center of the are, and the area's dimensions
|
||||||
|
* As a corner and an angle and distance to the second corner
|
||||||
* Using legacy format (compatible with standard minetestmapper)
|
* Using legacy format (compatible with standard minetestmapper)
|
||||||
|
|
||||||
**Granularity**
|
**Granularity**
|
||||||
@ -1501,6 +1507,40 @@ Geometry Using Center and Dimensions
|
|||||||
option is used with a center-style geometry, then that geometry is
|
option is used with a center-style geometry, then that geometry is
|
||||||
interpreted as a corner geometry instead.
|
interpreted as a corner geometry instead.
|
||||||
|
|
||||||
|
Geometry using Corner and Angle with Length
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
A geometry using one corner (or endpoint of the line) and an
|
||||||
|
angle with a line length is specified as follows::
|
||||||
|
|
||||||
|
--drawline <xcorner>,<ycorner>@<angle>+<length>[np]
|
||||||
|
|
||||||
|
This syntax is only supported for 2-dimensional geometries
|
||||||
|
(e.g. when drawing figures on the map).
|
||||||
|
|
||||||
|
where ``xcorner,ycorner`` are the coordinates of one corner,
|
||||||
|
``angle`` is the angle, or compass direction, in degrees of the
|
||||||
|
line or second corner, and ``length`` is the length of the
|
||||||
|
line, or the distance to the second corner.
|
||||||
|
|
||||||
|
An angle of 0° is north, 90° is east, 180° is south and 270° is
|
||||||
|
west. Negative values are accepted as well: -90° is also west,
|
||||||
|
for instance.
|
||||||
|
|
||||||
|
When the map is scaled, the length may or may not need to be
|
||||||
|
scaled. Where scaling is possible, a suffix 'n' specifies
|
||||||
|
that the length is in nodes, and so it scales. A suffix 'p'
|
||||||
|
specifies a length in pixels, which do not scale.
|
||||||
|
|
||||||
|
Scaling is not possible for figures that are drawn on the map,
|
||||||
|
e.g. using '--drawmapline'. Use '--drawline' instead if
|
||||||
|
a figure must scale with the map.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
--drawline 100,100@20+100p
|
||||||
|
|
||||||
|
|
||||||
Legacy Geometry Format
|
Legacy Geometry Format
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
65
mapper.cpp
65
mapper.cpp
@ -46,6 +46,8 @@ using namespace std;
|
|||||||
#define OPT_SILENCE_SUGGESTIONS 0x92
|
#define OPT_SILENCE_SUGGESTIONS 0x92
|
||||||
#define OPT_PRESCAN_WORLD 0x93
|
#define OPT_PRESCAN_WORLD 0x93
|
||||||
|
|
||||||
|
#define DRAW_ARROW_LENGTH 10
|
||||||
|
#define DRAW_ARROW_ANGLE 30
|
||||||
// Will be replaced with the actual name and location of the executable (if found)
|
// Will be replaced with the actual name and location of the executable (if found)
|
||||||
string executableName = "minetestmapper";
|
string executableName = "minetestmapper";
|
||||||
string executablePath; // ONLY for use on windows
|
string executablePath; // ONLY for use on windows
|
||||||
@ -124,6 +126,7 @@ void usage()
|
|||||||
" --drawair\n"
|
" --drawair\n"
|
||||||
" --draw[map]point \"<x>,<y> color\"\n"
|
" --draw[map]point \"<x>,<y> color\"\n"
|
||||||
" --draw[map]line \"<geometry> color\"\n"
|
" --draw[map]line \"<geometry> color\"\n"
|
||||||
|
" --draw[map]line \"<x>,<y> <angle> <length>[np] color\"\n"
|
||||||
" --draw[map]circle \"<geometry> color\"\n"
|
" --draw[map]circle \"<geometry> color\"\n"
|
||||||
" --draw[map]ellipse \"<geometry> color\"\n"
|
" --draw[map]ellipse \"<geometry> color\"\n"
|
||||||
" --draw[map]rectangle \"<geometry> color\"\n"
|
" --draw[map]rectangle \"<geometry> color\"\n"
|
||||||
@ -433,6 +436,29 @@ static void convertDimensionToCornerCoordinates(NodeCoord &coord1, NodeCoord &co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void convertPolarToCartesianCoordinates(NodeCoord &coord1, NodeCoord &coord2, double angle, double length)
|
||||||
|
{
|
||||||
|
angle *= M_PI / 180;
|
||||||
|
double dxf = sin(angle) * length;
|
||||||
|
int dx = (dxf < 0 ? -1 : 1) * int(fabs(dxf + (dxf < 0 ? -0.5 : 0.5)));
|
||||||
|
dx -= dx < 0 ? -1 : dx > 0 ? +1 : 0;
|
||||||
|
double dyf = cos(angle) * length;
|
||||||
|
int dy = (dyf < 0 ? -1 : 1) * int(fabs(dyf + (dyf < 0 ? -0.5 : 0.5)));
|
||||||
|
dy -= dy < 0 ? -1 : dy > 0 ? +1 : 0;
|
||||||
|
coord2.x() = coord1.x() + dx;
|
||||||
|
coord2.y() = coord1.y() + dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void convertCartesianToPolarCoordinates(NodeCoord &coord1, NodeCoord &coord2, double &angle, double &length)
|
||||||
|
{
|
||||||
|
int lx = coord2.x() - coord1.x();
|
||||||
|
lx += lx < 0 ? -1 : lx > 0 ? 1 : 0;
|
||||||
|
int ly = coord2.y() - coord1.y();
|
||||||
|
ly += ly < 0 ? -1 : ly > 0 ? 1 : 0;
|
||||||
|
length = sqrt(lx*lx + ly*ly);
|
||||||
|
angle = atan2(lx, ly) / M_PI * 180;
|
||||||
|
}
|
||||||
|
|
||||||
static void orderCoordinateDimensions(NodeCoord &coord1, NodeCoord &coord2, int n)
|
static void orderCoordinateDimensions(NodeCoord &coord1, NodeCoord &coord2, int n)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
@ -454,6 +480,7 @@ static void orderCoordinateDimensions(NodeCoord &coord1, NodeCoord &coord2, int
|
|||||||
// (center of the area, and dimensions)
|
// (center of the area, and dimensions)
|
||||||
// <x>[,:]<y>+<w>+<h>
|
// <x>[,:]<y>+<w>+<h>
|
||||||
// (corner of the area, and dimensions)
|
// (corner of the area, and dimensions)
|
||||||
|
// <x>,<y>@<angle>+<length>
|
||||||
static bool parseGeometry(istream &is, NodeCoord &coord1, NodeCoord &coord2, NodeCoord &dimensions, bool &legacy, bool ¢ered, int n, FuzzyBool expectDimensions, int wildcard = 0)
|
static bool parseGeometry(istream &is, NodeCoord &coord1, NodeCoord &coord2, NodeCoord &dimensions, bool &legacy, bool ¢ered, int n, FuzzyBool expectDimensions, int wildcard = 0)
|
||||||
{
|
{
|
||||||
int pos;
|
int pos;
|
||||||
@ -526,6 +553,44 @@ static bool parseGeometry(istream &is, NodeCoord &coord1, NodeCoord &coord2, Nod
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (safePeekStream(is) == '@') {
|
||||||
|
// <x>,<y>@<angle>+<length>[np]
|
||||||
|
if (n != 2)
|
||||||
|
return false;
|
||||||
|
centered = false;
|
||||||
|
is.ignore(1);
|
||||||
|
double angle;
|
||||||
|
double length;
|
||||||
|
bool world_relative = false;
|
||||||
|
|
||||||
|
is >> angle;
|
||||||
|
if (safePeekStream(is) != '+' && safePeekStream(is) != '-')
|
||||||
|
return false;
|
||||||
|
if (safePeekStream(is) == '+')
|
||||||
|
is.ignore(1);
|
||||||
|
is >> length;
|
||||||
|
if (!validStreamAtEof(is)) {
|
||||||
|
switch (safePeekStream(is)) {
|
||||||
|
case 'n' :
|
||||||
|
is.ignore(1);
|
||||||
|
world_relative = true;
|
||||||
|
break;
|
||||||
|
case 'p' :
|
||||||
|
is.ignore(1);
|
||||||
|
world_relative = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!validStreamAtWsOrEof(is))
|
||||||
|
return false;
|
||||||
|
convertPolarToCartesianCoordinates(coord1, coord2, angle, length);
|
||||||
|
if (!world_relative) {
|
||||||
|
convertCornerToDimensionCoordinates(coord1, coord2, dimensions, n);
|
||||||
|
coord2.x() = NodeCoord::Invalid;
|
||||||
|
coord2.y() = NodeCoord::Invalid;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
// <x>,<y>+<w>+<h>
|
// <x>,<y>+<w>+<h>
|
||||||
centered = false;
|
centered = false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user