48 const double* pLow,
const double* pHigh,
49 const double* pVLow,
const double* pVHigh,
50 const IInterval& ivT, uint32_t dimension)
52 initialize(pLow, pHigh, pVLow, pVHigh, ivT.getLowerBound(), ivT.getUpperBound(), dimension);
56 const double* pLow,
const double* pHigh,
57 const double* pVLow,
const double* pVHigh,
58 double tStart,
double tEnd, uint32_t dimension)
60 initialize(pLow, pHigh, pVLow, pVHigh, tStart, tEnd, dimension);
73 ivT.getLowerBound(), ivT.getUpperBound(), low.
m_dimension);
79 double tStart,
double tEnd)
90 const Region& mbr,
const Region& vbr,
const IInterval& ivT)
99 const Region& mbr,
const Region& vbr,
double tStart,
double tEnd)
173 void MovingRegion::initialize(
174 const double* pLow,
const double* pHigh,
175 const double* pVLow,
const double* pVHigh,
176 double tStart,
double tEnd, uint32_t dimension)
245 m_pLow[i] < r.
m_pLow[i] - std::numeric_limits<double>::epsilon() ||
246 m_pLow[i] > r.
m_pLow[i] + std::numeric_limits<double>::epsilon() ||
247 m_pHigh[i] < r.
m_pHigh[i] - std::numeric_limits<double>::epsilon() ||
248 m_pHigh[i] > r.
m_pHigh[i] + std::numeric_limits<double>::epsilon() ||
249 m_pVLow[i] < r.
m_pVLow[i] - std::numeric_limits<double>::epsilon() ||
250 m_pVLow[i] > r.
m_pVLow[i] + std::numeric_limits<double>::epsilon() ||
260 for (uint32_t cDim = 0; cDim <
m_dimension; ++cDim)
268 double MovingRegion::getLow(uint32_t d,
double t)
const
278 double MovingRegion::getHigh(uint32_t d,
double t)
const
323 bool MovingRegion::intersectsRegionInTime(
const MovingRegion& r, IInterval& ivOut)
const
325 return intersectsRegionInTime(r, r, ivOut);
340 bool MovingRegion::intersectsRegionInTime(
const IInterval& ivPeriod,
const MovingRegion& r, IInterval& ivOut)
const
346 assert(ivPeriod.getLowerBound() < ivPeriod.getUpperBound());
361 if (tmax <= tmin)
return false;
363 tmin = std::max(tmin, ivPeriod.getLowerBound());
364 tmax = std::min(tmax, ivPeriod.getUpperBound());
367 if (tmax <= tmin)
return false;
369 assert(tmax < std::numeric_limits<double>::max());
370 assert(tmin > -std::numeric_limits<double>::max());
375 for (uint32_t cDim = 0; cDim <
m_dimension; ++cDim)
378 tmin >= ivPeriod.getLowerBound() && tmax <= ivPeriod.getUpperBound() &&
415 assert(tmin <= tmax);
419 tmin >= ivPeriod.getLowerBound() && tmax <= ivPeriod.getUpperBound() &&
423 ivOut.setBounds(tmin, tmax);
438 bool MovingRegion::containsRegionInTime(
const IInterval& ivPeriod,
const MovingRegion& r)
const
444 double tmin = std::max(ivPeriod.getLowerBound(), r.
m_startTime);
445 double tmax = std::min(ivPeriod.getUpperBound(), r.
m_endTime);
449 if (tmax <= tmin || tmin < m_startTime || tmax >
m_endTime)
return false;
451 double intersectionTime;
456 tmin >= ivPeriod.getLowerBound() && tmax <= ivPeriod.getUpperBound() &&
460 for (uint32_t cDim = 0; cDim <
m_dimension; ++cDim)
471 if (tmin < intersectionTime && intersectionTime < tmax)
return false;
472 if (tmin == intersectionTime && r.
m_pVHigh[cDim] >
m_pVHigh[cDim])
return false;
479 if (tmin < intersectionTime && intersectionTime < tmax)
return false;
480 if (tmin == intersectionTime && r.
m_pVLow[cDim] <
m_pVLow[cDim])
return false;
504 double tmin = std::max(ivI.getLowerBound(),
m_startTime);
505 double tmax = std::min(ivI.getUpperBound(),
m_endTime);
507 assert(tmin > -std::numeric_limits<double>::max());
508 assert(tmax < std::numeric_limits<double>::max());
509 assert(tmin <= tmax);
511 if (tmin >= tmax - std::numeric_limits<double>::epsilon() &&
512 tmin <= tmax + std::numeric_limits<double>::epsilon())
515 double dx1, dx2, dx3;
516 double dv1, dv2, dv3;
517 double H = tmax - tmin;
528 H * (dx1 + dx2 + dx3 + dx1*dx2 + dx1*dx3 + dx2*dx3) +
529 H*H * (dv1 + dv2 + dv3 + dx1*dv2 + dv1*dx2 + dx1*dv3 +
530 dv1*dx3 + dx2*dv3 + dv2*dx3) / 2.0 +
531 H*H*H * (dv1*dv2 + dv1*dv3 + dv2*dv3) / 3.0;
539 return H * (dx1 + dx2) + H * H * (dv1 + dv2) / 2.0;
564 assert(ivI.getLowerBound() < ivI.getUpperBound());
570 if (tmax <= tmin)
return 0.0;
572 tmin = std::max(tmin, ivI.getLowerBound());
573 tmax = std::min(tmax, ivI.getUpperBound());
576 if (tmax <= tmin)
return 0.0;
578 assert(tmax < std::numeric_limits<double>::max());
579 assert(tmin > -std::numeric_limits<double>::max());
581 if (tmin >= tmax - std::numeric_limits<double>::epsilon() &&
582 tmin <= tmax + std::numeric_limits<double>::epsilon())
585 double H = tmax - tmin;
589 double a = 0.0, b = 0.0, c = 0.0, f = 0.0, l = 0.0, m = 0.0, n = 0.0;
591 for (uint32_t cDim = 0; cDim <
m_dimension; ++cDim)
601 for (uint32_t cDim = 0; cDim <
m_dimension; ++cDim)
603 a += dv[cDim] * dv[cDim];
604 b += 2.0 * dx[cDim] * dv[cDim];
605 c += dx[cDim] * dx[cDim];
611 if (a == 0.0 && c == 0.0)
return 0.0;
612 if (a == 0.0)
return H * std::sqrt(c);
613 if (c == 0.0)
return H * H * std::sqrt(a) / 2.0;
615 f = std::sqrt(a * H * H + b * H + c);
617 m = 4.0 * a * c - b * b;
618 n = 2.0 * std::sqrt(a);
620 return (l * f + log(l / n + f) * m / n - b * std::sqrt(c) - std::log(b / n + std::sqrt(c)) * m / n) / (4.0 * a);
647 for (uint32_t cDim = 0; cDim <
m_dimension; ++cDim)
678 assert(ivPeriod.getLowerBound() < ivPeriod.getUpperBound());
681 if (containsPointInTime(ivPeriod, p))
691 if (tmax <= tmin)
return false;
693 tmin = std::max(tmin, ivPeriod.getLowerBound());
694 tmax = std::min(tmax, ivPeriod.getUpperBound());
697 if (tmax <= tmin)
return false;
699 assert(tmax < std::numeric_limits<double>::max());
700 assert(tmin > -std::numeric_limits<double>::max());
702 for (uint32_t cDim = 0; cDim <
m_dimension; ++cDim)
705 tmin >= ivPeriod.getLowerBound() && tmax <= ivPeriod.getUpperBound() &&
739 if (tmin > tmax)
return false;
742 ivOut.setBounds(tmin, tmax);
747 bool MovingRegion::containsPointInTime(
const MovingPoint& p)
const
757 bool MovingRegion::containsPointInTime(
const IInterval& ivPeriod,
const MovingPoint& p)
const
763 double tmin = std::max(ivPeriod.getLowerBound(), p.
m_startTime);
764 double tmax = std::min(ivPeriod.getUpperBound(), p.
m_endTime);
767 if (tmax <= tmin || tmin < m_startTime || tmax >
m_endTime)
return false;
769 double intersectionTime;
772 tmin >= ivPeriod.getLowerBound() && tmax <= ivPeriod.getUpperBound() &&
776 for (uint32_t cDim = 0; cDim <
m_dimension; ++cDim)
786 if (tmin < intersectionTime && intersectionTime < tmax)
return false;
794 if (tmin < intersectionTime && intersectionTime < tmax)
return false;
795 if (tmin == intersectionTime && p.
m_pVCoords[cDim] <
m_pVLow[cDim])
return false;
806 for (uint32_t cDim = 0; cDim <
m_dimension; ++cDim)
832 for (uint32_t cDim = 0; cDim <
m_dimension; ++cDim)
866 assert(ivI.getLowerBound() < ivI.getUpperBound());
873 if (tmax <= tmin)
return 0.0;
875 tmin = std::max(tmin, ivI.getLowerBound());
876 tmax = std::min(tmax, ivI.getUpperBound());
879 if (tmax <= tmin)
return 0.0;
881 assert(tmax < std::numeric_limits<double>::max());
882 assert(tmin > -std::numeric_limits<double>::max());
887 if (! intersectsRegionInTime(ivIn, r, ivOut))
return 0.0;
890 tmin = ivIn.getLowerBound();
891 tmax = ivIn.getUpperBound();
892 assert(tmin <= tmax);
894 assert(tmin >= ivI.getLowerBound() && tmax <= ivI.getUpperBound());
896 if (containsRegionInTime(ivIn, r))
907 auto ascending = [](CrossPoint& lhs, CrossPoint& rhs) {
return lhs.m_t > rhs.m_t; };
908 std::priority_queue < CrossPoint, std::vector<CrossPoint>, decltype(ascending)> pq(ascending);
923 assert(c.m_t >= tmin && c.m_t <= tmax);
938 assert(c.m_t >= tmin && c.m_t <= tmax);
954 assert(c.m_t >= tmin && c.m_t <= tmax);
969 assert(c.m_t >= tmin && c.m_t <= tmax);
981 c = pq.top(); pq.pop();
986 if (c.m_boundary == 0)
988 x.
m_pLow[c.m_dimension] = c.m_to->m_pLow[c.m_dimension];
989 x.
m_pVLow[c.m_dimension] = c.m_to->m_pVLow[c.m_dimension];
993 x.
m_pHigh[c.m_dimension] = c.m_to->m_pHigh[c.m_dimension];
994 x.
m_pVHigh[c.m_dimension] = c.m_to->m_pVHigh[c.m_dimension];
1019 return (
sizeof(uint32_t) + 2 *
sizeof(
double) + 4 *
m_dimension *
sizeof(
double));
1026 memcpy(&dimension, ptr,
sizeof(uint32_t));
1027 ptr +=
sizeof(uint32_t);
1029 ptr +=
sizeof(double);
1030 memcpy(&
m_endTime, ptr,
sizeof(
double));
1031 ptr +=
sizeof(double);
1047 *data =
new uint8_t[len];
1048 uint8_t* ptr = *data;
1051 ptr +=
sizeof(uint32_t);
1053 ptr +=
sizeof(double);
1054 memcpy(ptr, &
m_endTime,
sizeof(
double));
1055 ptr +=
sizeof(double);
1080 for (uint32_t cDim = 0; cDim <
m_dimension; ++cDim)
1098 double tmin = std::max(ivI.getLowerBound(),
m_startTime);
1099 double tmax = std::min(ivI.getUpperBound(),
m_endTime);
1101 assert(tmin > -std::numeric_limits<double>::max());
1102 assert(tmax < std::numeric_limits<double>::max());
1103 assert(tmin <= tmax);
1105 if (tmin >= tmax - std::numeric_limits<double>::epsilon() &&
1106 tmin <= tmax + std::numeric_limits<double>::epsilon())
1109 double dx1, dx2, dx3;
1110 double dv1, dv2, dv3;
1111 double H = tmax - tmin;
1122 H * dx1 * dx2 * dx3 + H * H * (dx1 * dx2 * dv3 + (dx1 * dv2 + dv1 * dx2) * dx3) / 2.0 +
1123 H * H * H * ((dx1 * dv2 + dv1 * dx2) * dv3 + dv1 * dv2 * dx3) / 3.0 + H * H * H * H * dv1 * dv2 * dv3 / 4.0;
1131 return H * dx1 * dx2 + H * H * (dx1 * dv2 + dv1 * dx2) / 2.0 + H * H * H * dv1 * dv2 / 3.0;
1137 return H * dx1 + H * H * dv1 / 2.0;
1161 for (uint32_t cIndex = 0; cIndex <
m_dimension; ++cIndex)
1163 m_pLow[cIndex] = std::numeric_limits<double>::max();
1164 m_pHigh[cIndex] = -std::numeric_limits<double>::max();
1165 m_pVLow[cIndex] = std::numeric_limits<double>::max();
1166 m_pVHigh[cIndex] = -std::numeric_limits<double>::max();
1169 m_startTime = -std::numeric_limits<double>::max();
1170 m_endTime = std::numeric_limits<double>::max();
1199 os << r.
m_pLow[i] <<
" ";
virtual double getVCoord(uint32_t index) const
virtual double getProjectedCoord(uint32_t index, double t) const
virtual bool intersectsRegionAtTime(double t, const MovingRegion &r) const
virtual bool containsRegionInTime(const MovingRegion &r) const
virtual bool operator==(const MovingRegion &) const
void getVMBR(Region &out) const override
virtual void combineRegionInTime(const MovingRegion &r)
virtual double getVLow(uint32_t index) const
void makeDimension(uint32_t dimension) override
virtual bool containsPointInTime(const MovingPoint &p) const
virtual double getCenterDistanceInTime(const MovingRegion &r) const
void loadFromByteArray(const uint8_t *data) override
void storeToByteArray(uint8_t **data, uint32_t &len) override
double getAreaInTime() const override
uint32_t getByteArraySize() override
virtual bool containsRegionAfterTime(double t, const MovingRegion &r) const
virtual double getVHigh(uint32_t index) const
virtual bool intersectsPointInTime(const MovingPoint &p) const
virtual void getCombinedRegionAfterTime(double t, MovingRegion &out, const MovingRegion &in) const
virtual double getIntersectingAreaInTime(const MovingRegion &r) const
virtual void combineRegionAfterTime(double t, const MovingRegion &r)
virtual bool intersectsRegionInTime(const MovingRegion &r) const
virtual double getProjectedSurfaceAreaInTime() const
virtual double getHigh(uint32_t index, double t) const
void makeInfinite(uint32_t dimension) override
virtual bool containsRegionAtTime(double t, const MovingRegion &r) const
virtual double getExtrapolatedLow(uint32_t index, double t) const
void getMBRAtTime(double t, Region &out) const override
MovingRegion * clone() override
virtual MovingRegion & operator=(const MovingRegion &r)
virtual double getLow(uint32_t index, double t) const
virtual double getExtrapolatedHigh(uint32_t index, double t) const
virtual void makeDimension(uint32_t dimension)
SIDX_DLL std::ostream & operator<<(std::ostream &os, const Ball &ball)