vector<int> grid_index::points_near_segment(Vec2 a, Vec2 b, mesh2d& idxd, int additional_cells) { /* this function will return points that are nearby a potential segment (NOT present inside mesh2d) NOTE: we could make this code specific to the use case required, meaning line-point distance, but it's not really necessary and sounds like premature optimization, on top of requiring more filtering (needs the point nearest to pt_a. */ vector<int> results; set<Vec2i> cells; Vec2i a_i(a * resolution); Vec2i b_i(b * resolution); // msgm(a_i, b_i); // if (a_i != b_i) { int x_lo = min(a_i.x, b_i.x)-additional_cells; int x_hi = max(a_i.x, b_i.x)+additional_cells; int y_lo = min(a_i.y, b_i.y)-additional_cells; int y_hi = max(a_i.y, b_i.y)+additional_cells; for (int x = x_lo; x <= x_hi; ++x) { for (int y = y_lo; y <= y_hi; ++y) { if(x>-1 && y>-1 && x<resolution && y<resolution){ cells.insert({x,y}); } } } } // else { // cells.insert(a_i); // } // msg(cells); set<int> already; for (auto&cell : cells) { // auto range = bucket_segments.equal_range(cell); auto range = bucket_points.equal_range(cell); for (auto it = range.first; it != range.second; ++it) { // if (already.count(it->second)) {msgm("skipping,",it->second); continue;} if (already.count(it->second)) {continue;} // msg(it->second); already.insert(it->second); results.push_back(it->second); } } return results; }
long matrix::mul_ijk(const matrix *a, const matrix *b, matrix *r) { int width, height; a->size(&height, &width); for (int i = 0; i < height; i++) { iter_row r_i(r, i); for (int j = 0; j < height; j++) { iter_row a_i(a, i); iter_col b_i(b, j); double n = 0; for (int k = 0; k < width; k++) { n += **a_i * **b_i; a_i++; b_i++; } **r_i = n; r_i++; } } return (long)width * width * height * 2; }
long matrix::mul_kij(const matrix *a, const matrix *b, matrix *r) { int width, height, h_div, h_mod; a->size(&height, &width); h_div = height / 16; h_mod = height % 16; for (iter_all i(r); *i; i++) **i = 0; for (int k = 0; k < width; k++) { iter_col a_i(a, k); for (int i = 0; i < height; i++) { number n = **a_i; a_i++; iter_row b_i(b, k); iter_row r_i(r, i); for (int j = 0; j < h_div; j++) { (*r_i)[0] += (*b_i)[0] * n; (*r_i)[1] += (*b_i)[1] * n; (*r_i)[2] += (*b_i)[2] * n; (*r_i)[3] += (*b_i)[3] * n; (*r_i)[4] += (*b_i)[4] * n; (*r_i)[5] += (*b_i)[5] * n; (*r_i)[6] += (*b_i)[6] * n; (*r_i)[7] += (*b_i)[7] * n; (*r_i)[8] += (*b_i)[8] * n; (*r_i)[9] += (*b_i)[9] * n; (*r_i)[10] += (*b_i)[10] * n; (*r_i)[11] += (*b_i)[11] * n; (*r_i)[12] += (*b_i)[12] * n; (*r_i)[13] += (*b_i)[13] * n; (*r_i)[14] += (*b_i)[14] * n; (*r_i)[15] += (*b_i)[15] * n; r_i += 16; b_i += 16; } for (int j = 0; j < h_mod; j++) { **r_i += **b_i * n; r_i++; b_i++; } } } return (long)width * width * height * 2; }
void grid_index::add(Vec2 a, Vec2 b, int i) { Vec2i a_i(a * resolution); Vec2i b_i(b * resolution); // msgm("adding segment", i, "coords", a, b); if (a_i != b_i) { int x_lo = min(a_i.x, b_i.x); int x_hi = max(a_i.x, b_i.x); int y_lo = min(a_i.y, b_i.y); int y_hi = max(a_i.y, b_i.y); for (int x = x_lo; x <= x_hi; ++x) { for (int y = y_lo; y <= y_hi; ++y) { bucket_segments.insert({ {x,y},i}); } } } else { //msgm("adding", i, ) bucket_segments .insert({ a_i,i}); } }
void add(Vec2 a, Vec2 b, int i) { Vec2i a_i(a / resolution); Vec2i b_i(b / resolution); if (a_i != b_i) { int x_lo = min(a_i.x, b_i.x); int x_hi = max(a_i.x, b_i.x); int y_lo = min(a_i.y, b_i.y); int y_hi = max(a_i.y, b_i.y); for (int x = x_lo; x <= x_hi; ++x) { for (int y = y_lo; y <= y_hi; ++y) { bucket_index.insert({ {x,y},i }); } } } else { bucket_index.insert({ a_i,i }); } if (i == 0) msg("SAY WAT AGAIN"); }
int grid_index::intersects(Vec2 a, Vec2 b, mesh2d& idxd, vector<pair<int,Vec2>> &results) { set<Vec2i> cells; Vec2i a_i(a * resolution); Vec2i b_i(b * resolution); // msgm(a_i, b_i); if (a_i != b_i) { int x_lo = min(a_i.x, b_i.x); int x_hi = max(a_i.x, b_i.x); int y_lo = min(a_i.y, b_i.y); int y_hi = max(a_i.y, b_i.y); for (int x = x_lo; x <= x_hi; ++x) { for (int y = y_lo; y <= y_hi; ++y) { cells.insert({x,y}); } } } else { cells.insert(a_i); } set<int> already; for (auto&cell : cells) { // auto range = bucket_index.equal_range(cell); auto range = bucket_segments.equal_range(cell); for (auto it = range.first; it != range.second; ++it) { // if (it->second > -1 || already.count(it->second)) continue; if (already.count(it->second)) continue; already.insert(it->second); // auto segment = idxd[-(it->second)-1]; auto segment = idxd[it->second]; //pair<Vec2, Vec2> segment = idxd[it->second]; Vec2 itsc_pt; bool inter = ::intersects(a, b, segment.first, segment.second, itsc_pt); if (inter) { results.push_back({ it->second, itsc_pt }); } } } return results.size(); }