Files
secondo/Algebras/FixedMRegion/fmr/UPoint.cpp
2026-01-23 17:03:45 +08:00

183 lines
4.7 KiB
C++

/*
----
* This file is part of libfmr
*
* File: UPoint.cpp
* Author: flo
*
* Created on September 10, 2016, 6:20 PM
----
//paragraph [1] Title: [{\Large \bf \begin {center}] [\end {center}}]
//[TOC] [\tableofcontents]
[1] Implementation of the class ~UPoint~
[TOC]
1 Overview
The class ~UPoint~ represents a single time interval of a moving point.
Besides moving linearly from the startpoint ~s~ along a vector ~v~, it
may optionally also rotate around a center ~c~ by an angle ~a~. A set
of those UPoints with disjunct time intervals make up an ~MPoint~.
The main purpose of this construct is to implement the operation
MPoint ~inside~ FMRegion (see also MPoint.cpp)
To implement this operation, the rotation and movement of the FMRegion is
projected on the MPoint (resp. on each of its UPoint units), which is the
reason, why a rotating movement component is implemented here.
- First, transform the start of the UPoint to match the initial vector
and angle of the FMRegion
- Then, add the movement vector of the FMRegion to the UPoint and store
the center point and rotation angle of the FMRegion
- During the movement, the center point moves away from the startpoint
along the vector of the UPoint, and then the rotation is performed.
After this transformation, the FMRegion can be seen as a static region
while the intersection times are still the same as with the initial
configuration, since the relative position of the UPoint to the FMRegion
is exactly the same as before at all times.
Calculation of movement for time ~t~: s.rotate(c-v[*]t, a[*]t) + v[*]t
The parametric functions of this moving point are as follows:
fx(t) = c.x + (s.x-c.x+v.x[*]t)[*]cos(a[*]t) - (s.y-c.y+v.y[*]t)[*]sin(a[*]t)
fy(t) = c.y + (s.x-c.x+v.x[*]t)[*]sin(a[*]t) + (s.y-c.y+v.y[*]t)[*]cos(a[*]t)
*/
#include "fmr_UPoint.h"
using namespace fmr;
/*
2 Constructor
Constructs an invalid moving point.
*/
UPoint::UPoint() {
valid = false;
}
/*
3 Construct form RList
Constructs a UPoint from its RList representation.
*/
UPoint::UPoint(RList& l) {
iv = Interval(l[0]);
s = Point((double) l[1][0], (double) l[1][1]);
Point e((double) l[1][2], (double) l[1][3]);
v = e - s;
valid = true;
}
/*
4 Construct from start and endpoint
For a given startpoint ~s~, endpoint ~e~ and interval ~iv~,
construct a UPoint without rotation.
*/
UPoint::UPoint(Point s, Point e, Interval iv) : s(s), iv(iv) {
v = e - s;
rot = 0;
valid = true;
}
/*
5 ~transform~
Transforms a straight moving UPoint to also reflect the movement
of an fmregion transform unit.
*/
UPoint UPoint::transform(TransformationUnit& _tu) {
// First, calculate the intersection of the time intervals.
// The resulting UPoint will only cover the overlapping
// part of the time intervals
Interval niv = _tu.iv.intersection(iv);
if ((niv.start == niv.end) && (!niv.lc || !niv.rc))
return UPoint();
// Calculcate the UPoint and TransformationUnit restricted to
// the overlapping time interval
UPoint up = restrict(niv);
TransformationUnit tu = _tu.restrict(niv);
// Now, calculcate the new startpoint and vector of the resulting
// UPoint to honour the initial vector and angle of the fmregion
up.s = (up.s - tu.v0).rotate(tu.c, -tu.a0);
up.v = (up.v - tu.v ).rotate(-tu.a0);
// Store the center of rotation and the (inverted) angle, since the
// UPoint will rotate in the other direction.
up.c = tu.c;
up.rot = -tu.a;
// The resulting UPoint will now at all times t have exactly the
// same relative position to the (static) fmregion at time t=0 as
// the original UPoint had to the moving fmregion.
return up;
}
/*
6 ~restrict~
Returns a new UPoint, which is restricted to the time interval ~niv~.
The original object is not modified.
*/
UPoint UPoint::restrict (Interval niv) {
double st = iv.getFrac(niv.start);
double et = iv.getFrac(niv.end);
return UPoint(s + v*st, s + v*et, niv);
}
/*
7 ~project~
Calculate the position of the UPoint at time fraction ~frac~.
First, calculate the center point (c-v[*]t), then rotate it and
finally, add the movement along the vector.
*/
Point UPoint::project(double t) {
return s.rotate(c-v*t, rot*t) + v*t;
}
/*
8 ~atinstant~
Calculate the position of the UPoint at time ~time~
*/
Point UPoint::atinstant(double time) {
double t = (time - iv.start)/(iv.end - iv.start);
return project(t);
}
/*
9 ~toRList~
Returns an RList representation of this UPoint.
*/
RList UPoint::toRList() {
RList ret;
ret.append(iv.toRList());
RList p;
p.append(s.x);
p.append(s.y);
p.append(s.x+v.x);
p.append(s.y+v.y);
ret.append(p);
return ret;
}