/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include"mozilla/FloatingPoint.h"// for UnspecifiedNaN
namespace mozilla { namespace gfx {
/* Force small values to zero. We do this to avoid having sin(360deg) * evaluate to a tiny but nonzero value.
*/ double FlushToZero(double aVal) { // XXX Is double precision really necessary here if (-FLT_EPSILON < aVal && aVal < FLT_EPSILON) { return 0.0f;
} else { return aVal;
}
}
/* Computes tan(aTheta). For values of aTheta such that tan(aTheta) is * undefined or very large, SafeTangent returns a manageably large value * of the correct sign.
*/ double SafeTangent(double aTheta) { // XXX Is double precision really necessary here constdouble kEpsilon = 0.0001;
/* tan(theta) = sin(theta)/cos(theta); problems arise when * cos(theta) is too close to zero. Limit cos(theta) to the * range [-1, -epsilon] U [epsilon, 1].
*/
// Intersect the polygon given by aPoints with the half space induced by // aPlaneNormal and return the resulting polygon. The returned points are // stored in aDestBuffer, and its meaningful subspan is returned. template <typename F>
Span<Point4DTyped<UnknownUnits, F>> IntersectPolygon(
Span<Point4DTyped<UnknownUnits, F>> aPoints, const Point4DTyped<UnknownUnits, F>& aPlaneNormal,
Span<Point4DTyped<UnknownUnits, F>> aDestBuffer) { if (aPoints.Length() < 1 || aDestBuffer.Length() < 1) { return {};
}
size_t nextIndex = 0; // aDestBuffer[nextIndex] is the next emitted point.
// Iterate over the polygon edges. In each iteration the current edge // is the edge from *prevPoint to point. If the two end points lie on // different sides of the plane, we have an intersection. Otherwise, // the edge is either completely "inside" the half-space created by // the clipping plane, and we add curPoint, or it is completely // "outside", and we discard curPoint. This loop can create duplicated // points in the polygon. constauto* prevPoint = &aPoints[aPoints.Length() - 1];
F prevDot = aPlaneNormal.DotProduct(*prevPoint); for (constauto& curPoint : aPoints) {
F curDot = aPlaneNormal.DotProduct(curPoint);
if ((curDot >= 0.0) != (prevDot >= 0.0)) { // An intersection with the clipping plane has been detected. // Interpolate to find the intersecting curPoint and emit it.
F t = -prevDot / (curDot - prevDot);
aDestBuffer[nextIndex++] = curPoint * t + *prevPoint * (1.0 - t); if (nextIndex >= aDestBuffer.Length()) { break;
}
}
if (curDot >= 0.0) { // Emit any source points that are on the positive side of the // clipping plane.
aDestBuffer[nextIndex++] = curPoint; if (nextIndex >= aDestBuffer.Length()) { break;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.