TEST(Segment, Intersection_Segment_parallel){ vector<Point> ans; vector<Point> res = Segment(1,3,3,5).intersection(Segment(2,1,4,3)); ASSERT_EQ(ans, res); };

Router::Router(const Signature& signature, const std::unordered_map<std::string, float>& language) : m_carrier(*signature.carrier()), m_language(language), m_value_index(signature.carrier()->item_count()) { POMAGMA_INFO("Building router indices"); for (auto pair : signature.nullary_functions()) { const auto& name = pair.first; const auto& fun = *pair.second; if (m_language.find(name) != m_language.end()) { const TypeId type = new_type(NULLARY, name); if (Ob val = fun.find()) { m_segments.push_back(Segment(type, val)); } } } for (auto pair : signature.injective_functions()) { const auto& name = pair.first; const auto& fun = *pair.second; if (m_language.find(name) != m_language.end()) { const TypeId type = new_type(UNARY, name); for (auto iter = fun.iter(); iter.ok(); iter.next()) { Ob arg = *iter; Ob val = fun.find(arg); m_segments.push_back(Segment(type, val, arg)); } } } for (auto pair : signature.binary_functions()) { const auto& name = pair.first; const auto& fun = *pair.second; if (m_language.find(name) != m_language.end()) { const TypeId type = new_type(BINARY, name); for (auto iter = m_carrier.iter(); iter.ok(); iter.next()) { Ob lhs = *iter; for (auto iter = fun.iter_lhs(lhs); iter.ok(); iter.next()) { Ob rhs = *iter; Ob val = fun.find(lhs, rhs); m_segments.push_back(Segment(type, val, lhs, rhs)); } } } } for (auto pair : signature.symmetric_functions()) { const auto& name = pair.first; const auto& fun = *pair.second; if (m_language.find(name) != m_language.end()) { const TypeId type = new_type(BINARY, name); for (auto iter = m_carrier.iter(); iter.ok(); iter.next()) { Ob lhs = *iter; for (auto iter = fun.iter_lhs(lhs); iter.ok(); iter.next()) { Ob rhs = *iter; Ob val = fun.find(lhs, rhs); m_segments.push_back(Segment(type, val, lhs, rhs)); } } } } std::sort(m_segments.begin(), m_segments.end()); // assume all values are reached by at least one segment m_value_index.resize(1 + m_carrier.item_count(), 0); for (size_t i = 0; i < m_segments.size(); ++i) { m_value_index[m_segments[i].val] = i; } }

int main(int argc, char** argv) { srand(time(NULL)); // init rand; #if PORTAL Portal p(Segment(10, 40, 10, 20), Segment(40, 10, 20, 10)); std::vector<Segment> lines(p.deviateLine(Segment(20, 40, 0, 30))); for (const Segment& line: lines) std::cerr << line << std::endl; #endif #if Thumbnail QApplication app(argc, argv); PolygonList polygonList; //polygonList << poc::Polygon(30, 250, 21, 260, 5); poc::Polygon polygon; polygon << Point2d(55, 55) << Point2d(455, 55) << Point2d(455, 455) << Point2d(155, 455) << Point2d(155, 255) << Point2d(255, 255) << Point2d(255, 355) << Point2d(355, 355) << Point2d(355, 155) << Point2d(55, 155); polygonList << polygon; qDebug() << polygonList; ThumbnailCreator thumbnailCreator(polygonList); QImage thumbnail = thumbnailCreator.makeThumbnail(); QLabel* label = new QLabel; label->setPixmap(QPixmap::fromImage(thumbnail)); label->show(); return app.exec(); #endif #if TESTPOINT Test::test<< Point2d(); #endif #if TESTVECTOR Test::testVector2d(); #endif #if TESTPOLYGON Test::testPolygon(); #endif #if GUI QApplication app(argc, argv); // QFontDatabase::addApplicationFont("../PieceOfCake/fonts/edosz.ttf"); // QFontDatabase::addApplicationFont("../PieceOfCake/fonts/watermark.ttf"); qmlRegisterType<GameInfo>("gameinfo", 1, 0, "GameInfo"); qmlRegisterType<LevelInfo>("levelinfo", 1, 0, "LevelInfo"); MainWindow window; window.show(); return app.exec(); #endif #if QML QGuiApplication app(argc, argv); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); return app.exec(); #endif #if GNUPLOT // poc::Polygon polygon; // polygon << << Point2d() << << Point2d(0, 1) << << Point2d(1, 1) << << Point2d(1); poc::Polygon polygon(0, 100, 0, 100, 7); // std::vector<Point2d> vertices = polygon.getVertices(); // for (unsigned int k = 0; k < vertices.size(); ++k) // std::cerr << vertices.at(k).getX() << " " << vertices.at(k).getY() << " " << -10 << std::endl; float size = 300; float delta = 10; int max = size/delta; float** matrix = polygon.surface(size, delta); for (int i = 0; i < max; ++i) { for (int j = 0; j < max; ++j) { std::cerr << i << " " << j << " " << matrix[i][j] << std::endl; } delete[] matrix[i]; } delete[] matrix; #endif #if XML Test::testXML(); #else return EXIT_SUCCESS; #endif }

void Canvas::DrawSegment(int x, int y, unsigned radius, Angle start, Angle end, bool horizon) { Segment(*this, x, y, radius, start, end, horizon); }

// // THIS FUNCTION IS THREAD SAFE, but not using optimized clipping // void MapWindow::DrawTaskPicto(HDC hdc,int TaskIdx, RECT rc, double fScaleFact) { int center_x = (rc.right-rc.left)/2; int center_y = (rc.bottom-rc.top)/2; int SecType = SectorType; int width = center_x-2; HPEN oldpen = 0; HBRUSH oldbrush = 0; if(AATEnabled) oldbrush = (HBRUSH) SelectObject(hdc, LKBrush_LightGrey); else oldbrush = (HBRUSH) SelectObject(hdc, GetStockObject(HOLLOW_BRUSH)); oldpen = (HPEN) SelectObject(hdc, hpStartFinishThick); int finish=0; while( ValidTaskPoint(finish)) finish++; finish--; if(center_y < width) width = center_y-2; POINT startfinishline[2] = {{0,-width/ScreenScale}, {0,width/ScreenScale}}; POINT track[3] = {{0,-width/5/ScreenScale}, {width/2/ScreenScale,0}, {0,width/5/ScreenScale}}; if(TaskIdx == finish) { track[0].x = -width/2/ScreenScale; track[0].y= -width/5/ScreenScale; track[1].x = 0 ; track[1].y= 0; track[2].x = -width/2/ScreenScale ; track[2].y= width/5/ScreenScale; } LockTaskData(); // protect from external task changes double StartRadial = Task[TaskIdx].AATStartRadial; double FinishRadial = Task[TaskIdx].AATFinishRadial; if(TaskIdx==0) { FinishRadial = Task[TaskIdx].AATStartRadial; StartRadial = Task[TaskIdx].AATFinishRadial; } double LineBrg; double SecRadius; GetTaskSectorParameter( TaskIdx, &SecType,&SecRadius); switch (SecType) { case CIRCLE: CircleNoCliping(hdc, center_x, center_y, width-2, rc, true); break; case SECTOR: Segment(hdc, center_x, center_y, width, rc, StartRadial, FinishRadial); break; case DAe: if (!AATEnabled) { // this Type exist only if not AAT task // JMW added german rules CircleNoCliping(hdc, center_x, center_y, width/8, rc, true); Segment(hdc, center_x, center_y, width, rc, StartRadial, FinishRadial); } break; default: case LINE: if (TaskIdx == 0) { LineBrg = Task[TaskIdx].OutBound-90; } else if (TaskIdx == finish) { LineBrg = Task[TaskIdx].InBound-90; } else { LineBrg = Task[TaskIdx].Bisector; } threadsafePolygonRotateShift(startfinishline, 2, center_x, center_y, LineBrg); Polygon(hdc, startfinishline, 2); if ((TaskIdx == 0) || (TaskIdx == finish)) { threadsafePolygonRotateShift(track, 3, center_x, center_y, LineBrg); Polygon(hdc, track, 3); } break; case CONE: if (DoOptimizeRoute()) { int radius = width-2; CircleNoCliping(hdc, center_x, center_y, radius, rc, true); HPEN prevPen = (HPEN)::SelectObject(hdc, hpTerrainLine); for( int i = 1; i < 4 && radius > (width/5); ++i) { CircleNoCliping(hdc, center_x, center_y, radius -= width/5, rc, true); } ::SelectObject(hdc, prevPen); } break; } UnlockTaskData(); SelectObject(hdc, oldpen); SelectObject(hdc, oldbrush); }

void operator() (Drawable & drawable) { if (!drawable.GetDrawEnable()) return; assert(drawable.GetVertArray()); const VertexArray & va = *drawable.GetVertArray(); const VertexFormat::Enum vf = va.GetVertexFormat(); const unsigned int vsize = VertexFormat::Get(vf).stride / sizeof(float); const unsigned int vcount = va.GetNumVertices(); const unsigned int icount = va.GetNumIndices(); // FIXME: text drawables can contain empty vertex arrays, // they should be culled before getting here if (vcount == 0) { // reset segment as we might miss text drawable vcount change // happens with Tracks/Cars scroll onfocus tooltip update // need to investigate this if (drawable.GetVertexBufferSegment().age) drawable.SetVertexBufferSegment(Segment()); return; } // get dynamic vertex data object (first object in the vector) const unsigned int obindex = 0; assert(!ctx.objects[vf].empty()); Object & ob = ctx.objects[vf][obindex]; // gen object buffers if (ob.vbuffer == 0) { glGenBuffers(1, &ob.ibuffer); glGenBuffers(1, &ob.vbuffer); if (ctx.use_vao) { glGenVertexArrays(1, &ob.varray); if (ob.varray == 0) ctx.use_vao = ctx.good_vao = false; } ob.vformat = vf; } // set segment Segment sg; sg.ioffset = ob.icount * sizeof(unsigned int); sg.icount = icount; sg.voffset = ob.vcount; sg.vcount = vcount; sg.vbuffer = ob.varray ? ob.varray : ob.vbuffer; sg.vformat = vf; sg.object = obindex; sg.age = ctx.age_dynamic; drawable.SetVertexBufferSegment(sg); // upload data into staging buffers std::vector<unsigned int> & index_buffer = ctx.staging_index_buffer[vf]; std::vector<float> & vertex_buffer = ctx.staging_vertex_buffer[vf]; const unsigned int ibn = (ob.icount + icount); const unsigned int vbn = (ob.vcount + vcount) * vsize; if (index_buffer.size() < ibn) { const unsigned int ibmin = min_dynamic_index_buffer_size / sizeof(unsigned int); index_buffer.resize(std::max(ibn, ibmin)); } if (vertex_buffer.size() < vbn) { const unsigned int vbmin = min_dynamic_vertex_buffer_size / sizeof(float); vertex_buffer.resize(std::max(vbn, vbmin)); } ob.icount = WriteIndices(va, ob.icount, ob.vcount, index_buffer); ob.vcount = WriteVertices(va, ob.vcount, vsize, vertex_buffer); }

LPP* MorpionLPP::getLPP() { setComment(gameId()); // each possible move is a structural variable // our goal is to maximize sum over all variables for (const Move& m: b.getMoveList()) { std::string v_name = to_string(m); setVariableBounds(v_name, 0.0, 1.0); getObjective().push_back(std::pair<std::string, double>(v_name, 1.0)); // Constraint for exact problems. // // mv_ variables are either 0 or 1 (i.e. the move is either played or not) if (getFlag("exact") || getFlag("binary_moves")) { setVariableBoolean(v_name, true); } } // each segment gives us constraints: // (1) if the segment is placed in the starting position // (a) sum of weights of moves that place this segment <= 0 // (b) 1 - sum of weights of moves that remove this segment >= 0 // i.e. sum of weights of moves that remove this segment <= 1 // (2) if the segment is not placed in the starting position // (a) sum of weights of moves that place this segment <= 1 // (b) sum of weights of moves that place this segment // - sum of weights of moves that remove this segment >= 0 for (const Segment& s: b.getSegmentList()) { int x = s.first.x; int y = s.first.y; int d = s.second; std::string constr_name = "segment_" + to_string(x) + "_" + to_string(y) + "_" + to_string(d); if (b.hasDot(Dot(x,y))) { // (1a) { Constraint constr; for (Move& pl: b.getMovesPlacingSegment(s)) { constr.addVariable(to_string(pl), 1.0); } constr.setName("r1a_" + constr_name); constr.setType(Constraint::LT); constr.setBound(0.0); addConstraint(constr); } // (1b) { Constraint constr; for (Move& rm: b.getMovesRemovingSegment(s)) { constr.addVariable(to_string(rm), 1.0); } constr.setName("r1b_" + constr_name); constr.setType(Constraint::LT); constr.setBound(1.0); addConstraint(constr); } } else { // (2a) { Constraint constr; for (Move& pl: b.getMovesPlacingSegment(s)) { constr.addVariable(to_string(pl), 1.0); } constr.setName("r2a_" + constr_name); constr.setType(Constraint::LT); constr.setBound(1.0); addConstraint(constr); } // (2b) { Constraint constr; for (Move& pl: b.getMovesPlacingSegment(s)) { constr.addVariable(to_string(pl), 1.0); } for (Move& rm: b.getMovesRemovingSegment(s)) { constr.addVariable(to_string(rm), -1.0); } constr.setName("r2b_" + constr_name); constr.setType(Constraint::GT); constr.setBound(0.0); addConstraint(constr); } } } // EXTRA CONSTRAINTS: // // for each move m: // for each dot d required by m: // for each move n placing d that is consistent with m: // weight_m <= sum of weights of n's if (getFlag("extra")) { for (const Move& m: b.getMoveList()) { std::string constr_name = "_" + to_string(m); for (const Dot& d: m.requiredDots(b.getVariant())) { if (b.hasDot(d)) continue; Constraint constr; for (const Move& n: b.getMovesPlacingSegment(Segment(d,0))) { if (m.consistentWith(n,b.getVariant())) { constr.addVariable(to_string(n), -1.0); } } constr.addVariable(to_string(m), 1.0); constr.setName("extra_" + to_string(d) + constr_name); constr.setType(Constraint::LT); constr.setBound(0.0); addConstraint(constr); } } } // Disallow cycles of length 3 from the solution. // Improves fuzzy solutions if (getFlag("short-cycles")) { for (const Segment& s: b.getSegmentList()) { int d = s.second; if (d % 2 == 1) continue; addConstraints(createCycleConstraints(s, d + 2, d + 5)); addConstraints(createCycleConstraints(s, d + 6, d + 1)); } } // Constraints for acyclic problems (explanation makes sense for exact problems): // // OBSOLETE // // 1. Each move mv_* has accompanying order variable order_* // 2. Move that is not picked has always order 0, // move that is picked has order between 1 and 675 // // It is accomplished with the condition: // mv_ <= order_ <= 675 * mv_ // // 3. Assume that mv_1 removes segment s and mv_2 places segment s (mv_1 != mv_2). // Then // order_1 + (1 - mv_1) * 1000 >= order_2 + 1 // // The (1-mv_1)*1000 term assures that the condition is not enforced // for moves that are not picked (i.e. have mv_1 = 0) if (getFlag("acyclic")) { throw std::string("not implemented"); } // Constraints for symmetric problems. // // Moves that are symmetric by central symmetry // with center at ref + (1.5,1.5) have to have equal weights if (getFlag("symmetric")) { for (const Move&m: b.getMoveList()) { Move sm = b.centerSymmetry(m); Constraint c; c.addVariable(to_string(m), 1.0); c.addVariable(to_string(sm), -1.0); c.setType(Constraint::EQ); c.setBound(0.0); c.setName("sym_" + to_string(m)); addConstraint(c); } } // dot-acyclic - better implementation of acyclic problems // dots that are not placed have dot_ variable equal to 0 // this is important for --hull option // use this not only for dot-acyclic problems for (const Dot& d: b.getDotList()) { if (b.hasDot(d)) continue; Constraint c; c.setName("dotmove_" + to_string(d)); c.addVariable("dot_" + to_string(d), 1.0); for (const Move& m: b.getMovesPlacingDot(d)) { c.addVariable(to_string(m), -b.bound()); } c.setType(Constraint::LT); c.setBound(0.0); addConstraint(c); } if (getFlag("dot-acyclic")) { for (int x = 0; x < b.getWidth(); x++) { for (int y= 0; y < b.getHeight(); y++) { if (b.infeasibleDot(Dot(x,y)) || b.hasDot(Dot(x,y))) continue; setVariableBounds("dot_" + to_string(Dot(x,y)), 0, b.bound()); if (getFlag("symmetric")) { Constraint c; if (b.infeasibleDot(b.centerSymmetry(Dot(x,y)))) continue; c.setName("dotsym_"); c.addVariable("dot_" + to_string(Dot(x,y)), 1.0); c.addVariable("dot_" + to_string(b.centerSymmetry(Dot(x,y))), -1.0); c.setType(Constraint::EQ); c.setBound(0.0); addConstraint(c); } } } for (const Move& m: b.getMoveList()) { for (const Dot& rq: m.requiredDots(b.getVariant())) { if (b.hasDot(rq)) continue; Constraint c; // dot_placed >= dot_required + 1 - (1 - m) * bound // i.e. dot_placed - dot_required - bound * m >= 1 - bound c.setName("dot_"); c.addVariable("dot_" + to_string(m.placedDot()), 1.0); c.addVariable("dot_" + to_string(rq), -1.0); c.addVariable(to_string(m), -b.bound()); c.setBound(1 - b.bound()); c.setType(Constraint::GT); addConstraint(c); } } } // Constraints that enforce that the board (if it is rectangle) is // the convex hull of the solution if (getFlag("rhull")) { // right side addConstraint(getSideConstraint(1,0,true)); // left side addConstraint(getSideConstraint(1,0,false)); // top side addConstraint(getSideConstraint(0,1,true)); // bottom side addConstraint(getSideConstraint(0,1,false)); } // Constraints that enforce that the board (if it is octagon) is // the convex hull of the solution if (getFlag("hull")) { // right side addConstraint(getSideConstraint(1,0,true)); // left side addConstraint(getSideConstraint(1,0,false)); // lower right side addConstraint(getSideConstraint(1,-1,false)); // upper left side addConstraint(getSideConstraint(1,-1,true)); // top side addConstraint(getSideConstraint(0,1,true)); // bottom side addConstraint(getSideConstraint(0,1,false)); // lower left side addConstraint(getSideConstraint(1,1,false)); // upper right side addConstraint(getSideConstraint(1,1,true)); } return this; }

/*GetALine follow squares intersecting the segment sg, until it reaches : -the border of the board, -an obstacle or -a square that insects the segment only one time (the segment can't go beyond it to neigbooring squares) */ void SquareLine::GetALine() { vector2d l_cornerspos[4]; //corners of a square board->GetSquareCornersInLogPx(s_cur,l_cornerspos); Segment sg2; int i,intersection_value ; vector2d ipoint; //foreach segment in the square, see intersection; for(i=0; i<4; i++) { if(i+1 == 4) sg2=Segment(l_cornerspos[i],l_cornerspos[0]); else sg2=Segment(l_cornerspos[i],l_cornerspos[i+1]); intersection_value = lines_intersect(sg,sg2, ipoint); ipoint.setint(); if(intersection_value == 1 && ! (ipoint== p_lastipoint) ) { if( ipoint == l_cornerspos[i] || ipoint == l_cornerspos[i+1]) { vector2d g = sg.p1-ipoint; Square s; if(g.x>0) { if(g.y>0) { s=s_cur+vector2d(1,0); if(board->GetContentAt(s) == e_obstacle) { s=s_cur+vector2d(0,1); if(board->GetContentAt(s) == e_obstacle) { return; } else { pl_squares->push_back(s); } } else { pl_squares->push_back(s); } s_cur=s_cur+vector2d(1,1); } else if(g.y<0) { s=s_cur+vector2d(1,0); if(board->GetContentAt(s) == e_obstacle) { s=s_cur+vector2d(0,-1); if(board->GetContentAt(s) == e_obstacle) { return; } else { pl_squares->push_back(s); } } else { pl_squares->push_back(s); } s_cur=s_cur+vector2d(1,-1); } else assert(0); //this means that the line coincides with the x-axis. and this is not possible since the destination point is a square center. } else if(g.x<0) { if(g.y>0) { s=s_cur+vector2d(-1,0); if(board->GetContentAt(s) == e_obstacle) { s=s_cur+vector2d(0,1); if(board->GetContentAt(s) == e_obstacle) { return; } else { pl_squares->push_back(s); } } else { pl_squares->push_back(s); } s_cur=s_cur+vector2d(-1,1); } else if(g.y<0) { s=s_cur+vector2d(-1,0); if(board->GetContentAt(s) == e_obstacle) { s=s_cur+vector2d(0,-1); if(board->GetContentAt(s) == e_obstacle) { return; } else { pl_squares->push_back(s); } } else { pl_squares->push_back(s); } s_cur=s_cur+vector2d(-1,-1); } else assert(0); //this means that the line coincides with the x-axis. and this is not possible since the destination point is a square center. } else assert(0); //this means that the line coincides with the y-axis. and this is not possible since the destination point is a square center. } else if(i==0) { s_cur=s_cur+vector2d(0,-1); } else if(i==1) { s_cur=s_cur+vector2d(1,0); } else if(i==2) { s_cur=s_cur+vector2d(0,1); } else { s_cur=s_cur+vector2d(-1,0); } p_lastipoint=ipoint; break; } } if(!NotOutOfBoard(s_cur) || board->GetContentAt(s_cur) == e_obstacle) { return; } if(i==4) {//when i == 4, it's the last square touched by the segment sg. return; } pl_squares->push_back(s_cur); GetALine(); }

//gets the square next to s_from, in the direction of s_to. //used by FindARefuge to have a square next to an obstacle. Square SquareLine::GetAdjacentSquareTowards(Square s_from, Square s_to, Board * board) { vector2d l_cornerspos[4]; //corners of a square Square s_ret=s_from; Segment sg2; int i,intersection_value ; vector2d ipoint; board->GetSquareCornersInLogPx(s_from,l_cornerspos); Segment sg(board->GetCenterInPx(s_from),board->GetCenterInPx(s_to)); //foreach segment in the square, see intersection; for(i=0; i<4; i++) { if(i+1 == 4) sg2=Segment(l_cornerspos[i],l_cornerspos[0]); else sg2=Segment(l_cornerspos[i],l_cornerspos[i+1]); intersection_value = lines_intersect(sg,sg2, ipoint); ipoint.setint(); if(intersection_value == 1) { if( ipoint == l_cornerspos[i] || ipoint == l_cornerspos[i+1]) { vector2d g = sg.p1-ipoint; if(g.x>0) { if(g.y>0) { s_ret=s_ret+vector2d(1,1); } else if(g.y<0) { s_ret=s_ret+vector2d(1,-1); } else assert(0); //this means that the line coincides with the x-axis. and this is not possible since the destination point is a square center. } else if(g.x<0) { if(g.y>0) { s_ret=s_ret+vector2d(-1,1); } else if(g.y<0) { s_ret=s_ret+vector2d(-1,-1); } else assert(0); //this means that the line coincides with the x-axis. and this is not possible since the destination point is a square center. } else assert(0); //this means that the line coincides with the y-axis. and this is not possible since the destination point is a square center. } else if(i==0) { s_ret=s_ret+vector2d(0,-1); } else if(i==1) { s_ret=s_ret+vector2d(1,0); } else if(i==2) { s_ret=s_ret+vector2d(0,1); } else { s_ret=s_ret+vector2d(-1,0); } break; } } return s_ret; }

TEST(Circle, Intersection_Segment_1){ vector<Point> ans = { Point(sqrt(2.),sqrt(2.)) }; ASSERT_EQ(ans, Circle(Point(0,0),2).intersection(Segment(0,0,3,3))); };

TEST(Circle, Intersection_Segment_ox_2){ vector<Point> ans = { Point(sqrt(2.),sqrt(2.)), Point(-sqrt(2.),sqrt(2.)) }; ASSERT_EQ(ans, Circle(Point(4,4),2).intersection(Segment(-3,sqrt(2.),3,sqrt(2.)))); };

TEST(Circle, Projection){ ASSERT_EQ(Segment(2.5,2.5,4.5,4.5), Circle(Point(3,4),(Point(2,3) - Point(3,4)).norm()).projection(Point(5,5))); };

TEST(Segment, Projection){ ASSERT_EQ(Segment(3,3,5,5), Segment(2,4,4,6).projection(Point(7,7))); };

TEST(Segment, Intersection_Segment_noIntersection_2){ vector<Point> ans; vector<Point> res = Segment(1,3,3,5).intersection(Segment(4,2,5,1)); ASSERT_EQ(ans, res); };

static inline Segment construct( const point_type& low, const point_type& high) { return Segment(low, high); }

bool SquareLine::CanSee() { #if defined(_showdebugger_) // Debugger::GetInstance().Output("(%d,%d) ",s_cur.x,s_cur.y); #endif //defined(_showdebugger_) if(s_cur == s_goal) return true; if(!NotOutOfBoard(s_cur))//IsAValidRefuge can call CanSee with a square out of board. return true; //if no obstacle can hide the refuge from the borders of the map, the refuge is exposed. else if(board->GetContentAt(s_cur) == e_obstacle) return false; vector2d l_cornerspos[4]; //corners of a square board->GetSquareCornersInLogPx(s_cur,l_cornerspos); Segment sg2; int i,intersection_value ; vector2d ipoint; //foreach segment in the square, see intersection; for(i=0; i<4; i++) { if(i+1 == 4) sg2=Segment(l_cornerspos[i],l_cornerspos[0]); else sg2=Segment(l_cornerspos[i],l_cornerspos[i+1]); intersection_value = lines_intersect(sg,sg2, ipoint); ipoint.setint(); if(intersection_value == 1 && ! (ipoint== p_lastipoint) ) { if( ipoint == l_cornerspos[i] || ipoint == l_cornerspos[i+1]) { vector2d g = sg.p1-ipoint; if(g.x>0) { if(g.y>0) { s_cur=s_cur+vector2d(1,1); } else if(g.y<0) { s_cur=s_cur+vector2d(1,-1); } else assert(0); //this means that the line coincides with the x-axis. and this is not possible since the destination point is a square center. } else if(g.x<0) { if(g.y>0) { s_cur=s_cur+vector2d(-1,1); } else if(g.y<0) { s_cur=s_cur+vector2d(-1,-1); } else assert(0); //this means that the line coincides with the x-axis. and this is not possible since the destination point is a square center. } else assert(0); //this means that the line coincides with the y-axis. and this is not possible since the destination point is a square center. } else if(i==0) { s_cur=s_cur+vector2d(0,-1); } else if(i==1) { s_cur=s_cur+vector2d(1,0); } else if(i==2) { s_cur=s_cur+vector2d(0,1); } else { s_cur=s_cur+vector2d(-1,0); } p_lastipoint=ipoint; break; } } return CanSee(); }

void ConnectionsPerformanceTest::runSpatialPoolerTest(UInt numCells, UInt numInputs, UInt w, UInt numWinners, string label) { clock_t timer = clock(); Connections connections(numCells, 1, numInputs); Cell cell; Segment segment; vector<Cell> sdr; Activity activity; // Initialize for (UInt c = 0; c < numCells; c++) { cell = Cell(c); segment = connections.createSegment(c); for (UInt i = 0; i < numInputs; i++) { connections.createSynapse(segment, i, (Permanence)rand()/RAND_MAX); } } checkpoint(timer, label + ": initialize"); // Learn vector<Cell> winnerCells; SynapseData synapseData; Permanence permanence; for (int i = 0; i < 500; i++) { sdr = randomSDR(numInputs, w); activity = connections.computeActivity(sdr, 0.5, 0); winnerCells = computeSPWinnerCells(numWinners, activity); for (Cell winnerCell : winnerCells) { segment = Segment(0, winnerCell); for (Synapse synapse : connections.synapsesForSegment(segment)) { synapseData = connections.dataForSynapse(synapse); permanence = synapseData.permanence; if (find(sdr.begin(), sdr.end(), synapseData.presynapticCell) != sdr.end()) { permanence += 0.2; } else { permanence -= 0.1; } permanence = max(permanence, (Permanence)0); permanence = min(permanence, (Permanence)1); // TODO (Question): Remove synapses with 0 permanence? connections.updateSynapsePermanence(synapse, permanence); } } } checkpoint(timer, label + ": initialize + learn"); // Test for (int i = 0; i < 500; i++) { sdr = randomSDR(numInputs, w); activity = connections.computeActivity(sdr, 0.5, 0); winnerCells = computeSPWinnerCells(numWinners, activity); } checkpoint(timer, label + ": initialize + learn + test"); }

void route_edges2(Layouter &state,plugin& pg, double scale, int iter, double temp, int debug){ VR nodes; double d=state.avgsize/5; int n=state.nw.nodes.size(); for (int i=0;i<n;i++){ nodes.push_back(state.nw.nodes[i].rect()); nodes.back().extend(d); //debugrect(nodes.back(),0,0,255); } for (int i=0,m=state.nw.edges.size();i<m;i++){ //if (i!=iter) continue; Edge &e=state.nw.edges[i]; e.splinehandles.clear(); e.splinepoints.clear(); int n1=e.from; int n2=e.to; Point vec,p1,p2; double dir; switch(e.type){ case substrate: dir=lim(state.nw.nodes[n1].dir+PI/2); vec=Point(dir); swap(n1,n2); p1=state.nw.nodes[n1]; vec=state.nw.nodes[n2].rect().border_vec(vec); p2=state.nw.nodes[n2]+vec; break; case product: dir=lim(state.nw.nodes[n1].dir-PI/2); vec=Point(dir); vec=state.nw.nodes[n1].rect().border_vec(vec); p1=state.nw.nodes[n1]+vec; p2=state.nw.nodes[n2]; break; case activator: case inhibitor: case catalyst: swap(n1,n2); default: p1=state.nw.nodes[n1]; p2=state.nw.nodes[n2]; } vector<Segment> vs; vs.push_back(Segment(ParamEdge(p1,p2),true,true)); split_route(vs,nodes,0,n1,n2); Point vec1=state.nw.nodes[n1].rect().border_vec(vs.front().edge.to()-vs.front().edge.from()); Point vec2=state.nw.nodes[n2].rect().border_vec(vs.back().edge.from()-vs.back().edge.to()); switch(e.type){ case activator: case inhibitor: case catalyst: dir=lim(state.nw.nodes[n2].dir); if (scalar(Point(dir),vs.back().edge.from()-vs.back().edge.to())<0) dir=lim(dir+PI); vec=Point(dir); vec=state.nw.nodes[n2].rect().border_vec(vec); p2=state.nw.nodes[n2]+vec; case substrate: e.splinehandles.push_back(vec1+d); e.splinehandles.push_back(vec+d); break; case product: e.splinehandles.push_back(vec+d); e.splinehandles.push_back(vec2+d); break; default: e.splinehandles.push_back(vec1+d); e.splinehandles.push_back(vec2+d); } for (int j=1,s=vs.size();j<s;j++){ Point before=vs[j-1].edge.from(); Point cur=vs[j-1].edge.to(); //if (cur!=vs[j].edge.from()) throw "ups: edge segments not continious"; Point after=vs[j].edge.to(); Point dv=unit(before-cur)*d+unit(after-cur)*d; debugline(cur,cur+dv,0,255,0,true); e.splinehandles.insert(--e.splinehandles.end(),unit(to_left(dv,PI/2))*sign(scalar(to_left(dv,PI/2),before-cur))*d); e.splinepoints.push_back(cur+dv); } } }

void Lightning::create() { remove(); Ogre::Vector3 end = mOrigin + mDirection*mLength; Ogre::Vector3 current, last = mOrigin; // Create ray segments for(Ogre::uint32 k = 1; k < mDivisions+1; k++) { Ogre::Vector3 current = mOrigin + mDirection*mLength*(static_cast<Ogre::Real>(k)/mDivisions); current += (mLength/(mDivisions*3))*Ogre::Vector3( Ogre::Math::RangeRandom(-1, 1), Ogre::Math::RangeRandom(-1, 1), Ogre::Math::RangeRandom(-1, 1)); mSegments.push_back(Segment(last, current)); mRealLength += (current-last).length(); last = current; } // Create the associated billboard set mBillboardSet = mSceneManager->createBillboardSet(); mBillboardSet->setMaterialName("SkyX_Lightning"); mBillboardSet->setBillboardType(Ogre::BBT_ORIENTED_SELF); Ogre::Real width = mWidthMultiplier*3*(static_cast<Ogre::Real>(mRecursivity)/4+1)*Ogre::Math::RangeRandom(0.5f, 2.5f-mRecursivity/3); // Create the associated billboard for each segment Ogre::Real delta; Ogre::Vector2 bounds; Ogre::Billboard* bb; for(Ogre::uint32 k = 0; k < mSegments.size(); k++) { delta = 1.0f / mSegments.size(); bounds = Ogre::Vector2(k*delta,(k+1)*delta); bounds = Ogre::Vector2(mBounds.x, mBounds.x) + bounds*(mBounds.y-mBounds.x); bb = mBillboardSet->createBillboard((mSegments.at(k).a+mSegments.at(k).b)/2); bb->setDimensions(width, (mSegments.at(k).a-mSegments.at(k).b).length()); bb->setColour(Ogre::ColourValue(0,bounds.x,bounds.y)); bb->mDirection = (mSegments.at(k).a-mSegments.at(k).b).normalisedCopy(); bb = mBillboardSet->createBillboard(mSegments.at(k).a + (mSegments.at(k).a-mSegments.at(k).b).normalisedCopy()*width/2); bb->setDimensions(width, width); bb->setColour(Ogre::ColourValue(1,bounds.x,bounds.x)); bb->mDirection = (mSegments.at(k).a-mSegments.at(k).b).normalisedCopy(); bb = mBillboardSet->createBillboard(mSegments.at(k).b - (mSegments.at(k).a-mSegments.at(k).b).normalisedCopy()*width/2); bb->setDimensions(width, width); bb->setColour(Ogre::ColourValue(1,bounds.y,bounds.y)); bb->mDirection = -(mSegments.at(k).a-mSegments.at(k).b).normalisedCopy(); width *= 1-(1.0f/(mRecursivity*mRecursivity))*(1.0f/mSegments.size()); } mBillboardSet->_updateBounds(); mSceneNode->attachObject(mBillboardSet); mBillboardSet->setCustomParameter(0, Ogre::Vector4(1,0,0,0)); // Ramifications if (mRecursivity > 0) { Ogre::Real angle; Ogre::Vector3 dir; Ogre::Real lengthMult; for (Ogre::uint32 k = 0; k < mDivisions-1; k++) { angle = (mSegments.at(k).b-mSegments.at(k).a).normalisedCopy().dotProduct( ((mSegments.at(k+1).b-mSegments.at(k+1).a).normalisedCopy())); if (angle < Ogre::Math::RangeRandom(mAngleRange.x, mAngleRange.y)) { dir = (mSegments.at(k).b-mSegments.at(k).a).normalisedCopy(); dir.x *= Ogre::Math::RangeRandom(0.8f, 1.2f); dir.y *= Ogre::Math::RangeRandom(0.8f, 1.2f); dir.z *= Ogre::Math::RangeRandom(0.8f, 1.2f); dir.normalise(); delta = 1.0f / mSegments.size(); bounds = Ogre::Vector2(mBounds.x+(mBounds.y-mBounds.x)*(k+1)*delta,1); lengthMult = Ogre::Math::RangeRandom(0.1f, 0.7f); Lightning* lightning = new Lightning(mSceneManager, mSceneNode, mSegments.at(k).b, dir, lengthMult*mLength, 2+mDivisions*lengthMult, mRecursivity-1, mTimeMultiplier, mWidthMultiplier, bounds); lightning->create(); mChildren.push_back(lightning); } } } mCreated = true; }

LimaStatusCode ParagraphBoundariesFinder::process( AnalysisContent& analysis) const { TimeUtils::updateCurrentTime(); SENTBOUNDLOGINIT; LINFO << "start finding paragraph founds"; // find paragraphs in text (positions of double carriage returns), // then find corresponding vertices in graph AnalysisGraph* graph=static_cast<AnalysisGraph*>(analysis.getData(m_graph)); if (graph==0) { LERROR << "no graph '" << m_graph << "' available !"; return MISSING_DATA; } SegmentationData* boundaries=new SegmentationData(m_graph); analysis.setData("ParagraphBoundaries",boundaries); LimaStringText* text=static_cast<LimaStringText*>(analysis.getData("Text")); std::vector<uint64_t> paragraphPositions; int currentPos=0; int i=text->indexOf(m_paragraphSeparator,currentPos); while (i!=-1) { paragraphPositions.push_back((uint64_t)i); // goto next char that is not a carriage return currentPos=text->indexOf(QRegExp(QString("[^")+ m_paragraphSeparator+"]"),i+1); i=text->indexOf(m_paragraphSeparator,currentPos); } if (paragraphPositions.empty()) { LWARN << "no paragraph found"; return SUCCESS_ID; } // find vertices related to positions in graph uint64_t parNum=0; std::deque<LinguisticGraphVertex> toVisit; std::set<LinguisticGraphVertex> visited; LinguisticGraphVertex beginParagraph=graph->firstVertex(); toVisit.push_back(graph->firstVertex()); visited.insert(graph->firstVertex()); while (!toVisit.empty()) { LinguisticGraphVertex currentVertex=toVisit.front(); toVisit.pop_front(); if (currentVertex == graph->lastVertex()) { // end of the graph continue; // may be other nodes to test in queue } if (currentVertex != graph->firstVertex()) { Token* t = get(vertex_token,*(graph->getGraph()),currentVertex); uint64_t position=t->position(); if (position >= (paragraphPositions[parNum]+1)) { boundaries->add(Segment("paragraph",beginParagraph,currentVertex,graph)); beginParagraph=currentVertex; parNum++; if (parNum >= paragraphPositions.size()) { break; } } } // store following nodes to test LinguisticGraphOutEdgeIt outEdge,outEdge_end; boost::tie(outEdge,outEdge_end)=out_edges(currentVertex,*(graph->getGraph())); for (; outEdge!=outEdge_end; outEdge++) { LinguisticGraphVertex next=target(*outEdge,*(graph->getGraph())); if (visited.find(next)==visited.end()) { toVisit.push_back(next); visited.insert(next); } } } TimeUtils::logElapsedTime("ParagraphBoundariesFinder"); return SUCCESS_ID; }

/*virtual*/ void WBActionEldCheckLine::Execute() { WBAction::Execute(); STATIC_HASHED_STRING( EventOwner ); WBEntity* const pEntity = GetEntity(); WBEntity* const pOwnerEntity = GetOwner(); EldritchWorld* const pWorld = EldritchFramework::GetInstance()->GetWorld(); WBEventManager* const pEventManager = WBWorld::GetInstance()->GetEventManager(); Vector LineStart; Angles LineOrientation; GetLineTransform( LineStart, LineOrientation ); const Vector LineDirection = LineOrientation.ToVector(); CollisionInfo Info; Info.m_CollideWorld = true; Info.m_CollideEntities = true; Info.m_CollidingEntity = pOwnerEntity; Info.m_UserFlags = EECF_Trace; if( m_LineLength > 0.0f ) { const Vector LineEnd = LineStart + LineDirection * m_LineLength; const Segment TraceSegment = Segment( LineStart, LineEnd ); if( !pWorld->Trace( TraceSegment, Info ) ) { return; } } else { const Ray TraceRay = Ray( LineStart, LineDirection ); if( !pWorld->Trace( TraceRay, Info ) ) { return; } } const Vector HitLocation = Info.m_Intersection; const Vector HitNormal = Info.m_Plane.m_Normal; // Notify this entity that the line check hit that entity. if( Info.m_HitEntity ) { WB_MAKE_EVENT( OnLineCheck, pEntity ); WB_SET_AUTO( OnLineCheck, Hash, CheckTag, m_CheckTag ); WB_SET_AUTO( OnLineCheck, Entity, Checked, static_cast<WBEntity*>( Info.m_HitEntity ) ); WB_SET_AUTO( OnLineCheck, Vector, LineDirection, LineDirection ); WB_SET_AUTO( OnLineCheck, Vector, HitLocation, HitLocation ); WB_SET_AUTO( OnLineCheck, Vector, HitNormal, HitNormal ); WB_DISPATCH_EVENT( pEventManager, OnLineCheck, pEntity ); } else { const Vector HalfHitNormal = 0.5f * Info.m_Plane.m_Normal; const Vector HitVoxel = pWorld->GetVoxelCenter( HitLocation - HalfHitNormal ); WB_MAKE_EVENT( OnLineCheckMissed, pEntity ); WB_SET_AUTO( OnLineCheckMissed, Hash, CheckTag, m_CheckTag ); WB_SET_AUTO( OnLineCheckMissed, Vector, LineDirection, LineDirection ); WB_SET_AUTO( OnLineCheckMissed, Vector, HitLocation, HitLocation ); WB_SET_AUTO( OnLineCheckMissed, Vector, HitNormal, HitNormal ); WB_SET_AUTO( OnLineCheckMissed, Vector, HitVoxel, HitVoxel ); WB_DISPATCH_EVENT( pEventManager, OnLineCheckMissed, pEntity ); } }

void Light::addTriangle(Point p1, Point p2, Uint32 begin, const std::vector<Segment>& segments) { if( p1 == p2 ) return; for( size_t k(begin); k < segments.size(); k++ ) { Segment s = convertToLocal(segments[k]); double a = Vector2d::angle(s.p1, s.p2); if( a == 0 ) continue; Point p0, w1, w2; if( a > 0 ) { w1 = s.p1; w2 = s.p2; } else { w1 = s.p2; w2 = s.p1; } if( Triangle::contains(p0, p1, p2, w1) ) { Point i; Line::intersects(p0, w1, p1, p2, i); addTriangle(p1, i, k + 1, segments); p1 = i; } if( Triangle::contains(p0, p1, p2, w2) ) { Point i; Line::intersects(p0, w2, p1, p2, i); addTriangle(i, p2, k + 1, segments); p2 = i; } Point i1, i2, i3; bool int1 = s.intersects(Segment(p0, p1), i1), int2 = s.intersects(Segment(p0, p2), i2), int3 = s.intersects(Segment(p1, p2), i3); if( (int1 && i1 == p0) || (int2 && i2 == p0) || (int3 && i3 == p0) ) continue; if( int1 && int2 ) { p1 = i1; p2 = i2; } else { if( int1 && int3 ) { addTriangle(i1, i3, begin, segments); p1 = i3; } if( int2 && int3 ) { addTriangle(i2, i3, begin, segments); p2 = i3; } } } m_colors.push_back({m_color.r, m_color.g, m_color.b, char(255*(m_radius - p2.length()) / m_radius)}); m_colors.push_back({m_color.r, m_color.g, m_color.b, char(255*(m_radius - p1.length()) / m_radius)}); addFace(getVertex(0), addVertex(p1), addVertex(p2)); }

void MapWindow::DrawTask(HDC hdc, RECT rc, const POINT &Orig_Aircraft) { int i; double tmp; COLORREF whitecolor = RGB_WHITE; COLORREF origcolor = SetTextColor(hDCTemp, whitecolor); HPEN oldpen = 0; HBRUSH oldbrush = 0; static short size_tasklines=0; if (DoInit[MDI_DRAWTASK]) { switch (ScreenSize) { case ss480x272: case ss272x480: case ss320x240: case ss240x320: size_tasklines=NIBLSCALE(4); break; default: size_tasklines=NIBLSCALE(3); break; } DoInit[MDI_DRAWTASK]=false; } if (!WayPointList) return; oldpen = (HPEN) SelectObject(hdc, hpStartFinishThick); oldbrush = (HBRUSH) SelectObject(hdc, GetStockObject(HOLLOW_BRUSH)); LockTaskData(); // protect from external task changes for (i = 1; ValidTaskPoint(i); i++) { if (!ValidTaskPoint(i + 1)) { // final waypoint if (ActiveWayPoint > 1 || !ValidTaskPoint(2)) { // only draw finish line when past the first // waypoint. FIXED 110307: or if task is with only 2 tps DrawStartEndSector(hdc, rc, Task[i].Start, Task[i].End, Task[i].Index, FinishLine, FinishRadius); } } else { // normal sector if (AATEnabled != TRUE) { //_DrawLine(hdc, PS_DASH, NIBLSCALE(3), WayPointList[Task[i].Index].Screen, Task[i].Start, RGB_PETROL, rc); //_DrawLine(hdc, PS_DASH, NIBLSCALE(3), WayPointList[Task[i].Index].Screen, Task[i].End, RGB_PETROL, rc); // DrawDashLine(hdc, size_tasklines, WayPointList[Task[i].Index].Screen, Task[i].Start, RGB_PETROL, rc); // DrawDashLine(hdc, size_tasklines, WayPointList[Task[i].Index].Screen, Task[i].End, RGB_PETROL, rc); } int Type = 0; double Radius = 0.; GetTaskSectorParameter(i, &Type, &Radius); switch (Type) { case CIRCLE: tmp = Radius * zoom.ResScaleOverDistanceModify(); Circle(hdc, WayPointList[Task[i].Index].Screen.x, WayPointList[Task[i].Index].Screen.y, (int) tmp, rc, false, false); break; case SECTOR: tmp = Radius * zoom.ResScaleOverDistanceModify(); Segment(hdc, WayPointList[Task[i].Index].Screen.x, WayPointList[Task[i].Index].Screen.y, (int) tmp, rc, Task[i].AATStartRadial - DisplayAngle, Task[i].AATFinishRadial - DisplayAngle); break; case DAe: if (!AATEnabled) { // this Type exist only if not AAT task // JMW added german rules tmp = 500 * zoom.ResScaleOverDistanceModify(); Circle(hdc, WayPointList[Task[i].Index].Screen.x, WayPointList[Task[i].Index].Screen.y, (int) tmp, rc, false, false); tmp = 10e3 * zoom.ResScaleOverDistanceModify(); Segment(hdc, WayPointList[Task[i].Index].Screen.x, WayPointList[Task[i].Index].Screen.y, (int) tmp, rc, Task[i].AATStartRadial - DisplayAngle, Task[i].AATFinishRadial - DisplayAngle); } break; case LINE: if (!AATEnabled) { // this Type exist only if not AAT task if(ISGAAIRCRAFT) { POINT start,end; double rotation=AngleLimit360(Task[i].Bisector-DisplayAngle); int length=14*ScreenScale; //Make intermediate WP lines always of the same size independent by zoom level start.x=WayPointList[Task[i].Index].Screen.x+(long)(length*fastsine(rotation)); start.y=WayPointList[Task[i].Index].Screen.y-(long)(length*fastcosine(rotation)); rotation=Reciprocal(rotation); end.x=WayPointList[Task[i].Index].Screen.x+(long)(length*fastsine(rotation)); end.y=WayPointList[Task[i].Index].Screen.y-(long)(length*fastcosine(rotation)); _DrawLine(hdc, PS_SOLID, NIBLSCALE(3), start, end, taskcolor, rc); } else _DrawLine(hdc, PS_SOLID, NIBLSCALE(3), Task[i].Start, Task[i].End, taskcolor, rc); } break; case CONE: tmp = Radius * zoom.ResScaleOverDistanceModify(); int center_x = WayPointList[Task[i].Index].Screen.x; int center_y = WayPointList[Task[i].Index].Screen.y; Circle(hdc, center_x, center_y, (int) tmp, rc, false, false); HPEN prevPen = (HPEN)::SelectObject(hdc, hpTerrainLine); for( int j = 1; j < 5 && tmp > 0; ++j) { Circle(hdc, center_x, center_y, tmp -= NIBLSCALE(5), rc, true, true); } ::SelectObject(hdc, prevPen); break; } if (AATEnabled && !DoOptimizeRoute()) { // ELSE HERE IS *** AAT *** // JMW added iso lines if ((i == ActiveWayPoint) || (mode.Is(Mode::MODE_TARGET_PAN) && (i == TargetPanIndex))) { // JMW 20080616 flash arc line if very close to target static bool flip = false; if (DerivedDrawInfo.WaypointDistance < AATCloseDistance()*2.0) { flip = !flip; } else { flip = true; } if (flip) { for (int j = 0; j < MAXISOLINES - 1; j++) { if (TaskStats[i].IsoLine_valid[j] && TaskStats[i].IsoLine_valid[j + 1]) { _DrawLine(hdc, PS_SOLID, NIBLSCALE(2), TaskStats[i].IsoLine_Screen[j], TaskStats[i].IsoLine_Screen[j + 1], RGB(0, 0, 255), rc); } } } } } } } if ((ActiveWayPoint < 2) && ValidTaskPoint(0) && ValidTaskPoint(1)) { DrawStartEndSector(hdc, rc, Task[0].Start, Task[0].End, Task[0].Index, StartLine, StartRadius); if (EnableMultipleStartPoints) { for (i = 0; i < MAXSTARTPOINTS; i++) { if (StartPoints[i].Active && ValidWayPoint(StartPoints[i].Index)) { DrawStartEndSector(hdc, rc, StartPoints[i].Start, StartPoints[i].End, StartPoints[i].Index, StartLine, StartRadius); } } } } for (i = 0; ValidTaskPoint(i + 1); i++) { int imin = min(Task[i].Index, Task[i + 1].Index); int imax = max(Task[i].Index, Task[i + 1].Index); // JMW AAT! double bearing = Task[i].OutBound; POINT sct1, sct2; if (AATEnabled) { LatLon2Screen(Task[i].AATTargetLon, Task[i].AATTargetLat, sct1); LatLon2Screen(Task[i + 1].AATTargetLon, Task[i + 1].AATTargetLat, sct2); DistanceBearing(Task[i].AATTargetLat, Task[i].AATTargetLon, Task[i + 1].AATTargetLat, Task[i + 1].AATTargetLon, NULL, &bearing); // draw nominal track line DrawDashLine(hdc, NIBLSCALE(1), // 091217 WayPointList[imin].Screen, WayPointList[imax].Screen, taskcolor, rc); } else { sct1 = WayPointList[imin].Screen; sct2 = WayPointList[imax].Screen; } if ((i >= ActiveWayPoint && DoOptimizeRoute()) || !DoOptimizeRoute()) { POINT ClipPt1 = sct1, ClipPt2 = sct2; if(LKGeom::ClipLine((POINT) {rc.left, rc.top}, (POINT) {rc.right, rc.bottom}, ClipPt1, ClipPt2)) { DrawMulticolorDashLine(hdc, size_tasklines, sct1, sct2, taskcolor, RGB_BLACK,rc); // draw small arrow along task direction POINT p_p; POINT Arrow[2] = { {6, 6}, {-6, 6} }; ScreenClosestPoint(sct1, sct2, Orig_Aircraft, &p_p, NIBLSCALE(25)); threadsafePolygonRotateShift(Arrow, 2, p_p.x, p_p.y, bearing - DisplayAngle); _DrawLine(hdc, PS_SOLID, size_tasklines-NIBLSCALE(1), Arrow[0], p_p, taskcolor, rc); _DrawLine(hdc, PS_SOLID, size_tasklines-NIBLSCALE(1), Arrow[1], p_p, taskcolor, rc); } } } // Draw DashLine From current position to Active TurnPoint center if(ValidTaskPoint(ActiveWayPoint)) { POINT ptStart; LatLon2Screen(DrawInfo.Longitude, DrawInfo.Latitude, ptStart); DrawDashLine(hdc, NIBLSCALE(1), ptStart, WayPointList[Task[ActiveWayPoint].Index].Screen, taskcolor, rc); } { UnlockTaskData(); } // restore original color SetTextColor(hDCTemp, origcolor); SelectObject(hdc, oldpen); SelectObject(hdc, oldbrush); }

int CObject::Create (ubyte nType, ubyte nId, short nCreator, short nSegment, const CFixVector& vPos, const CFixMatrix& mOrient, fix xSize, ubyte cType, ubyte mType, ubyte rType) { #if DBG if (nType == OBJ_WEAPON) { nType = nType; if ((nCreator >= 0) && (OBJECTS [nCreator].info.nType == OBJ_ROBOT)) nType = nType; if (nId == FLARE_ID) nType = nType; if (gameData.objs.bIsMissile [(int) nId]) nType = nType; } else if (nType == OBJ_ROBOT) { #if 0 if (ROBOTINFO ((int) nId).bossFlag && (BOSS_COUNT >= MAX_BOSS_COUNT)) return -1; #endif } else if (nType == OBJ_HOSTAGE) nType = nType; else if (nType == OBJ_FIREBALL) nType = nType; else if (nType == OBJ_REACTOR) nType = nType; else if (nType == OBJ_DEBRIS) nType = nType; else if (nType == OBJ_MARKER) nType = nType; else if (nType == OBJ_PLAYER) nType = nType; else if (nType == OBJ_POWERUP) nType = nType; #endif SetSegment (FindSegByPos (vPos, nSegment, 1, 0)); if ((Segment () < 0) || (Segment () > gameData.segs.nLastSegment)) return -1; if (nType == OBJ_DEBRIS) { if (gameData.objs.nDebris >= gameStates.render.detail.nMaxDebrisObjects) return -1; } // Zero out object structure to keep weird bugs from happening in uninitialized fields. m_nId = OBJ_IDX (this); SetSignature (gameData.objs.nNextSignature++); SetType (nType); SetId (nId); SetLastPos (vPos); SetPos (&vPos); SetSize (xSize); SetCreator ((sbyte) nCreator); SetOrient (&mOrient); SetControlType (cType); SetMovementType (mType); SetRenderType (rType); SetContainsType (-1); SetLifeLeft ( ((gameData.app.nGameMode & GM_ENTROPY) && (nType == OBJ_POWERUP) && (nId == POW_HOARD_ORB) && (extraGameInfo [1].entropy.nVirusLifespan > 0)) ? I2X (extraGameInfo [1].entropy.nVirusLifespan) : IMMORTAL_TIME); SetAttachedObj (-1); m_xCreationTime = gameData.time.xGame; #if 0 if (GetControlType () == CT_POWERUP) CPowerupInfo::SetCount (1); // Init physics info for this CObject if (GetMovementType () == MT_PHYSICS) m_vStartVel.SetZero (); if (GetRenderType () == RT_POLYOBJ) CPolyObjInfo::SetTexOverride (-1); if (GetType () == OBJ_WEAPON) { CPhysicsInfo::SetFlags (CPhysInfo.GetFlags () | WI_persistent (m_info.nId) * PF_PERSISTENT); CLaserInfo::SetCreationTime (gameData.time.xGame); CLaserInfo::SetLastHitObj (0); CLaserInfo::SetScale (I2X (1)); } else if (GetType () == OBJ_DEBRIS) gameData.objs.nDebris++; if (GetControlType () == CT_POWERUP) CPowerupInfo::SetCreationTime (gameData.time.xGame); else if (GetControlType () == CT_EXPLOSION) { CAttachedInfo::SetPrev (-1); CAttachedInfo::SetNext (-1); CAttachedInfo::SetParent (-1); } #endif Link (); LinkToSeg (nSegment); return m_nId; }

int main(void) { consoleDemoInit(); //videoSetMode(MODE_FB0); videoSetMode( MODE_5_2D ); vramSetBankA(VRAM_A_MAIN_BG); vramSetBankB(VRAM_B_MAIN_BG); // vramSetBankC(VRAM_C_MAIN_BG); // vramSetBankD(VRAM_D_MAIN_BG_0x06040000); int bg = bgInit(3, BgType_Bmp8, BgSize_B8_512x512, 0,0); //vramSetBankA(VRAM_A_LCD); lcdMainOnBottom(); // lcdMainOnTop(); printf("Video modes configured\n"); printf("BG ID %d\n", bg); if (fatInitDefault()) printf("FAT initialized\n"); else printf("FAT initialization failed\n"); AppState state; uiOpenNotebook(state); // Keyboard *kbd = keyboardDemoInit(); Segment * currentSegment = NULL; touchPosition touch; while (1) { scanKeys(); if(keysHeld() & KEY_TOUCH) { // write the touchscreen coordinates in the touch variable touchRead(&touch); Point screenPoint = Point(touch.px, touch.py); Point imagePoint = state.convertScreenToImage(screenPoint); if (currentSegment == NULL) { state.currentPage->segments.push_back(Segment()); currentSegment = &(state.currentPage->segments[state.currentPage->segments.size()-1]); currentSegment->points.push_back(imagePoint); continue; } Point lastImagePoint = currentSegment->points[currentSegment->points.size()-1]; currentSegment->points.push_back(imagePoint); Point bufferPoint = state.convertScreenToBuffer(screenPoint); Point lastBufferPoint = state.convertImageToBuffer(lastImagePoint); drawLine(lastBufferPoint.x, lastBufferPoint.y, bufferPoint.x, bufferPoint.y, RGB15(31,0,0) | BIT(15)); } else { currentSegment = NULL; } if (keysDown() & KEY_X) { int page = state.lastPage+1; while (state.notebook.pages.size() < page+1) { state.notebook.pages.push_back(Page()); printf("New Page created\n"); } state.currentPage = &(state.notebook.pages[page]); currentSegment = NULL; printf("Display page %d\n", page); fillDisplay(RGB15(0,0,0) | BIT(15), page, state); drawPage(state.currentPage, RGB15(31,0,0) | BIT(15), state); } if (keysDown() & KEY_Y) { int page = 0; if (state.lastPage > 0) { page = state.lastPage-1; } state.currentPage = &(state.notebook.pages[page]); currentSegment = NULL; printf("Display page %d\n", page); fillDisplay(RGB15(0,0,0) | BIT(15), page, state); drawPage(state.currentPage, RGB15(31,0,0) | BIT(15), state); } if (keysDown() & KEY_A) { int page = 0; std::string fileName = state.notebookName + "/notes.txt"; state.notebook = loadFile(fileName.c_str()); state.currentPage = &(state.notebook.pages[page]); currentSegment = NULL; printf("Display page %d\n", page); fillDisplay(RGB15(0,0,0) | BIT(15), page, state); drawPage(state.currentPage, RGB15(31,0,0) | BIT(15), state); } if (keysDown() & KEY_B) { std::string fileName = state.notebookName + "/notes.txt"; saveFile(fileName.c_str(), state.notebook); } if (keysDown() & KEY_LEFT) { state.scroll_x-=50; updateCenter(state); } if (keysDown() & KEY_RIGHT) { state.scroll_x+=50; updateCenter(state); } if (keysDown() & KEY_UP) { state.scroll_y-=50; updateCenter(state); } if (keysDown() & KEY_DOWN) { state.scroll_y+=50; updateCenter(state); } if (keysDown() & KEY_START) { uiOpenNotebook(state); } swiWaitForVBlank(); } }

Download::Download(UserConnection& conn, QueueItem& qi) noexcept : Transfer(conn, qi.getTarget(), qi.getTTH()), tempTarget(qi.getTempTarget()) { conn.setDownload(this); QueueItem::SourceConstIter source = qi.getSource(getUser()); if(qi.isSet(QueueItem::FLAG_PARTIAL_LIST)) { setType(TYPE_PARTIAL_LIST); } else if(qi.isSet(QueueItem::FLAG_USER_LIST)) { setType(TYPE_FULL_LIST); } if(source->isSet(QueueItem::Source::FLAG_PARTIAL)) setFlag(FLAG_PARTIAL); if(qi.isSet(QueueItem::FLAG_CLIENT_VIEW)) setFlag(FLAG_VIEW); if(qi.isSet(QueueItem::FLAG_MATCH_QUEUE)) setFlag(FLAG_QUEUE); if(qi.isSet(QueueItem::FLAG_VIEW_NFO)) setFlag(FLAG_NFO); if(qi.isSet(QueueItem::FLAG_RECURSIVE_LIST)) setFlag(FLAG_RECURSIVE); if(qi.isSet(QueueItem::FLAG_TTHLIST_BUNDLE)) setFlag(FLAG_TTHLIST_BUNDLE); if (qi.getPriority() == QueueItemBase::HIGHEST) setFlag(FLAG_HIGHEST_PRIO); if (qi.getBundle()) { dcassert(!qi.isSet(QueueItem::FLAG_USER_LIST)); dcassert(!qi.isSet(QueueItem::FLAG_TEXT)); setBundle(qi.getBundle()); } if(getType() == TYPE_FILE && qi.getSize() != -1) { if(HashManager::getInstance()->getTree(getTTH(), getTigerTree())) { setTreeValid(true); setSegment(qi.getNextSegment(getTigerTree().getBlockSize(), conn.getChunkSize(), conn.getSpeed(), source->getPartialSource(), true)); qi.setBlockSize(getTigerTree().getBlockSize()); } else if(conn.isSet(UserConnection::FLAG_SUPPORTS_TTHL) && !source->isSet(QueueItem::Source::FLAG_NO_TREE) && qi.getSize() > HashManager::MIN_BLOCK_SIZE) { // Get the tree unless the file is small (for small files, we'd probably only get the root anyway) setType(TYPE_TREE); getTigerTree().setFileSize(qi.getSize()); setSegment(Segment(0, -1)); } else { // Use the root as tree to get some sort of validation at least... getTigerTree() = TigerTree(qi.getSize(), qi.getSize(), getTTH()); setTreeValid(true); setSegment(qi.getNextSegment(getTigerTree().getBlockSize(), 0, 0, source->getPartialSource(), true)); } if ((getStartPos() + getSegmentSize()) != qi.getSize() || (conn.getDownload() && conn.getDownload()->isSet(FLAG_CHUNKED))) { setFlag(FLAG_CHUNKED); } if(getSegment().getOverlapped()) { setFlag(FLAG_OVERLAP); // set overlapped flag to original segment for(auto d: qi.getDownloads()) { if(d->getSegment().contains(getSegment())) { d->setOverlapped(true); break; } } } } }

Segment Scene::random_segment(const CGAL::Bbox_3& bbox) { Point p = random_point(bbox); Point q = random_point(bbox); return Segment(p,q); }

Segment QueueItem::getNextSegment(int64_t blockSize, int64_t wantedSize) const { if(getSize() == -1 || blockSize == 0) { return Segment(0, -1); } if(!BOOLSETTING(SEGMENTED_DL) && !downloads.empty()) { return Segment(0, 0); } int64_t remaining = getSize() - getDownloadedBytes(); int64_t targetSize; if(BOOLSETTING(SEGMENTED_DL)) { double done = static_cast<double>(getDownloadedBytes()) / getSize(); // We want smaller blocks at the end of the transfer, squaring gives a nice curve... targetSize = wantedSize * std::max(0.25, (1. - (done * done))); if(targetSize > blockSize) { // Round off to nearest block size targetSize = ((targetSize + (blockSize / 2)) / blockSize) * blockSize; } else { targetSize = blockSize; } } else { targetSize = remaining; } int64_t start = 0; int64_t curSize = targetSize; while(start < getSize()) { int64_t end = std::min(getSize(), start + curSize); Segment block(start, end - start); bool overlaps = false; for(SegmentIter i = done.begin(); !overlaps && i != done.end(); ++i) { if(curSize <= blockSize) { int64_t dstart = i->getStart(); int64_t dend = i->getEnd(); // We accept partial overlaps, only consider the block done if it is fully consumed by the done block if(dstart <= start && dend >= end) { overlaps = true; } } else { overlaps = block.overlaps(*i); } } for(DownloadList::const_iterator i = downloads.begin(); !overlaps && i !=downloads.end(); ++i) { overlaps = block.overlaps((*i)->getSegment()); } if(!overlaps) { return block; } if(curSize > blockSize) { curSize -= blockSize; } else { start = end; curSize = targetSize; } } return Segment(0, 0); }

MachOLayout<A>::MachOLayout(const void* machHeader, uint64_t offset, const char* path, ino_t inode, time_t modTime, uid_t uid) : fPath(path), fOffset(offset), fArchPair(0,0), fMTime(modTime), fInode(inode), fHasSplitSegInfo(false), fRootOwned(uid==0), fShareableLocation(false), fDynamicLookupLinkage(false), fMainExecutableLookupLinkage(false), fIsDylib(false), fHasDyldInfo(false), fDyldInfoExports(NULL) { fDylibID.name = NULL; fDylibID.currentVersion = 0; fDylibID.compatibilityVersion = 0; bzero(fUUID, sizeof(fUUID)); const macho_header<P>* mh = (const macho_header<P>*)machHeader; if ( mh->cputype() != arch() ) throw "Layout object is wrong architecture"; switch ( mh->filetype() ) { case MH_DYLIB: fIsDylib = true; break; case MH_BUNDLE: case MH_EXECUTE: case MH_DYLIB_STUB: case MH_DYLINKER: break; default: throw "file is not a mach-o final linked image"; } fFlags = mh->flags(); fFileType = mh->filetype(); fArchPair.arch = mh->cputype(); fArchPair.subtype = mh->cpusubtype(); const macho_dyld_info_command<P>* dyldInfo = NULL; const macho_symtab_command<P>* symbolTableCmd = NULL; const macho_dysymtab_command<P>* dynamicSymbolTableCmd = NULL; const macho_load_command<P>* const cmds = (macho_load_command<P>*)((uint8_t*)mh + sizeof(macho_header<P>)); const uint32_t cmd_count = mh->ncmds(); const macho_load_command<P>* cmd = cmds; for (uint32_t i = 0; i < cmd_count; ++i) { switch ( cmd->cmd() ) { case LC_ID_DYLIB: { macho_dylib_command<P>* dylib = (macho_dylib_command<P>*)cmd; fDylibID.name = strdup(dylib->name()); fDylibID.currentVersion = dylib->current_version(); fDylibID.compatibilityVersion = dylib->compatibility_version(); fNameFileOffset = dylib->name() - (char*)machHeader; fShareableLocation = ( (strncmp(fDylibID.name, "/usr/lib/", 9) == 0) || (strncmp(fDylibID.name, "/System/Library/", 16) == 0) ); } break; case LC_LOAD_DYLIB: case LC_LOAD_WEAK_DYLIB: case LC_REEXPORT_DYLIB: case LC_LOAD_UPWARD_DYLIB: { macho_dylib_command<P>* dylib = (macho_dylib_command<P>*)cmd; Library lib; lib.name = strdup(dylib->name()); lib.currentVersion = dylib->current_version(); lib.compatibilityVersion = dylib->compatibility_version(); lib.weakImport = ( cmd->cmd() == LC_LOAD_WEAK_DYLIB ); fLibraries.push_back(lib); } break; case LC_SEGMENT_SPLIT_INFO: fHasSplitSegInfo = true; break; case macho_segment_command<P>::CMD: { macho_segment_command<P>* segCmd = (macho_segment_command<P>*)cmd; fSegments.push_back(Segment(segCmd->vmaddr(), segCmd->vmsize(), segCmd->fileoff(), segCmd->filesize(), segCmd->initprot(), segCmd->segname())); } break; case LC_SYMTAB: symbolTableCmd = (macho_symtab_command<P>*)cmd; break; case LC_DYSYMTAB: dynamicSymbolTableCmd = (macho_dysymtab_command<P>*)cmd; break; case LC_DYLD_INFO: case LC_DYLD_INFO_ONLY: fHasDyldInfo = true; dyldInfo = (struct macho_dyld_info_command<P>*)cmd; break; case LC_UUID: { const macho_uuid_command<P>* uc = (macho_uuid_command<P>*)cmd; memcpy(&fUUID, uc->uuid(), 16); } break; } cmd = (const macho_load_command<P>*)(((uint8_t*)cmd)+cmd->cmdsize()); } fLowSegment = NULL; fLowExecutableSegment = NULL; fLowWritableSegment = NULL; fLowReadOnlySegment = NULL; fVMExecutableSize = 0; fVMWritablSize = 0; fVMReadOnlySize = 0; fVMSize = 0; const Segment* highSegment = NULL; for(std::vector<Segment>::const_iterator it = fSegments.begin(); it != fSegments.end(); ++it) { const Segment& seg = *it; if ( (fLowSegment == NULL) || (seg.address() < fLowSegment->address()) ) fLowSegment = &seg; if ( (highSegment == NULL) || (seg.address() > highSegment->address()) ) highSegment = &seg; if ( seg.executable() ) { if ( (fLowExecutableSegment == NULL) || (seg.address() < fLowExecutableSegment->address()) ) fLowExecutableSegment = &seg; fVMExecutableSize += seg.size(); } else if ( seg.writable()) { if ( (fLowWritableSegment == NULL) || (seg.address() < fLowWritableSegment->address()) ) fLowWritableSegment = &seg; fVMWritablSize += seg.size(); } else { if ( (fLowReadOnlySegment == NULL) || (seg.address() < fLowReadOnlySegment->address()) ) fLowReadOnlySegment = &seg; fVMReadOnlySize += seg.size(); } } if ( (highSegment != NULL) && (fLowSegment != NULL) ) fVMSize = (highSegment->address() + highSegment->size() - fLowSegment->address() + 4095) & (-4096); // scan undefines looking, for magic ordinals if ( (symbolTableCmd != NULL) && (dynamicSymbolTableCmd != NULL) ) { const macho_nlist<P>* symbolTable = (macho_nlist<P>*)((uint8_t*)machHeader + symbolTableCmd->symoff()); const uint32_t startUndefs = dynamicSymbolTableCmd->iundefsym(); const uint32_t endUndefs = startUndefs + dynamicSymbolTableCmd->nundefsym(); for (uint32_t i=startUndefs; i < endUndefs; ++i) { uint8_t ordinal = GET_LIBRARY_ORDINAL(symbolTable[i].n_desc()); if ( ordinal == DYNAMIC_LOOKUP_ORDINAL ) fDynamicLookupLinkage = true; else if ( ordinal == EXECUTABLE_ORDINAL ) fMainExecutableLookupLinkage = true; } } if ( dyldInfo != NULL ) { if ( dyldInfo->export_off() != 0 ) { fDyldInfoExports = (uint8_t*)machHeader + dyldInfo->export_off(); } } }

TEST(Segment, Intersection_Segment_oy){ // ||oy vector<Point> ans = { Point(3,3) }; vector<Point> res = Segment(2,4,4,2).intersection(Segment(3,1,3,5)); ASSERT_EQ(ans, res); };