//this is only really for forces made manually, not by the forces that are made by other objects(including friction and normal forces) void Force::tick(std::vector<Object *> &objects) { //check for objects to act upon for(Object *obj : objects) { vec2* corners = obj->getVertices(); //i know for now that this array has a size of 4 //for(int i = 0; i < 4; i++) //std::cout << corners[i] << std::endl; //check each side for collisions with this line vec2 intersect1 = lineIntersect(corners[0], corners[1]); //top side vec2 intersect2 = lineIntersect(corners[1], corners[2]); //right side vec2 intersect3 = lineIntersect(corners[2], corners[3]); //bottom side vec2 intersect4 = lineIntersect(corners[3], corners[0]); //left side //now check to see if each intersection is actually on the if(pointOnSegment(intersect1, corners[0], corners[1])) { std::cout << "1" << std::endl; obj->forceApplied(this, intersect1); } if(pointOnSegment(intersect2, corners[1], corners[2])) { std::cout << "1" << std::endl; obj->forceApplied(this, intersect2); } if(pointOnSegment(intersect3, corners[2], corners[3])) { std::cout << "1" << std::endl; obj->forceApplied(this, intersect3); } if(pointOnSegment(intersect4, corners[3], corners[4])) { std::cout << "1" << std::endl; obj->forceApplied(this, intersect4); } toDelete = true; //maybe a for-loop here? //check if the intersects are in-bounds - should I have a method that does this? //a different method may need to be used - b/c how would i know which point is before the other? /*if(intersect1.x > corners[0].x && intersect1.x < corners[1].x) if(intersect1.y < corners[0].y && intersect1.y > corners[1].y) std::cout << "1 is inbounds" << std::endl; if(intersect2.x > corners[1].x && intersect2.x < corners[2].x) if(intersect2.y > corners[1].y && intersect2.y < corners[2].y) std::cout << "2 is inbounds" << std::endl; if(intersect1.x > corners[2].x && intersect1.x < corners[3].x) if(intersect1.y > corners[2].y && intersect1.y < corners[3].y) std::cout << "3 is inbounds" << std::endl; if(intersect1.x > corners[3].x && intersect1.x < corners[0].x) if(intersect1.y > corners[3].y && intersect1.y < corners[0].y) std::cout << "4 is inbounds" << std::endl; */ } }
void intersectGridLinesFromSegment(const osg::Vec2d& s0, const osg::Vec2d& s1, std::vector<osg::Vec2d>& list) { struct Entry { float dist; osg::Vec2d value; }; osg::Vec2d min(FLT_MAX,FLT_MAX); osg::Vec2d max(-FLT_MAX,-FLT_MAX); if(s0.x()<min.x()) min.x() = s0.x(); if(s0.x()>max.x()) max.x() = s0.x(); if(s0.y()<min.y()) min.y() = s0.y(); if(s0.y()>max.y()) max.y() = s0.y(); if(s1.x()<min.x()) min.x() = s1.x(); if(s1.x()>max.x()) max.x() = s1.x(); if(s1.y()<min.y()) min.y() = s1.y(); if(s1.y()>max.y()) max.y() = s1.y(); list.clear(); osg::Vec2d result; { int start = static_cast<int>(floor(min[0])); int stop = static_cast<int>(ceil(max[0])); double myMin = floor(min[1]); double myMax = ceil(max[1]); for (int i = start; i <= stop; i++) { if (lineIntersect(s0,s1,osg::Vec2d(i,myMin - 1), osg::Vec2d(i,myMax + 1), result)) { list.push_back(osg::Vec2d(i, result[1])); } } } { int start = static_cast<int>(floor(min[1])); int stop = static_cast<int>(ceil(max[1])); double myMin = floor(min[0]); double myMax = ceil(max[0]); for (int j = start; j <= stop; j++) { if (lineIntersect(s0,s1,osg::Vec2d(myMin - 1, j), osg::Vec2d(myMax + 1,j ), result)) { list.push_back(osg::Vec2d(result[0], j)); } } } std::sort(list.begin(), list.end(), less_mag(s0)); }
PixelRegion PixelRegion::globalCut(Side side, int p) { if (!lineIntersect(side, p)) { return PixelRegion({ 0, 0 }, { 0, 0 }); } PixelRegion cutOff(*this); int cutSize = 0; switch (side) { case LEFT: setLeft(p); cutOff.setRight(p - cutSize); break; case TOP: setTop(p); cutOff.setBottom(p - cutSize); break; case RIGHT: setRight(p); cutOff.setLeft(p + cutSize); break; case BOTTOM: setBottom(p); cutOff.setTop(p + cutSize); break; } return cutOff; }
int isPL(point a, point b, vector<point> &res) { // `点逆时针给出,无三点共线` static double theta[MAXN]; for (int i = 0; i < n; ++i) theta[i] = (list[(i + 1) % n] - list[i]).atan2(); double delta = theta[0]; for (int i = 0; i < n; ++i) theta[i] = normalize(theta[i] - delta); int x = lower_bound(theta, theta + n, normalize((b - a).atan2() - delta)) - theta; int y = lower_bound(theta, theta + n, normalize((a - b).atan2() - delta)) - theta; for (int k = 0; k <= 1; ++k, swap(a, b), swap(x, y)) { if (y < x) y += n; int l = x, r = y, m; while (l + 1 < r) { if (sign(det(b - a, list[(m = (l + r) / 2) % n] - a)) < 0) l = m; else r = m; } l %= n, r %= n; if (sign(det(b - a, list[r] - list[l])) == 0) { if (sign(det(b - a, list[l] - a)) == 0) return -l; // `直线与 $(list[l], list[r])$ 重合` } else { point p; lineIntersect(list[l], list[r], a, b, p); if (p.onSeg(list[l], list[r])) res.push_back(p); } } return res.size(); }
bool Box2D::intersect(Box2D* l) { glm::vec4 transformedcorners1[4]; glm::vec4 transformedcorners2[4]; transformedcorners1[0] = m_transform * glm::vec4(m_corners[0][0], 1.0, m_corners[0][1], 1.0); transformedcorners1[1] = m_transform * glm::vec4(m_corners[1][0], 1.0, m_corners[1][1], 1.0); transformedcorners1[2] = m_transform * glm::vec4(m_corners[2][0], 1.0, m_corners[2][1], 1.0); transformedcorners1[3] = m_transform * glm::vec4(m_corners[3][0], 1.0, m_corners[3][1], 1.0); transformedcorners2[0] = l->m_transform * glm::vec4(l->m_corners[0][0], 1.0, l->m_corners[0][1], 1.0); transformedcorners2[1] = l->m_transform * glm::vec4(l->m_corners[1][0], 1.0, l->m_corners[1][1], 1.0); transformedcorners2[2] = l->m_transform * glm::vec4(l->m_corners[2][0], 1.0, l->m_corners[2][1], 1.0); transformedcorners2[3] = l->m_transform * glm::vec4(l->m_corners[3][0], 1.0, l->m_corners[3][1], 1.0); for(int a=0; a<4; a++) { for(int b=0; b<4; b++) { if(lineIntersect(glm::vec2(transformedcorners1[a][0], transformedcorners1[a][2]), glm::vec2(transformedcorners1[(a+1)%4][0], transformedcorners1[(a+1)%4][2]), glm::vec2(transformedcorners2[b][0], transformedcorners2[b][2]), glm::vec2(transformedcorners2[(b+1)%4][0], transformedcorners2[(b+1)%4][2]))) { m_colliders.push_back(l); return true; } } } return false; }
bool PhysicalPolygon::intersectRay(Ray ray, sf::Vector2f& intersectionPoint, sf::Vector2f& intersectionNormal) const { if (vertices_.size() < 2) return false; float minDsq{MAX_FLOAT}; sf::Vector2f closestIntersectionPoint; sf::Vector2f closestIntersectionNormal; for (auto pVertex = vertices_.begin() + 1; pVertex != vertices_.end(); pVertex++) { float t, u; if (lineIntersect(Line(ray.origin, ray.direction), LineSegment(*pVertex, *(pVertex-1)), t, u)) { if (t >= 0.0f && u >= 0.0f && u <= 1.0f) { float dsq = lengthsq(t*ray.direction); if (dsq < minDsq) { minDsq = dsq; closestIntersectionPoint = ray.origin + t*ray.direction; sf::Vector2f normal(-(*(pVertex-1)-*pVertex).y, (*(pVertex-1)-*pVertex).x); closestIntersectionNormal = normalize( (dot(ray.origin - *pVertex, normal) > 0) ? normal : -normal ); } } } } if (minDsq == MAX_FLOAT) return false; else { intersectionPoint = closestIntersectionPoint; intersectionNormal = closestIntersectionNormal; } return true; }
void Triangle2HeightField::clipTop(const std::vector<osg::Vec2d>& in, std::vector<osg::Vec2d>& out, double limit) { osg::Vec2d result; for (int i = 0; i < in.size(); i++) { const osg::Vec2d& prev = in[(in.size()+i-1)%in.size()]; const osg::Vec2d& cur = in[i]; bool previousInside = prev[1] <= limit; bool currentInside = cur[1] <= limit; if ( (previousInside && !currentInside) || (!previousInside && currentInside) ) { double min(FLT_MAX); double max(-FLT_MAX); if(prev.x()<min) min = prev.x(); if(prev.x()>max) max = prev.x(); if(cur.x()<min) min = cur.x(); if(cur.x()>max) max = cur.x(); bool intersect = lineIntersect(prev, cur, osg::Vec2d(min - 1, limit), osg::Vec2d(max + 1, limit), result, false); result[1] = limit; out.push_back(result); if (!previousInside && currentInside) { out.push_back(cur); } } else if (previousInside && currentInside) { out.push_back(cur); } } }
std::vector<float> SystemsHandler::inputStateWeights(std::deque<InputState> *inputStates, long startTime, long endTime) { long len = inputStates->size(); std::vector<float> rtn(len); for(int i=0; i<rtn.size()-1; i++) { rtn[i] = lineIntersect(startTime, endTime, inputStates->at(i+1).timeStamp, inputStates->at(i).timeStamp); } rtn[rtn.size()-1] = 0; return rtn; }
// Circle through 3 points // Computes the circle containing the 3 given points. // The 3 points are (x[0], y[0]), (x[1], y[1]) and (x[2], y[2]). // The centre of the circle is returned as (r[0], r[1]). // The radius is returned normally. If the circle is undefined (the points are collinear), // -1.0 is returned. // REQUIRES: lineIntersect double circle3pts(double x[], double y[], double r[]) { double lix[4], liy[4]; lix[0] = 0.5 * (x[0] + x[1]); liy[0] = 0.5 * (y[0] + y[1]); lix[1] = lix[0] + y[1] - y[0]; liy[1] = liy[0] + x[0] - x[1]; lix[2] = 0.5 * (x[1] + x[2]); liy[2] = 0.5 * (y[1] + y[2]); lix[3] = lix[2] + y[2] - y[1]; liy[3] = liy[2] + x[1] - x[2]; if (!lineIntersect(lix, liy, r)) return -1.0; return sqrt((r[0] - x[0]) * (r[0] - x[0]) + (r[1] - y[0]) * (r[1] - y[0])); }
bool lineSegIntersect( E e, E f, E *r = NULL ) { E blah; if( !r ) r = &blah; double c1 = cross( e.a, e.b, f.a ); double c2 = cross( e.b, e.a, f.b ); double c3 = cross( f.a, f.b, e.a ); double c4 = cross( f.b, f.a, e.b ); if( c1 * c2 < -EPS || c3 * c4 < -EPS ) return false; if( fabs( c1 ) > EPS || fabs( c2 ) > EPS || fabs( c3 ) > EPS || fabs( c4 ) > EPS ) { lineIntersect( e, f, &r->a ); r->b = r->a; return dist( e.a, r->b ) + dist( r->b, e.b ) - dist( e.a, e.b ) <= EPS && dist( f.a, r->b ) + dist( r->b, f.b ) - dist( f.a, f.b ) <= EPS; } else { // degenerate line segments? if( dist2( e.a, e.b ) <= EPS && dist2( f.a, f.b ) <= EPS && dist2( f.a, e.a ) > EPS ) return false; // Collinear case bool fa = dist( e.a, e.b ) >= dist( e.a, f.a ) + dist( e.b, f.a ) - EPS; bool fb = dist( e.a, e.b ) >= dist( e.a, f.b ) + dist( e.b, f.b ) - EPS; switch( ( fa ? 10 : 0 ) + ( fb ? 1 : 0 ) ) { case 11: // f is inside e r->a = f.a; r->b = f.b; return true; case 10: // only f.a is inside e r->a = ( dist2( e.a, f.b ) <= dist2( e.b, f.b ) ? e.a : e.b ); r->b = f.a; return true; case 1: // only f.b is inside e r->a = ( dist2( e.a, f.a ) <= dist2( e.b, f.a ) ? e.a : e.b ); r->b = f.b; return true; case 0: // both outside of e if( dist( f.a, e.a ) + dist( e.a, f.b ) <= dist( f.a, f.b ) + EPS && dist( f.a, e.b ) + dist( e.b, f.b ) <= dist( f.a, f.b ) + EPS ) { // e is inside f r->a = e.a; r->b = e.b; return true; } return false; } } return false; // Will never get here }
// Determine for each edge the intersection point. Calculates // - cutPoints_ : coordinates of all intersection points // - edgePoint : per edge -1 or the index into cutPoints void Foam::cuttingPlane::intersectEdges ( const primitiveMesh& mesh, const scalarField& dotProducts, List<label>& edgePoint ) { // Use the dotProducts to find out the cut edges. const edgeList& edges = mesh.edges(); const pointField& points = mesh.points(); // Per edge -1 or the label of the intersection point edgePoint.setSize(edges.size()); DynamicList<point> dynCuttingPoints(4*cutCells_.size()); forAll(edges, edgeI) { const edge& e = edges[edgeI]; if ( (dotProducts[e[0]] < zeroish && dotProducts[e[1]] > positive) || (dotProducts[e[1]] < zeroish && dotProducts[e[0]] > positive) ) { // Edge is cut edgePoint[edgeI] = dynCuttingPoints.size(); const point& p0 = points[e[0]]; const point& p1 = points[e[1]]; scalar alpha = lineIntersect(linePointRef(p0, p1)); if (alpha < zeroish) { dynCuttingPoints.append(p0); } else if (alpha >= 1.0) { dynCuttingPoints.append(p1); } else { dynCuttingPoints.append((1-alpha)*p0 + alpha*p1); } } else { edgePoint[edgeI] = -1; } } this->storedPoints().transfer(dynCuttingPoints); }
bool PhysicalCircle::intersectLine(Line line, sf::Vector2f& intersectionPoint, sf::Vector2f& intersectionNormal) const { float t1, t2; if (lineIntersect(line, t1, t2)) { float t = (abs(t1) < abs(t2)) ? t1 : t2; intersectionPoint = line.origin + t*line.direction; intersectionNormal = normalize(intersectionPoint - center_); } else return false; return true; }
std::pair<float, float> poly_mutator::getPos(const int cx, const int cy, const float rad, const int w, const int h) { float ix; // intersection float iy; float fcx = static_cast<float>(cx); float fcy = static_cast<float>(cy); // end points of a line from center that extends beyond rect float ex = std::cos(rad) * (w + h); float ey = std::sin(rad) * (w + h); // intersect top if (lineIntersect(fcx, fcy, ex, ey, -1, 0, w, 0, ix, iy)) return std::pair<float, float>(ix, iy); // intersect right if (lineIntersect(fcx, fcy, ex, ey, w - 1, -1, w - 1, h, ix, iy)) return std::pair<float, float>(ix, iy); // intersect bottom if (lineIntersect(fcx, fcy, ex, ey, -1, h - 1, w, h - 1, ix, iy)) return std::pair<float, float>(ix, iy); // intersect left if (lineIntersect(fcx, fcy, ex, ey, 0, -1, 0, h, ix, iy)) return std::pair<float, float>(ix, iy); // something went wrong... return std::pair<float, float>(ix, iy); }
bool lineIntersectVertSeg( qreal a1, qreal b1, qreal c1, QPoint seg[2], QPoint &intersect) { qreal a2, b2, c2; if ( ! lineEquation(seg,a2,b2,c2)) { return false; } if ( ! lineIntersect(a1,b1,c1,a2,b2,c2,intersect)) { return false; } return intersect.y() >= seg[0].y() && intersect.y() <= seg[1].y(); }
void computeDual(double vx0, double vy0, double vx1, double vy1, int a, int b, int c, int d) { float npts = NSAMPLES; for (int i = 0; i < npts; i++) { float t1 = (float)i/(float)npts; for (int j = 0; j < npts; j++) { float t2 = (float)j/(float)npts; double x1 = s_x[a] + t1 * (s_x[b]-s_x[a]); double y1 = s_y[a] + t1 * (s_y[b]-s_y[a]); double x2 = s_x[c] + t2 * (s_x[d]-s_x[c]); double y2 = s_y[c] + t2 * (s_y[d]-s_y[c]); float t; int result = lineIntersect(vx0, vy0, vx1, vy1, x1, y1, x2, y2, t); if (result && t >= 0 && t <= 1.0) { intersection_count[i][j]++; } } } }
//----------------------------------------------------------------------------- // displayDual //----------------------------------------------------------------------------- void displayDual(double vx0, double vy0, double vx1, double vy1, float r, float g, float b) { glColor4f(r, g, b, 0.025); float npts = NSAMPLES; for (int i = 0; i < npts; i++) { float t1 = (float)i/(float)npts; for (int j = 0; j < npts; j++) { float t2 = (float)j/(float)npts; double x1 = s1_x[0] + t1 * (s1_x[1]-s1_x[0]); double y1 = s1_y[0] + t1 * (s1_y[1]-s1_y[0]); double x2 = s2_x[0] + t2 * (s2_x[1]-s2_x[0]); double y2 = s2_y[0] + t2 * (s2_y[1]-s2_y[0]); float t; int result = lineIntersect(vx0, vy0, vx1, vy1, x1, y1, x2, y2, t); if (result && t >= 0 && t <= 1.0) { intersection_count[i][j]++; glBegin(GL_POINTS); glVertex3f(t1, t2, 0.0); glEnd(); } } } }
bool PhysicalCircle::intersectLineSegment(LineSegment lineSegment, sf::Vector2f& intersectionPoint, sf::Vector2f& intersectionNormal) const { float t1, t2; if (lineIntersect(Line(lineSegment.start, lineSegment.end - lineSegment.start), t1, t2)) { float t; if (t1 >= 0.0f && t1 <= 1.0f) if (t2 >= 0.0f && t1 <= 1.0f) t = (t1 < t2) ? t1 : t2; else t = t1; else if (t2 >= 0.0f && t2 <= 1.0f) t = t2; else return false; intersectionPoint = lineSegment.start + t*(lineSegment.end - lineSegment.start); intersectionNormal = normalize(intersectionPoint - center_); } else return false; return true; }
bool PhysicalCircle::intersectRay(Ray ray, sf::Vector2f& intersectionPoint, sf::Vector2f& intersectionNormal) const { float t1, t2; if (lineIntersect(Line(ray.origin, ray.direction), t1, t2)) { float t; if (t1 >= 0.0f) if (t2 >= 0.0f) t = (t1 < t2) ? t1 : t2; else t = t1; else if (t2 >= 0.0f) t = t2; else return false; intersectionPoint = ray.origin + t*ray.direction; intersectionNormal = normalize(intersectionPoint - center_); } else return false; return true; }
vec2 Force::lineIntersect(vec4 line) const { return lineIntersect(vec2(line.x, line.y), vec2(line.z, line.w)); }
bool lineIntersect(Line line1, Line line2, float* i_x, float* i_y) { return lineIntersect(line1.getPoint1().x, line1.getPoint1().y, line1.getPoint2().x, line1.getPoint2().y, line2.getPoint1().x, line2.getPoint1().y, line2.getPoint2().x, line2.getPoint2().y, i_x, i_x); }
inline bool lineIntersect( E e, E f, P *r = NULL ) { return lineIntersect( e.a, e.b, f.a, f.b, *r ); }
bool PhysicalPolygon::intersectCircle(float radius, LineSegment displacement, sf::Vector2f& centerAfterCollision, sf::Vector2f& intersectionPoint, sf::Vector2f& intersectionNormal) const { float minDsq{MAX_FLOAT}; sf::Vector2f closestCenterAfterCollision; sf::Vector2f closestIntersectionPoint; sf::Vector2f closestIntersectionNormal; sf::Vector2f p1; sf::Vector2f p2; for (auto pVertex = vertices_.begin() + 1; pVertex != vertices_.end(); pVertex++) { sf::Vector2f normal(-(*(pVertex-1)-*pVertex).y, (*(pVertex-1)-*pVertex).x); normal = normalize( (dot(displacement.start - *pVertex, normal) > 0) ? normal : -normal ); Line shiftedLine(displacement.start - normal * radius, displacement.end - displacement.start); float t, u; if (lineIntersect(shiftedLine, LineSegment(*(pVertex - 1), *pVertex), t, u)) { if (t >= 0.0f && t <= 1.0f && u >= 0.0f && u <= 1.0f) { float dsq = lengthsq(t*shiftedLine.direction); if (dsq < minDsq) { minDsq = dsq; closestCenterAfterCollision = displacement.start + t*shiftedLine.direction; closestIntersectionPoint = shiftedLine.origin + t*shiftedLine.direction; closestIntersectionNormal = normal; p1 = *(pVertex-1); // end points to exclude p2 = *pVertex; } } } } for (auto pVertex = vertices_.begin(); pVertex != vertices_.end(); pVertex++) { if (*pVertex == p1 || *pVertex == p2) continue; sf::Vector2f v = displacement.end - displacement.start; sf::Vector2f p = *pVertex; sf::Vector2f w = p - displacement.start; float a = dot(w, v)/lengthsq(v); float b = radius * radius - lengthsq(w - a*v); if (b >= 0) { float d = a - sqrtf(b/dot(v, v)); if (d > 0.0f && d < 1.0f && d < sqrtf(minDsq)) { minDsq = d*d; closestCenterAfterCollision = displacement.start + d*v; closestIntersectionPoint = p; closestIntersectionNormal = closestCenterAfterCollision - p; } } } if (minDsq == MAX_FLOAT) return false; else { centerAfterCollision = closestCenterAfterCollision - 0.1f*normalize(displacement.end - displacement.start); intersectionPoint = closestIntersectionPoint; intersectionNormal = normalize(closestIntersectionNormal); } return true; }