本文整理汇总了C++中Intersections::insert方法的典型用法代码示例。如果您正苦于以下问题:C++ Intersections::insert方法的具体用法?C++ Intersections::insert怎么用?C++ Intersections::insert使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Intersections
的用法示例。
在下文中一共展示了Intersections::insert方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: intersect
bool intersect(const Cubic& cubic, Intersections& i) {
SkTDArray<double> ts;
double precision = calcPrecision(cubic);
cubic_to_quadratics(cubic, precision, ts);
int tsCount = ts.count();
if (tsCount == 1) {
return false;
}
double t1Start = 0;
Cubic part;
for (int idx = 0; idx < tsCount; ++idx) {
double t1 = ts[idx];
Quadratic q1;
sub_divide(cubic, t1Start, t1, part);
demote_cubic_to_quad(part, q1);
double t2Start = t1;
for (int i2 = idx + 1; i2 <= tsCount; ++i2) {
const double t2 = i2 < tsCount ? ts[i2] : 1;
Quadratic q2;
sub_divide(cubic, t2Start, t2, part);
demote_cubic_to_quad(part, q2);
Intersections locals;
intersect2(q1, q2, locals);
for (int tIdx = 0; tIdx < locals.used(); ++tIdx) {
// discard intersections at cusp? (maximum curvature)
double t1sect = locals.fT[0][tIdx];
double t2sect = locals.fT[1][tIdx];
if (idx + 1 == i2 && t1sect == 1 && t2sect == 0) {
continue;
}
double to1 = t1Start + (t1 - t1Start) * t1sect;
double to2 = t2Start + (t2 - t2Start) * t2sect;
i.insert(to1, to2);
}
t2Start = t2;
}
t1Start = t1;
}
return i.intersected();
}
示例2: addIntersection
void QTessellatorPrivate::addIntersection(const Edge *e1, const Edge *e2)
{
const IntersectionLink emptyLink = {-1, -1};
int next = vertices.nextPos(vertices[e1->edge]);
if (e2->edge == next)
return;
int prev = vertices.prevPos(vertices[e1->edge]);
if (e2->edge == prev)
return;
Q27Dot5 yi;
bool det_positive;
bool isect = e1->intersect(*e2, &yi, &det_positive);
QDEBUG("checking edges %d and %d", e1->edge, e2->edge);
if (!isect) {
QDEBUG() << " no intersection";
return;
}
// don't emit an intersection if it's at the start of a line segment or above us
if (yi <= y) {
if (!det_positive)
return;
QDEBUG() << " ----->>>>>> WRONG ORDER!";
yi = y;
}
QDEBUG() << " between edges " << e1->edge << "and" << e2->edge << "at point ("
<< Q27Dot5ToDouble(yi) << ')';
Intersection i1;
i1.y = yi;
i1.edge = e1->edge;
IntersectionLink link1 = intersections.value(i1, emptyLink);
Intersection i2;
i2.y = yi;
i2.edge = e2->edge;
IntersectionLink link2 = intersections.value(i2, emptyLink);
// new pair of edges
if (link1.next == -1 && link2.next == -1) {
link1.next = link1.prev = i2.edge;
link2.next = link2.prev = i1.edge;
} else if (link1.next == i2.edge || link1.prev == i2.edge
|| link2.next == i1.edge || link2.prev == i1.edge) {
#ifdef DEBUG
checkLinkChain(intersections, i1);
checkLinkChain(intersections, i2);
Q_ASSERT(edgeInChain(i1, i2.edge));
#endif
return;
} else if (link1.next == -1 || link2.next == -1) {
if (link2.next == -1) {
qSwap(i1, i2);
qSwap(link1, link2);
}
Q_ASSERT(link1.next == -1);
#ifdef DEBUG
checkLinkChain(intersections, i2);
#endif
// only i2 in list
link1.next = i2.edge;
link1.prev = link2.prev;
link2.prev = i1.edge;
Intersection other;
other.y = yi;
other.edge = link1.prev;
IntersectionLink link = intersections.value(other, emptyLink);
Q_ASSERT(link.next == i2.edge);
Q_ASSERT(link.prev != -1);
link.next = i1.edge;
intersections.insert(other, link);
} else {
bool connected = edgeInChain(i1, i2.edge);
if (connected)
return;
#ifdef DEBUG
checkLinkChain(intersections, i1);
checkLinkChain(intersections, i2);
#endif
// both already in some list. Have to make sure they are connected
// this can be done by cutting open the ring(s) after the two eges and
// connecting them again
Intersection other1;
other1.y = yi;
other1.edge = link1.next;
IntersectionLink linko1 = intersections.value(other1, emptyLink);
Intersection other2;
other2.y = yi;
other2.edge = link2.next;
IntersectionLink linko2 = intersections.value(other2, emptyLink);
linko1.prev = i2.edge;
link2.next = other1.edge;
linko2.prev = i1.edge;
link1.next = other2.edge;
intersections.insert(other1, linko1);
intersections.insert(other2, linko2);
}
//.........这里部分代码省略.........
示例3: hackToFixPartialCoincidence
static void hackToFixPartialCoincidence(const Quadratic& q1, const Quadratic& q2, Intersections& i) {
// look to see if non-coincident data basically has unsortable tangents
// look to see if a point between non-coincident data is on the curve
int cIndex;
for (int uIndex = 0; uIndex < i.fUsed; ) {
double bestDist1 = 1;
double bestDist2 = 1;
int closest1 = -1;
int closest2 = -1;
for (cIndex = 0; cIndex < i.fCoincidentUsed; ++cIndex) {
double dist = fabs(i.fT[0][uIndex] - i.fCoincidentT[0][cIndex]);
if (bestDist1 > dist) {
bestDist1 = dist;
closest1 = cIndex;
}
dist = fabs(i.fT[1][uIndex] - i.fCoincidentT[1][cIndex]);
if (bestDist2 > dist) {
bestDist2 = dist;
closest2 = cIndex;
}
}
_Line ends;
_Point mid;
double t1 = i.fT[0][uIndex];
xy_at_t(q1, t1, ends[0].x, ends[0].y);
xy_at_t(q1, i.fCoincidentT[0][closest1], ends[1].x, ends[1].y);
double midT = (t1 + i.fCoincidentT[0][closest1]) / 2;
xy_at_t(q1, midT, mid.x, mid.y);
LineParameters params;
params.lineEndPoints(ends);
double midDist = params.pointDistance(mid);
// Note that we prefer to always measure t error, which does not scale,
// instead of point error, which is scale dependent. FIXME
if (!approximately_zero(midDist)) {
++uIndex;
continue;
}
double t2 = i.fT[1][uIndex];
xy_at_t(q2, t2, ends[0].x, ends[0].y);
xy_at_t(q2, i.fCoincidentT[1][closest2], ends[1].x, ends[1].y);
midT = (t2 + i.fCoincidentT[1][closest2]) / 2;
xy_at_t(q2, midT, mid.x, mid.y);
params.lineEndPoints(ends);
midDist = params.pointDistance(mid);
if (!approximately_zero(midDist)) {
++uIndex;
continue;
}
// if both midpoints are close to the line, lengthen coincident span
int cEnd = closest1 ^ 1; // assume coincidence always travels in pairs
if (!between(i.fCoincidentT[0][cEnd], t1, i.fCoincidentT[0][closest1])) {
i.fCoincidentT[0][closest1] = t1;
}
cEnd = closest2 ^ 1;
if (!between(i.fCoincidentT[0][cEnd], t2, i.fCoincidentT[0][closest2])) {
i.fCoincidentT[0][closest2] = t2;
}
int remaining = --i.fUsed - uIndex;
if (remaining > 0) {
memmove(&i.fT[0][uIndex], &i.fT[0][uIndex + 1], sizeof(i.fT[0][0]) * remaining);
memmove(&i.fT[1][uIndex], &i.fT[1][uIndex + 1], sizeof(i.fT[1][0]) * remaining);
}
}
// if coincident data is subjectively a tiny span, replace it with a single point
for (cIndex = 0; cIndex < i.fCoincidentUsed; ) {
double start1 = i.fCoincidentT[0][cIndex];
double end1 = i.fCoincidentT[0][cIndex + 1];
_Line ends1;
xy_at_t(q1, start1, ends1[0].x, ends1[0].y);
xy_at_t(q1, end1, ends1[1].x, ends1[1].y);
if (!AlmostEqualUlps(ends1[0].x, ends1[1].x) || AlmostEqualUlps(ends1[0].y, ends1[1].y)) {
cIndex += 2;
continue;
}
double start2 = i.fCoincidentT[1][cIndex];
double end2 = i.fCoincidentT[1][cIndex + 1];
_Line ends2;
xy_at_t(q2, start2, ends2[0].x, ends2[0].y);
xy_at_t(q2, end2, ends2[1].x, ends2[1].y);
// again, approximately should be used with T values, not points FIXME
if (!AlmostEqualUlps(ends2[0].x, ends2[1].x) || AlmostEqualUlps(ends2[0].y, ends2[1].y)) {
cIndex += 2;
continue;
}
if (approximately_less_than_zero(start1) || approximately_less_than_zero(end1)) {
start1 = 0;
} else if (approximately_greater_than_one(start1) || approximately_greater_than_one(end1)) {
start1 = 1;
} else {
start1 = (start1 + end1) / 2;
}
if (approximately_less_than_zero(start2) || approximately_less_than_zero(end2)) {
start2 = 0;
} else if (approximately_greater_than_one(start2) || approximately_greater_than_one(end2)) {
start2 = 1;
} else {
start2 = (start2 + end2) / 2;
}
i.insert(start1, start2);
//.........这里部分代码省略.........
示例4: calcPrecision
// this flavor centers potential intersections recursively. In contrast, '2' may inadvertently
// chase intersections near quadratic ends, requiring odd hacks to find them.
static bool intersect3(const Cubic& cubic1, double t1s, double t1e, const Cubic& cubic2,
double t2s, double t2e, double precisionScale, Intersections& i) {
i.upDepth();
bool result = false;
Cubic c1, c2;
sub_divide(cubic1, t1s, t1e, c1);
sub_divide(cubic2, t2s, t2e, c2);
SkTDArray<double> ts1;
// OPTIMIZE: if c1 == c2, call once (happens when detecting self-intersection)
cubic_to_quadratics(c1, calcPrecision(c1) * precisionScale, ts1);
SkTDArray<double> ts2;
cubic_to_quadratics(c2, calcPrecision(c2) * precisionScale, ts2);
double t1Start = t1s;
int ts1Count = ts1.count();
for (int i1 = 0; i1 <= ts1Count; ++i1) {
const double tEnd1 = i1 < ts1Count ? ts1[i1] : 1;
const double t1 = t1s + (t1e - t1s) * tEnd1;
Quadratic s1;
int o1 = quadPart(cubic1, t1Start, t1, s1);
double t2Start = t2s;
int ts2Count = ts2.count();
for (int i2 = 0; i2 <= ts2Count; ++i2) {
const double tEnd2 = i2 < ts2Count ? ts2[i2] : 1;
const double t2 = t2s + (t2e - t2s) * tEnd2;
if (cubic1 == cubic2 && t1Start >= t2Start) {
t2Start = t2;
continue;
}
Quadratic s2;
int o2 = quadPart(cubic2, t2Start, t2, s2);
#if ONE_OFF_DEBUG
char tab[] = " ";
if (tLimits1[0][0] >= t1Start && tLimits1[0][1] <= t1
&& tLimits1[1][0] >= t2Start && tLimits1[1][1] <= t2) {
Cubic cSub1, cSub2;
sub_divide(cubic1, t1Start, t1, cSub1);
sub_divide(cubic2, t2Start, t2, cSub2);
SkDebugf("%.*s %s t1=(%1.9g,%1.9g) t2=(%1.9g,%1.9g)", i.depth()*2, tab, __FUNCTION__,
t1Start, t1, t2Start, t2);
Intersections xlocals;
intersectWithOrder(s1, o1, s2, o2, xlocals);
SkDebugf(" xlocals.fUsed=%d\n", xlocals.used());
}
#endif
Intersections locals;
intersectWithOrder(s1, o1, s2, o2, locals);
double coStart[2] = { -1 };
_Point coPoint;
int tCount = locals.used();
for (int tIdx = 0; tIdx < tCount; ++tIdx) {
double to1 = t1Start + (t1 - t1Start) * locals.fT[0][tIdx];
double to2 = t2Start + (t2 - t2Start) * locals.fT[1][tIdx];
// if the computed t is not sufficiently precise, iterate
_Point p1 = xy_at_t(cubic1, to1);
_Point p2 = xy_at_t(cubic2, to2);
if (p1.approximatelyEqual(p2)) {
if (locals.fIsCoincident[0] & 1 << tIdx) {
if (coStart[0] < 0) {
coStart[0] = to1;
coStart[1] = to2;
coPoint = p1;
} else {
i.insertCoincidentPair(coStart[0], to1, coStart[1], to2, coPoint, p1);
coStart[0] = -1;
}
result = true;
} else if (cubic1 != cubic2 || !approximately_equal(to1, to2)) {
if (i.swapped()) { // FIXME: insert should respect swap
i.insert(to2, to1, p1);
} else {
i.insert(to1, to2, p1);
}
result = true;
}
} else {
double offset = precisionScale / 16; // FIME: const is arbitrary -- test & refine
#if 1
double c1Bottom = tIdx == 0 ? 0 :
(t1Start + (t1 - t1Start) * locals.fT[0][tIdx - 1] + to1) / 2;
double c1Min = SkTMax(c1Bottom, to1 - offset);
double c1Top = tIdx == tCount - 1 ? 1 :
(t1Start + (t1 - t1Start) * locals.fT[0][tIdx + 1] + to1) / 2;
double c1Max = SkTMin(c1Top, to1 + offset);
double c2Min = SkTMax(0., to2 - offset);
double c2Max = SkTMin(1., to2 + offset);
#if ONE_OFF_DEBUG
SkDebugf("%.*s %s 1 contains1=%d/%d contains2=%d/%d\n", i.depth()*2, tab, __FUNCTION__,
c1Min <= tLimits1[0][1] && tLimits1[0][0] <= c1Max
&& c2Min <= tLimits1[1][1] && tLimits1[1][0] <= c2Max,
to1 - offset <= tLimits1[0][1] && tLimits1[0][0] <= to1 + offset
&& to2 - offset <= tLimits1[1][1] && tLimits1[1][0] <= to2 + offset,
c1Min <= tLimits2[0][1] && tLimits2[0][0] <= c1Max
&& c2Min <= tLimits2[1][1] && tLimits2[1][0] <= c2Max,
to1 - offset <= tLimits2[0][1] && tLimits2[0][0] <= to1 + offset
&& to2 - offset <= tLimits2[1][1] && tLimits2[1][0] <= to2 + offset);
SkDebugf("%.*s %s 1 c1Bottom=%1.9g c1Top=%1.9g c2Bottom=%1.9g c2Top=%1.9g"
" 1-o=%1.9g 1+o=%1.9g 2-o=%1.9g 2+o=%1.9g offset=%1.9g\n",
i.depth()*2, tab, __FUNCTION__, c1Bottom, c1Top, 0., 1.,
//.........这里部分代码省略.........
示例5: intersectEnd
// intersect the end of the cubic with the other. Try lines from the end to control and opposite
// end to determine range of t on opposite cubic.
static bool intersectEnd(const Cubic& cubic1, bool start, const Cubic& cubic2, const _Rect& bounds2,
Intersections& i) {
// bool selfIntersect = cubic1 == cubic2;
_Line line;
int t1Index = start ? 0 : 3;
line[0] = cubic1[t1Index];
// don't bother if the two cubics are connnected
#if 0
if (!selfIntersect && (line[0].approximatelyEqual(cubic2[0])
|| line[0].approximatelyEqual(cubic2[3]))) {
return false;
}
#endif
bool result = false;
SkTDArray<double> tVals; // OPTIMIZE: replace with hard-sized array
for (int index = 0; index < 4; ++index) {
if (index == t1Index) {
continue;
}
_Vector dxy1 = cubic1[index] - line[0];
dxy1 /= gPrecisionUnit;
line[1] = line[0] + dxy1;
_Rect lineBounds;
lineBounds.setBounds(line);
if (!bounds2.intersects(lineBounds)) {
continue;
}
Intersections local;
if (!intersect(cubic2, line, local)) {
continue;
}
for (int idx2 = 0; idx2 < local.used(); ++idx2) {
double foundT = local.fT[0][idx2];
if (approximately_less_than_zero(foundT)
|| approximately_greater_than_one(foundT)) {
continue;
}
if (local.fPt[idx2].approximatelyEqual(line[0])) {
if (i.swapped()) { // FIXME: insert should respect swap
i.insert(foundT, start ? 0 : 1, line[0]);
} else {
i.insert(start ? 0 : 1, foundT, line[0]);
}
result = true;
} else {
*tVals.append() = local.fT[0][idx2];
}
}
}
if (tVals.count() == 0) {
return result;
}
QSort<double>(tVals.begin(), tVals.end() - 1);
double tMin1 = start ? 0 : 1 - LINE_FRACTION;
double tMax1 = start ? LINE_FRACTION : 1;
int tIdx = 0;
do {
int tLast = tIdx;
while (tLast + 1 < tVals.count() && roughly_equal(tVals[tLast + 1], tVals[tIdx])) {
++tLast;
}
double tMin2 = SkTMax(tVals[tIdx] - LINE_FRACTION, 0.0);
double tMax2 = SkTMin(tVals[tLast] + LINE_FRACTION, 1.0);
int lastUsed = i.used();
result |= intersect3(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, i);
if (lastUsed == i.used()) {
tMin2 = SkTMax(tVals[tIdx] - (1.0 / gPrecisionUnit), 0.0);
tMax2 = SkTMin(tVals[tLast] + (1.0 / gPrecisionUnit), 1.0);
result |= intersect3(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, i);
}
tIdx = tLast + 1;
} while (tIdx < tVals.count());
return result;
}
示例6: calcPrecision
// this flavor approximates the cubics with quads to find the intersecting ts
// OPTIMIZE: if this strategy proves successful, the quad approximations, or the ts used
// to create the approximations, could be stored in the cubic segment
// FIXME: this strategy needs to intersect the convex hull on either end with the opposite to
// account for inset quadratics that cause the endpoint intersection to avoid detection
// the segments can be very short -- the length of the maximum quadratic error (precision)
// FIXME: this needs to recurse on itself, taking a range of T values and computing the new
// t range ala is linear inner. The range can be figured by taking the dx/dy and determining
// the fraction that matches the precision. That fraction is the change in t for the smaller cubic.
static bool intersect2(const Cubic& cubic1, double t1s, double t1e, const Cubic& cubic2,
double t2s, double t2e, double precisionScale, Intersections& i) {
Cubic c1, c2;
sub_divide(cubic1, t1s, t1e, c1);
sub_divide(cubic2, t2s, t2e, c2);
SkTDArray<double> ts1;
cubic_to_quadratics(c1, calcPrecision(c1) * precisionScale, ts1);
SkTDArray<double> ts2;
cubic_to_quadratics(c2, calcPrecision(c2) * precisionScale, ts2);
double t1Start = t1s;
int ts1Count = ts1.count();
for (int i1 = 0; i1 <= ts1Count; ++i1) {
const double tEnd1 = i1 < ts1Count ? ts1[i1] : 1;
const double t1 = t1s + (t1e - t1s) * tEnd1;
Cubic part1;
sub_divide(cubic1, t1Start, t1, part1);
Quadratic q1;
demote_cubic_to_quad(part1, q1);
// start here;
// should reduceOrder be looser in this use case if quartic is going to blow up on an
// extremely shallow quadratic?
Quadratic s1;
int o1 = reduceOrder(q1, s1);
double t2Start = t2s;
int ts2Count = ts2.count();
for (int i2 = 0; i2 <= ts2Count; ++i2) {
const double tEnd2 = i2 < ts2Count ? ts2[i2] : 1;
const double t2 = t2s + (t2e - t2s) * tEnd2;
Cubic part2;
sub_divide(cubic2, t2Start, t2, part2);
Quadratic q2;
demote_cubic_to_quad(part2, q2);
Quadratic s2;
double o2 = reduceOrder(q2, s2);
Intersections locals;
if (o1 == 3 && o2 == 3) {
intersect2(q1, q2, locals);
} else if (o1 <= 2 && o2 <= 2) {
locals.fUsed = intersect((const _Line&) s1, (const _Line&) s2, locals.fT[0],
locals.fT[1]);
} else if (o1 == 3 && o2 <= 2) {
intersect(q1, (const _Line&) s2, locals);
} else {
SkASSERT(o1 <= 2 && o2 == 3);
intersect(q2, (const _Line&) s1, locals);
for (int s = 0; s < locals.fUsed; ++s) {
SkTSwap(locals.fT[0][s], locals.fT[1][s]);
}
}
for (int tIdx = 0; tIdx < locals.used(); ++tIdx) {
double to1 = t1Start + (t1 - t1Start) * locals.fT[0][tIdx];
double to2 = t2Start + (t2 - t2Start) * locals.fT[1][tIdx];
// if the computed t is not sufficiently precise, iterate
_Point p1, p2;
xy_at_t(cubic1, to1, p1.x, p1.y);
xy_at_t(cubic2, to2, p2.x, p2.y);
if (p1.approximatelyEqual(p2)) {
i.insert(i.swapped() ? to2 : to1, i.swapped() ? to1 : to2);
} else {
double dt1, dt2;
computeDelta(cubic1, to1, (t1e - t1s), cubic2, to2, (t2e - t2s), dt1, dt2);
double scale = precisionScale;
if (dt1 > 0.125 || dt2 > 0.125) {
scale /= 2;
SkDebugf("%s scale=%1.9g\n", __FUNCTION__, scale);
}
#if SK_DEBUG
++debugDepth;
assert(debugDepth < 10);
#endif
i.swap();
intersect2(cubic2, SkTMax(to2 - dt2, 0.), SkTMin(to2 + dt2, 1.),
cubic1, SkTMax(to1 - dt1, 0.), SkTMin(to1 + dt1, 1.), scale, i);
i.swap();
#if SK_DEBUG
--debugDepth;
#endif
}
}
t2Start = t2;
}
t1Start = t1;
}
return i.intersected();
}