Skip to content

Commit 1726d18

Browse files
committed
VirtualPath: Export tangent from findClosestPointTo()
The tangent vector is essential for the move parallel tool where we want to calculate the distance of the cursor from the tangent line touching the path in question. Please note that we are generating a "pseudo tangent" for corners and line ends to enable sensible behavior during mouse drag events.
1 parent 20065ec commit 1726d18

File tree

3 files changed

+20
-6
lines changed

3 files changed

+20
-6
lines changed

src/core/objects/object.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,7 @@ ClosestPathCoord PathObject::findClosestPointTo(
11601160

11611161
using distance_type = decltype(ClosestPathCoord::distance_squared);
11621162
return std::accumulate(begin(path_parts), end(path_parts),
1163-
ClosestPathCoord { {}, std::numeric_limits<distance_type>::max() },
1163+
ClosestPathCoord { {}, {}, std::numeric_limits<distance_type>::max() },
11641164
op);
11651165
}
11661166

src/core/path_coord.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,17 @@ class PathCoord
158158

159159

160160
/**
161-
* The structure returned when looking for closest coordinates on a path.
161+
* The structure returned when looking for the closest coordinates on a path.
162+
* The tangent element is defined even on corners and line ends. Following the
163+
* intuitive view, the tangent line touches the corner, dividing the plane into
164+
* the part with the corner and the part without it. At the line ends, the
165+
* "tangent" is the direction of the neighboring segment. The "pseudo tangent"
166+
* is generated to define the direction for mouse drag actions.
162167
*/
163168
struct ClosestPathCoord
164169
{
165170
PathCoord path_coord;
171+
MapCoordF tangent;
166172
double distance_squared;
167173
};
168174

src/core/virtual_path.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -347,9 +347,11 @@ ClosestPathCoord VirtualPath::findClosestPointTo(
347347
size_type start_index,
348348
size_type end_index ) const
349349
{
350-
Q_ASSERT(!path_coords.empty());
350+
Q_ASSERT(path_coords.size() > 1);
351351

352-
auto result = ClosestPathCoord { path_coords.front(), distance_bound_squared };
352+
auto result = ClosestPathCoord { path_coords.front(),
353+
path_coords[1].pos - path_coords[0].pos,
354+
distance_bound_squared };
353355

354356
// Find upper bound for distance.
355357
for (const auto& path_coord : path_coords)
@@ -367,6 +369,7 @@ ClosestPathCoord VirtualPath::findClosestPointTo(
367369
result.path_coord = path_coord;
368370
}
369371
}
372+
result.tangent = calculateTangent(result.path_coord.index);
370373

371374
// Check between this coord and the next one.
372375
auto last = end(path_coords)-1;
@@ -391,6 +394,7 @@ ClosestPathCoord VirtualPath::findClosestPointTo(
391394
if (to_coord.lengthSquared() < result.distance_squared)
392395
{
393396
result.distance_squared = to_coord.lengthSquared();
397+
result.tangent = tangent;
394398
result.path_coord = *pc;
395399
}
396400
continue;
@@ -402,6 +406,7 @@ ClosestPathCoord VirtualPath::findClosestPointTo(
402406
if (coord.distanceSquaredTo(next_pos) < result.distance_squared)
403407
{
404408
result.distance_squared = coord.distanceSquaredTo(next_pos);
409+
result.tangent = tangent;
405410
result.path_coord = *next_pc;
406411
}
407412
continue;
@@ -425,13 +430,16 @@ ClosestPathCoord VirtualPath::findClosestPointTo(
425430
if (coords.flags[result.path_coord.index].isCurveStart())
426431
{
427432
MapCoordF unused;
433+
MapCoordF curve2_control_point1;
428434
PathCoord::splitBezierCurve(MapCoordF(coords.flags[result.path_coord.index]), MapCoordF(coords.flags[result.path_coord.index+1]),
429435
MapCoordF(coords.flags[result.path_coord.index+2]), MapCoordF(coords.flags[result.path_coord.index+3]),
430-
result.path_coord.param, unused, unused, result.path_coord.pos, unused, unused);
436+
result.path_coord.param, unused, unused, result.path_coord.pos, curve2_control_point1, unused);
437+
result.tangent = curve2_control_point1 - result.path_coord.pos;
431438
}
432439
else
433440
{
434-
result.path_coord.pos = pos + (next_pos - pos) * double(factor);
441+
result.tangent = next_pos - pos;
442+
result.path_coord.pos = pos + result.tangent * double(factor);
435443
}
436444
}
437445
}

0 commit comments

Comments
 (0)