void TestSpawnTeleport() { std::cout << "TEST EMPTY\n"; TBoard board(8, 8); TUnit::TSegments segments = { TSegment(Coords::TColRowPoint(0, 0)), TSegment(Coords::TColRowPoint(1, 0)), TSegment(Coords::TColRowPoint(1, 1)), TSegment(Coords::TColRowPoint(2, 1)), }; /* xX */ TUnit unit( TSegment(Coords::TColRowPoint(1, 0)), std::move(segments) ); auto teleported = board.TeleportUnitToSpawnPosition(unit); if (teleported.GetPivot().GetPosition().Column != 4) { throw TException("TestSpawnTeleport error") << __FILE__ << ":" << __LINE__ << " :\n" << teleported.GetPivot().GetPosition().Column << "\n" << "expected: 4" ; } }
unsigned CShuangpinSegmentor::_push (unsigned ch) { int startFrom = 0; bool isInputPy; EShuangpinType shpType; m_pystr.push_back (ch); const int len = m_pystr.size(); if (m_hasInvalid) { startFrom = len - 1; m_segs.push_back (TSegment (ch, startFrom, 1, IPySegmentor::INVALID)); goto RETURN; } shpType = s_shpData.getShuangpinType(); isInputPy = ( islower(ch) || (ch == ';' && (shpType == MS2003 || shpType == ZIGUANG)) ); if (!isInputPy) { startFrom = len - 1; IPySegmentor::ESegmentType seg_type; if (ch == '\'' && m_inputBuf.size() > 1) seg_type = IPySegmentor::SYLLABLE_SEP; else seg_type = IPySegmentor::STRING; m_segs.push_back (TSegment (ch, startFrom, 1, seg_type)); m_nAlpha += 1; m_nLastValidPos += 1; } else { bool bCompleted = !((len - m_nAlpha)%2) && isInputPy; char buf[4]; if (bCompleted) { sprintf(buf, "%c%c", m_pystr[len-2], ch); } else { sprintf(buf, "%c", ch); } startFrom = _encode(buf, ch, bCompleted); if (startFrom < 0) { m_hasInvalid = true; startFrom = m_pystr.size() - 1; m_segs.push_back (TSegment (ch, startFrom, 1, IPySegmentor::INVALID)); } } RETURN:; if (m_pGetFuzzySyllablesOp && m_pGetFuzzySyllablesOp->isEnabled()) if ( m_segs.back().m_type == SYLLABLE) _addFuzzySyllables (m_segs.back ()); return startFrom; }
TSegment TSegment::Slide(EMoveOperations direction) const { Coords::THexPoint hexPos = Coords::ToHex(Position); switch (direction) { case EMoveOperations::SLIDE_EAST: { ++hexPos.X; --hexPos.Z; break; } case EMoveOperations::SLIDE_WEST: { --hexPos.X; ++hexPos.Z; break; } case EMoveOperations::SLIDE_SOUTHEAST: { --hexPos.Z; ++hexPos.Y; break; } case EMoveOperations::SLIDE_SOUTHWEST: { --hexPos.X; ++hexPos.Y; break; } default: { throw TException("Invalid slide operation recieved in ") << __FILE__ << ":" << __LINE__; } } Coords::TColRowPoint newPos = Coords::FromHex(hexPos); return TSegment(newPos); }
int CHunpinSegmentor::_encode(const char* buf,int ret) { CMappedYin syls; syls.reserve(8); s_shpData.getMapString(buf, syls); if (syls.empty()) return -1; CMappedYin::const_iterator iter = syls.begin(); CMappedYin::const_iterator iter_end = syls.end(); m_segs.push_back (TSegment (0, 0, 1, IPySegmentor::SYLLABLE)); TSegment &s = m_segs.back(); s.m_len = 2; s.m_start = ret; s.m_syllables.clear(); s.m_type = IPySegmentor::SYLLABLE; for (; iter!=iter_end; iter++) { s.m_syllables.push_back(s_shpData.encodeSyllable(iter->c_str())); } return s.m_start; }
TSegment TSegment::TeleportBy(const Coords::THexPoint& hexDelta) const { Coords::THexPoint oldHexPos = Coords::ToHex(Position); Coords::THexPoint newHexPos( oldHexPos.X + hexDelta.X, oldHexPos.Y + hexDelta.Y, oldHexPos.Z + hexDelta.Z ); return TSegment(Coords::FromHex(newHexPos)); }
TSegment TSegment::RotateAround( const Coords::TColRowPoint& pivot, EMoveOperations direction ) const { static const auto shiftCoordsLeft = [](const Coords::THexPoint& p) -> Coords::THexPoint { // x y z // -> y z x return Coords::THexPoint(p.Y, p.Z, p.X); }; static const auto shiftCoordsRight = [](const Coords::THexPoint& p) -> Coords::THexPoint { // x y z // -> z x y return Coords::THexPoint(p.Z, p.X, p.Y); }; static const auto invertSigns = [](const Coords::THexPoint& p) -> Coords::THexPoint { return Coords::THexPoint(-1* p.X, -1 * p.Y, -1 * p.Z); }; Coords::THexPoint hexPivot = Coords::ToHex(pivot); Coords::THexPoint hexSelf = Coords::ToHex(Position); Coords::THexPoint hexSelfLocal( hexSelf.X - hexPivot.X, hexSelf.Y - hexPivot.Y, hexSelf.Z - hexPivot.Z ); Coords::THexPoint newHexSelfLocal = hexSelfLocal; switch (direction) { case EMoveOperations::ROTATE_CLOCKWISE: { newHexSelfLocal = invertSigns(shiftCoordsLeft(hexSelfLocal)); break; } case EMoveOperations::ROTATE_ANTI_CLOCKWISE: { newHexSelfLocal = invertSigns(shiftCoordsRight(hexSelfLocal)); break; } default: { throw TException("Invalid rotation operation recieved in ") << __FILE__ << ":" << __LINE__; } } Coords::THexPoint newPosition( hexPivot.X + newHexSelfLocal.X, hexPivot.Y + newHexSelfLocal.Y, hexPivot.Z + newHexSelfLocal.Z ); return TSegment(Coords::FromHex(newPosition)); }
TUnit TUnit::TeleportTo(const Coords::TColRowPoint& newPivotPos) const { Coords::TColRowPoint oldPivotPos = Pivot.GetPosition(); Coords::THexPoint newPivotHexPos = Coords::ToHex(newPivotPos); Coords::THexPoint oldPivotHexPos = Coords::ToHex(oldPivotPos); Coords::THexPoint hexDelta( newPivotHexPos.X - oldPivotHexPos.X, newPivotHexPos.Y - oldPivotHexPos.Y, newPivotHexPos.Z - oldPivotHexPos.Z ); return TUnit(TSegment(newPivotPos), TeleportSegments(hexDelta)); }
TWayGraph::TWays TWayGraph::FindWay( const Coords::TColRowPoint& from, size_t fromDirection, const Coords::TColRowPoint& to, size_t toDirection ) { FinishPoint = TSegment(to); FinishDirection = toDirection; size_t rows = Graph.size(); size_t columns = Graph.front().size(); for (size_t row = 0; row < rows; ++row) { for (size_t column = 0; column < columns; ++column) { for (size_t turn = 0; turn < TurnDirections; ++turn) { auto& node = Graph.at(row).at(column).at(turn); node.Color = EColor::WHITE; } } } Dfs(TSegment(from), fromDirection); return AllWays; }
void CameraTestTool::mouseMove(const TPointD &p, const TMouseEvent &e) { if (m_lastPos.x != -1) // left mouse button is clicked { m_scaling = eNoScale; return; } CleanupParameters *cp = CleanupSettingsModel::instance()->getCurrentParameters(); double pixelSize = getPixelSize(); TPointD size(10 * pixelSize, 10 * pixelSize); TRectD r(cp->m_camera.getStageRect()); TPointD aux(Stage::inch * TPointD(0.5 * cp->m_offx, 0.5 * cp->m_offy)); r -= aux; double maxDist = 5 * pixelSize; if (TRectD(r.getP00() - size, r.getP00() + size).contains(p)) m_scaling = e00; else if (TRectD(r.getP01() - size, r.getP01() + size).contains(p)) m_scaling = e01; else if (TRectD(r.getP11() - size, r.getP11() + size).contains(p)) m_scaling = e11; else if (TRectD(r.getP10() - size, r.getP10() + size).contains(p)) m_scaling = e10; else if (isCloseToSegment(p, TSegment(r.getP00(), r.getP10()), maxDist)) m_scaling = eM0; else if (isCloseToSegment(p, TSegment(r.getP10(), r.getP11()), maxDist)) m_scaling = e1M; else if (isCloseToSegment(p, TSegment(r.getP11(), r.getP01()), maxDist)) m_scaling = eM1; else if (isCloseToSegment(p, TSegment(r.getP01(), r.getP00()), maxDist)) m_scaling = e0M; else m_scaling = eNoScale; }
int leftScanlineIntersections(const TQuadratic &q, double t0, double t1, bool &ascending) { const TPointD &p0 = q.getP0(), &p1 = q.getP1(), &p2 = q.getP2(); double y1_y0 = y(p1) - y(p0), accel = y(p2) - y(p1) - y1_y0; // Fallback to segment case whenever we have too flat quads if (std::fabs(accel) < m_tol) return leftScanlineIntersections(TSegment(q.getPoint(t0), q.getPoint(t1)), ascending); // Calculate new ascension int ascends = isAscending(q, t1, t0 < t1); bool wasAscending = ascending; ascending = (ascends > 0) ? true : (ascends < 0) ? false : (wasAscending = !ascending, ascending); // Couples with the cusps check below // In case the y coords are not in range, quit int solIdx[2]; if (!areInYRange(q, t0, t1, solIdx)) return 0; // Identify coordinates for which q(t) == y double poly[3] = {y(p0) - m_y, 2.0 * y1_y0, accel}, s[2]; int sCount = tcg::poly_ops::solve_2(poly, s); // Tolerance dealt at the first bailout above if (sCount == 2) { // Calculate result int result = 0; if (solIdx[0] >= 0) { result += int(getX(q, s[solIdx[0]]) < m_x && (getY(q, t0) != m_y || ascending == wasAscending)); // Cusp check } if (solIdx[1] >= 0) result += int(getX(q, s[solIdx[1]]) < m_x); return result; } return (assert(sCount == 0), 0); // Should never happen, since m_y is in range. If it ever happens, // it must be close to the extremal - so quit with no intersections. }
int CShuangpinSegmentor::_encode(const char* buf, char ch, bool isComplete) { CMappedYin syls; syls.reserve(8); s_shpData.getMapString(buf, syls); if (syls.empty()) return -1; const int len = m_pystr.size(); CMappedYin::const_iterator iter = syls.begin(); CMappedYin::const_iterator iter_end = syls.end(); if (isComplete) { TSegment &s = m_segs.back(); s.m_len = 2; s.m_start = len - s.m_len; s.m_syllables.clear(); s.m_type = IPySegmentor::SYLLABLE; for (; iter!=iter_end; iter++) { s.m_syllables.push_back(s_shpData.encodeSyllable(iter->c_str())); } m_nLastValidPos += 1; return s.m_start; } else { TSegment s; s.m_len = 1; s.m_start = len - s.m_len; m_nLastValidPos += 1; for (; iter != iter_end; ++iter) { TSyllable syl = s_shpData.encodeSyllable(iter->c_str()); if ((int)syl != 0) { s.m_syllables.push_back(syl); m_segs.push_back (s); } else { m_segs.push_back (TSegment (ch, s.m_start, 1, IPySegmentor::STRING)); } } return s.m_start; } }
int intersect(const TQuadratic &q, const TSegment &s, std::vector<DoublePair> &intersections, bool firstIsQuad) { int solutionNumber = 0; // Note the line `a*x+b*y+c = 0` we search for solutions // di a*x(t)+b*y(t)+c=0 in [0,1] double a = s.getP0().y - s.getP1().y, b = s.getP1().x - s.getP0().x, c = -(a * s.getP0().x + b * s.getP0().y); // se il segmento e' un punto if (0.0 == a && 0.0 == b) { double outParForQuad = q.getT(s.getP0()); if (areAlmostEqual(q.getPoint(outParForQuad), s.getP0())) { if (firstIsQuad) intersections.push_back(DoublePair(outParForQuad, 0)); else intersections.push_back(DoublePair(0, outParForQuad)); return 1; } return 0; } if (q.getP2() - q.getP1() == q.getP1() - q.getP0()) { // the second is a segment.... if (firstIsQuad) return intersect(TSegment(q.getP0(), q.getP2()), s, intersections); else return intersect(s, TSegment(q.getP0(), q.getP2()), intersections); } std::vector<TPointD> bez, pol; bez.push_back(q.getP0()); bez.push_back(q.getP1()); bez.push_back(q.getP2()); bezier2poly(bez, pol); std::vector<double> poly_1(3, 0), sol; poly_1[0] = a * pol[0].x + b * pol[0].y + c; poly_1[1] = a * pol[1].x + b * pol[1].y; poly_1[2] = a * pol[2].x + b * pol[2].y; if (!(rootFinding(poly_1, sol))) return 0; double segmentPar, solution; TPointD v10(s.getP1() - s.getP0()); for (UINT i = 0; i < sol.size(); ++i) { solution = sol[i]; if ((0.0 <= solution && solution <= 1.0) || areAlmostEqual(solution, 0.0, 1e-6) || areAlmostEqual(solution, 1.0, 1e-6)) { segmentPar = (q.getPoint(solution) - s.getP0()) * v10 / (v10 * v10); if ((0.0 <= segmentPar && segmentPar <= 1.0) || areAlmostEqual(segmentPar, 0.0, 1e-6) || areAlmostEqual(segmentPar, 1.0, 1e-6)) { TPointD p1 = q.getPoint(solution); TPointD p2 = s.getPoint(segmentPar); assert(areAlmostEqual(p1, p2, 1e-1)); if (firstIsQuad) intersections.push_back(DoublePair(solution, segmentPar)); else intersections.push_back(DoublePair(segmentPar, solution)); solutionNumber++; } } } return solutionNumber; }
int intersectCloseControlPoints(const TQuadratic &c0, const TQuadratic &c1, std::vector<DoublePair> &intersections) { int ret = -2; double dist1 = tdistance2(c0.getP0(), c0.getP1()); if (dist1 == 0) dist1 = 1e-20; double dist2 = tdistance2(c0.getP1(), c0.getP2()); if (dist2 == 0) dist2 = 1e-20; double val0 = std::max(dist1, dist2) / std::min(dist1, dist2); double dist3 = tdistance2(c1.getP0(), c1.getP1()); if (dist3 == 0) dist3 = 1e-20; double dist4 = tdistance2(c1.getP1(), c1.getP2()); if (dist4 == 0) dist4 = 1e-20; double val1 = std::max(dist3, dist4) / std::min(dist3, dist4); if (val0 > 1000000 && val1 > 1000000) // both c0 and c1 approximated by segments { TSegment s0 = TSegment(c0.getP0(), c0.getP2()); TSegment s1 = TSegment(c1.getP0(), c1.getP2()); ret = intersect(s0, s1, intersections); for (UINT i = intersections.size() - ret; i < (int)intersections.size(); i++) { intersections[i].first = (dist1 < dist2) ? sqrt(intersections[i].first) : 1 - sqrt(1 - intersections[i].first); intersections[i].second = (dist3 < dist4) ? sqrt(intersections[i].second) : 1 - sqrt(1 - intersections[i].second); } // return ret; } else if (val0 > 1000000) // c0 only approximated segment { TSegment s0 = TSegment(c0.getP0(), c0.getP2()); ret = intersect(s0, c1, intersections); for (UINT i = intersections.size() - ret; i < (int)intersections.size(); i++) intersections[i].first = (dist1 < dist2) ? sqrt(intersections[i].first) : 1 - sqrt(1 - intersections[i].first); // return ret; } else if (val1 > 1000000) // only c1 approximated segment { TSegment s1 = TSegment(c1.getP0(), c1.getP2()); ret = intersect(c0, s1, intersections); for (UINT i = intersections.size() - ret; i < (int)intersections.size(); i++) intersections[i].second = (dist3 < dist4) ? sqrt(intersections[i].second) : 1 - sqrt(1 - intersections[i].second); // return ret; } /* if (ret!=-2) { std::vector<DoublePair> intersections1; int ret1 = intersect(c0, c1, intersections1, false); if (ret1>ret) { intersections = intersections1; return ret1; } } */ return ret; }
int intersect(const TQuadratic &c0, const TQuadratic &c1, std::vector<DoublePair> &intersections, bool checksegments) { int ret; // Works baddly, sometimes patch intersections... if (checksegments) { ret = intersectCloseControlPoints(c0, c1, intersections); if (ret != -2) return ret; } double a = c0.getP0().x - 2 * c0.getP1().x + c0.getP2().x; double b = 2 * (c0.getP1().x - c0.getP0().x); double d = c0.getP0().y - 2 * c0.getP1().y + c0.getP2().y; double e = 2 * (c0.getP1().y - c0.getP0().y); double coeff = b * d - a * e; int i = 0; if (areAlmostEqual(coeff, 0.0)) // c0 is a Segment, or a single point!!! { TSegment s = TSegment(c0.getP0(), c0.getP2()); ret = intersect(s, c1, intersections); if (a == 0 && d == 0) // values of t in s coincide with values of t in c0 return ret; for (i = intersections.size() - ret; i < (int)intersections.size(); i++) { intersections[i].first = c0.getT(s.getPoint(intersections[i].first)); } return ret; } double c = c0.getP0().x; double f = c0.getP0().y; double g = c1.getP0().x - 2 * c1.getP1().x + c1.getP2().x; double h = 2 * (c1.getP1().x - c1.getP0().x); double k = c1.getP0().x; double m = c1.getP0().y - 2 * c1.getP1().y + c1.getP2().y; double p = 2 * (c1.getP1().y - c1.getP0().y); double q = c1.getP0().y; if (areAlmostEqual(h * m - g * p, 0.0)) // c1 is a Segment, or a single point!!! { TSegment s = TSegment(c1.getP0(), c1.getP2()); ret = intersect(c0, s, intersections); if (g == 0 && m == 0) // values of t in s coincide with values of t in c0 return ret; for (i = intersections.size() - ret; i < (int)intersections.size(); i++) { intersections[i].second = c1.getT(s.getPoint(intersections[i].second)); } return ret; } double a2 = (g * d - a * m); double b2 = (h * d - a * p); double c2 = ((k - c) * d + (f - q) * a); coeff = 1.0 / coeff; double A = (a * a + d * d) * coeff * coeff; double aux = A * c2 + (a * b + d * e) * coeff; std::vector<double> t; std::vector<double> solutions; t.push_back(aux * c2 + a * c + d * f - k * a - d * q); aux += A * c2; t.push_back(aux * b2 - h * a - d * p); t.push_back(aux * a2 + A * b2 * b2 - g * a - d * m); t.push_back(2 * A * a2 * b2); t.push_back(A * a2 * a2); rootFinding(t, solutions); // solutions.push_back(0.0); //per convenzione; un valore vale l'altro.... for (i = 0; i < (int)solutions.size(); i++) { if (solutions[i] < 0) { if (areAlmostEqual(solutions[i], 0, 1e-6)) solutions[i] = 0; else continue; } else if (solutions[i] > 1) { if (areAlmostEqual(solutions[i], 1, 1e-6)) solutions[i] = 1; else continue; } DoublePair tt; tt.second = solutions[i]; tt.first = coeff * (tt.second * (a2 * tt.second + b2) + c2); if (tt.first < 0) { if (areAlmostEqual(tt.first, 0, 1e-6)) tt.first = 0; else continue; } else if (tt.first > 1) { if (areAlmostEqual(tt.first, 1, 1e-6)) tt.first = 1; else continue; } intersections.push_back(tt); assert(areAlmostEqual(c0.getPoint(tt.first), c1.getPoint(tt.second), 1e-1)); } return intersections.size(); }
int TRegion::Imp::leftScanlineIntersections( const TPointD &p, double(TPointD::*h), double(TPointD::*v)) const { struct Locals { const Imp *m_this; double m_x, m_y, m_tol; double TPointD::*m_h, TPointD::*m_v; inline double x(const TPointD &p) const { return p.*m_h; } inline double y(const TPointD &p) const { return p.*m_v; } inline double get(const TQuadratic &q, double t, double(TPointD::*val)) const { double one_t = 1.0 - t; return one_t * (one_t * q.getP0().*val + t * q.getP1().*val) + t * (one_t * q.getP1().*val + t * q.getP2().*val); } inline double getX(const TQuadratic &q, double t) const { return get(q, t, m_h); } inline double getY(const TQuadratic &q, double t) const { return get(q, t, m_v); } void getEdgeData(int e, TEdge *&ed, TStroke *&s, int &chunk0, const TThickQuadratic *&q0, double &t0, int &chunk1, const TThickQuadratic *&q1, double &t1) const { ed = m_this->m_edge[e]; s = ed->m_s; s->getChunkAndT(ed->m_w0, chunk0, t0); s->getChunkAndT(ed->m_w1, chunk1, t1); q0 = s->getChunk(chunk0); q1 = s->getChunk(chunk1); } bool isInYRange(double y0, double y1) const { return (y0 <= m_y && m_y < y1) // Assuming the first endpoint is vertical-including, || (y1 < m_y && m_y <= y0); // while the latter is not. Vertical conditions are EXACT. } bool areInYRange(const TQuadratic &q, double t0, double t1, int(&solIdx)[2]) const { assert(0.0 <= t0 && t0 <= 1.0), assert(0.0 <= t1 && t1 <= 1.0); const TPointD &p0 = q.getP0(), &p1 = q.getP1(), &p2 = q.getP2(); double der[2] = {y(p1) - y(p0), y(p0) - y(p1) + y(p2) - y(p1)}, s; double y0 = getY(q, t0), y1 = getY(q, t1); if (tcg::poly_ops::solve_1(der, &s, m_tol)) { if (t0 <= s && s < t1) { double ys = getY(q, s); solIdx[0] = (ys < m_y && m_y <= y0 || y0 <= m_y && m_y < ys) ? 0 : -1; solIdx[1] = (ys < m_y && m_y < y1 || y1 < m_y && m_y < ys) ? 1 : -1; } else if (t1 < s && s <= t0) { double ys = getY(q, s); solIdx[0] = (ys < m_y && m_y <= y0 || y0 <= m_y && m_y < ys) ? 1 : -1; solIdx[1] = (ys < m_y && m_y < y1 || y1 < m_y && m_y < ys) ? 0 : -1; } else { solIdx[0] = isInYRange(y0, y1) ? (t0 < s) ? 0 : 1 : -1; solIdx[1] = -1; } } else solIdx[1] = solIdx[0] = -1; return (solIdx[0] >= 0 || solIdx[1] >= 0); } int leftScanlineIntersections(const TSegment &seg, bool &ascending) { const TPointD &p0 = seg.getP0(), &p1 = seg.getP1(); bool wasAscending = ascending; ascending = (y(p1) > y(p0)) ? true : (y(p1) < y(p0)) ? false : (wasAscending = !ascending, ascending); // Couples with the cusp check below if (!isInYRange(y(p0), y(p1))) return 0; if (m_y == y(p0)) return int(x(p0) < m_x && ascending == wasAscending); // Cusps treated here double y1_y0 = y(p1) - y(p0), // (x, m_y) in (p0, p1) from here on poly[2] = {(m_y - y(p0)) * (x(p1) - x(p0)), -y1_y0}, sx_x0; return tcg::poly_ops::solve_1(poly, &sx_x0, m_tol) ? int(sx_x0 < m_x - x(p0)) : int(x(p0) < m_x && x(p1) < m_x); // Almost horizontal segments are } // flattened along the axes int isAscending(const TThickQuadratic &q, double t, bool forward) { double y0 = y(q.getP0()), y1 = y(q.getP1()), y2 = y(q.getP2()), y1_y0 = y1 - y0, y2_y1 = y2 - y1; double yspeed_2 = tcg::numeric_ops::lerp(y1_y0, y2_y1, t) * (2 * int(forward) - 1), yaccel = y2_y1 - y1_y0; return (yspeed_2 > 0.0) ? 1 : (yspeed_2 < 0.0) ? -1 : tcg::numeric_ops::sign(yaccel); } int leftScanlineIntersections(const TQuadratic &q, double t0, double t1, bool &ascending) { const TPointD &p0 = q.getP0(), &p1 = q.getP1(), &p2 = q.getP2(); double y1_y0 = y(p1) - y(p0), accel = y(p2) - y(p1) - y1_y0; // Fallback to segment case whenever we have too flat quads if (std::fabs(accel) < m_tol) return leftScanlineIntersections(TSegment(q.getPoint(t0), q.getPoint(t1)), ascending); // Calculate new ascension int ascends = isAscending(q, t1, t0 < t1); bool wasAscending = ascending; ascending = (ascends > 0) ? true : (ascends < 0) ? false : (wasAscending = !ascending, ascending); // Couples with the cusps check below // In case the y coords are not in range, quit int solIdx[2]; if (!areInYRange(q, t0, t1, solIdx)) return 0; // Identify coordinates for which q(t) == y double poly[3] = {y(p0) - m_y, 2.0 * y1_y0, accel}, s[2]; int sCount = tcg::poly_ops::solve_2(poly, s); // Tolerance dealt at the first bailout above if (sCount == 2) { // Calculate result int result = 0; if (solIdx[0] >= 0) { result += int(getX(q, s[solIdx[0]]) < m_x && (getY(q, t0) != m_y || ascending == wasAscending)); // Cusp check } if (solIdx[1] >= 0) result += int(getX(q, s[solIdx[1]]) < m_x); return result; } return (assert(sCount == 0), 0); // Should never happen, since m_y is in range. If it ever happens, // it must be close to the extremal - so quit with no intersections. } } locals = {this, p.*h, p.*v, 1e-4, h, v}; TEdge *ed; TStroke *s; int chunk0, chunk1; const TThickQuadratic *q0, *q1; double t0, t1; UINT e, eCount = m_edge.size(); int leftInters = 0; bool ascending = (locals.getEdgeData(eCount - 1, ed, s, chunk0, q0, t0, chunk1, q1, t1), locals.isAscending(*q1, t1, (t0 < t1))); for (e = 0; e != eCount; ++e) { // Explore current edge { // Retrieve edge data locals.getEdgeData(e, ed, s, chunk0, q0, t0, chunk1, q1, t1); // Compare edge against scanline segment if (chunk0 != chunk1) { if (chunk0 < chunk1) { leftInters += locals.leftScanlineIntersections(*q0, t0, 1.0, ascending); for (int c = chunk0 + 1; c != chunk1; ++c) leftInters += locals.leftScanlineIntersections(*s->getChunk(c), 0.0, 1.0, ascending); leftInters += locals.leftScanlineIntersections(*q1, 0.0, t1, ascending); } else { leftInters += locals.leftScanlineIntersections(*q0, t0, 0.0, ascending); for (int c = chunk0 - 1; c != chunk1; --c) leftInters += locals.leftScanlineIntersections(*s->getChunk(c), 1.0, 0.0, ascending); leftInters += locals.leftScanlineIntersections(*q1, 1.0, t1, ascending); } } else leftInters += locals.leftScanlineIntersections(*q0, t0, t1, ascending); } // Explore autoclose segment at the end of current edge { int nextE = (e + 1) % int(m_edge.size()); const TPointD &p0 = m_edge[e]->m_s->getPoint(m_edge[e]->m_w1), &p1 = m_edge[nextE]->m_s->getPoint(m_edge[nextE]->m_w0); leftInters += locals.leftScanlineIntersections(TSegment(p0, p1), ascending); } } return leftInters; }
// TOTEST unsigned CHunpinSegmentor::_push (unsigned ch) { m_pystr.push_back (ch); TSegmentVec::iterator ite = m_segs.size() > 0 ? m_segs.end() - 1 : m_segs.begin() - 1; const unsigned maxStringCount = 6; unsigned syllableCount = 0; unsigned stringCount = 0; for(; ite != m_segs.begin() - 1 ; ite --) { stringCount += (*ite).m_len; syllableCount ++; if (stringCount > maxStringCount) { syllableCount --; break; } } unsigned strlen = m_pystr.size(); unsigned ret; for(int index = syllableCount ; index >= 0; index --) { TSegmentVec::iterator it = m_segs.end() - index; unsigned tmpl; unsigned v; if(index != 0) { if((strlen - (*it).m_start) == 2) { char buf[4]; sprintf(buf, "%c%c", m_pystr[(*it).m_start], m_pystr[(*it).m_start+1]); int startFrom = _encode(buf); if(startFrom >= 0) break; } v = m_pytrie.match_longest (m_pystr.rbegin(), m_pystr.rbegin() + strlen - (*it).m_start, tmpl); if(tmpl == (strlen - (*it).m_start)) { TSegmentVec new_segs(1, TSegment(v, (*it).m_start, tmpl)); m_segs.erase (m_segs.end()-index, m_segs.end()); std::copy (new_segs.rbegin(), new_segs.rend(), back_inserter (m_segs)); break; } } else { v = m_pytrie.match_longest (m_pystr.rbegin(), m_pystr.rbegin() + 1, tmpl); if(tmpl == 0) { IPySegmentor::ESegmentType seg_type; if (ch == '\'' && m_inputBuf.size() > 1) { seg_type = IPySegmentor::SYLLABLE_SEP; } else if (islower (ch)) { seg_type = IPySegmentor::INVALID; } else { seg_type = IPySegmentor::STRING; } ret = m_pystr.size () - 1; m_segs.push_back (TSegment (ch, ret, 1, seg_type)); } else { ret = m_pystr.size () - 1; m_segs.push_back (TSegment (v, ret, 1)); } } } TSegment &last_seg = m_segs.back(); if (m_pGetFuzzySyllablesOp && m_pGetFuzzySyllablesOp->isEnabled()) if ( m_segs.back().m_type == SYLLABLE) _addFuzzySyllables (last_seg); return last_seg.m_start; }