void computeIntersection(const std::string& wkt1, const std::string& wkt2, int expectedIntersectionNum, const std::vector<Coordinate>& intPt, double distanceTolerance) // throws ParseException { GeomPtr g1(reader.read(wkt1)); GeomPtr g2(reader.read(wkt2)); LineString* l1ptr = dynamic_cast<LineString*>(g1.get()); LineString* l2ptr = dynamic_cast<LineString*>(g2.get()); ensure(0 != l1ptr); ensure(0 != l2ptr); LineString& l1 = *l1ptr; LineString& l2 = *l2ptr; std::vector<Coordinate> pt; pt.push_back(l1.getCoordinateN(0)); pt.push_back(l1.getCoordinateN(1)); pt.push_back(l2.getCoordinateN(0)); pt.push_back(l2.getCoordinateN(1)); computeIntersection(pt, expectedIntersectionNum, intPt, distanceTolerance); }
void Stroker::miterJoiner(Stroker* stroker, const Vector& point, const Vector& beforeNormal, const Vector& afterNormal) { Vector realPoint = point; Vector after = afterNormal; Vector before = beforeNormal; stroker->inverseScale_.transform(after); stroker->inverseScale_.transform(before); stroker->inverseScale_.transform(realPoint); DynamicArray<float>* outer = &stroker->outerPoints_; DynamicArray<float>* inner = &stroker->innerPoints_; Winding winding = stroker->determineWinding(before,after); if(winding == cCounterclockwise) { swap(outer,inner); before.invert(); after.invert(); } // Undo perpendiculate Vector prevDir(-before.y_,before.x_); Vector dir(-after.y_,after.x_); Vector intersection; dir.invert(); bool intersectionExists = computeIntersection(realPoint + before, realPoint + after, prevDir,dir, intersection); if(intersectionExists) { float angle = computeAngle(dir,prevDir); float limit = 1/sin(angle/2); if(limit > stroker->miterLimit_) { stroker->bevelJoiner(stroker,point,beforeNormal,afterNormal); return; } stroker->scale_.transform(intersection); stroker->scale_.transform(after); stroker->addPoint(outer,intersection); stroker->addPoint(outer,point + after); stroker->innerJoiner(inner,point,after); } else stroker->bevelJoiner(stroker,point,beforeNormal,afterNormal); }
void object::test<2>() { computeIntersection( "LINESTRING (588743.626135934 4518924.610969561, 588732.2822865889 4518925.4314047815)", "LINESTRING (588739.1191384895 4518927.235700594, 588731.7854614238 4518924.578370095)", 1, "POINT (588733.8306132929 4518925.319423238)", 0); }
void object::test<1>() { computeIntersection( "LINESTRING (588750.7429703881 4518950.493668233, 588748.2060409798 4518933.9452804085)", "LINESTRING (588745.824857241 4518940.742239175, 588748.2060437313 4518933.9452791475)", 1, "POINT (588748.2060416829 4518933.945284994)", 0); }
void SkeletonSketcher::jointSkeleton(osgViewer::View* view, const osgGA::GUIEventAdapter& ea) { QMutexLocker locker(&mutex_); osg::Vec3 position = computeIntersection(view, ea, false); if (position.isNaN()) return; current_path_->push_back(position); if (current_path_->size() == 2) { boost::SkeletonGraph& skeleton_graph = *skeleton_graph_; size_t skeleton_size = boost::num_vertices(skeleton_graph); double min_distance_1 = std::numeric_limits<double>::max(); double min_distance_2 = std::numeric_limits<double>::max(); size_t min_idx_1 = 0; size_t min_idx_2 = 0; for (size_t i = 0; i < skeleton_size; ++ i) { double distance_1 = (skeleton_graph[i]-current_path_->at(0)).length2(); double distance_2 = (skeleton_graph[i]-current_path_->at(1)).length2(); if (min_distance_1 > distance_1) { min_distance_1 = distance_1; min_idx_1 = i; } if (min_distance_2 > distance_2) { min_distance_2 = distance_2; min_idx_2 = i; } } boost::add_edge(min_idx_1, min_idx_2, skeleton_graph); current_path_->clear(); } //if (current_path_->size() == 2) //{ // boost::SkeletonGraph& skeleton_graph = *skeleton_graph_; // boost::add_vertex(current_path_->at(0), skeleton_graph); // boost::add_vertex(current_path_->at(1), skeleton_graph); // boost::add_edge(boost::num_vertices(skeleton_graph)-1, boost::num_vertices(skeleton_graph)-2, skeleton_graph); // current_path_->clear(); //} expire(); return; }
void object::test<4>() { std::vector<Coordinate> intPt; intPt.push_back(Coordinate(4348437.0557510145, 5552597.375203926)); computeIntersection( "LINESTRING (4348433.262114629 5552595.478385733, 4348440.849387404 5552599.272022122 )", "LINESTRING (4348433.26211463 5552595.47838573, 4348440.8493874 5552599.27202212 )", 1, intPt, 0); }
void object::test<3>() { std::vector<Coordinate> intPt; intPt.push_back(Coordinate(2089426.5233462777, 1180182.3877339689)); intPt.push_back(Coordinate(2085646.6891757075, 1195618.7333999649)); computeIntersection( "LINESTRING ( 2089426.5233462777 1180182.3877339689, 2085646.6891757075 1195618.7333999649 )", "LINESTRING ( 1889281.8148903656 1997547.0560044837, 2259977.3672235999 483675.17050843034 )", 2, intPt, 0); }
void object::test<5>() { std::vector<Coordinate> pt; pt.push_back(Coordinate(4348433.262114629, 5552595.478385733)); pt.push_back(Coordinate(4348440.849387404, 5552599.272022122)); pt.push_back(Coordinate(4348433.26211463, 5552595.47838573)); pt.push_back(Coordinate(4348440.8493874, 5552599.27202212)); std::vector<Coordinate> intPt; intPt.push_back(Coordinate(4348437.0557510145, 5552597.375203926)); computeIntersection( pt, 1, intPt, 0); }
// compute intersection of a triangle with a z plane // the triangle vertices must be ordered in z Segment computeSegment(Triangle& t, float z) { Vertex** vs=t.vertices; // two vertices to return Segment segment; segment.neighbours[0]=NULL; segment.neighbours[1]=NULL; segment.orderIndex=-1; // triangle vertices are always ordered by z assert(vs[0]->z<=vs[1]->z); assert(vs[1]->z<=vs[2]->z); // ensure the triangles are correctly assigned to the layers assert(z>=vs[0]->z); assert(z<=vs[2]->z); // so we just need to check the second vertex to decide which edges // get intersected. if(z<vs[1]->z){ segment.vertices[0]=computeIntersection(*vs[0],*vs[1],z); segment.vertices[1]=computeIntersection(*vs[0],*vs[2],z); }else{ segment.vertices[0]=computeIntersection(*vs[1],*vs[2],z); segment.vertices[1]=computeIntersection(*vs[0],*vs[2],z); } Vertex n=t.normal; n.z=0; // project normal to z plane n=normalize(n); // renormalize z segment.normal=n; return segment; }
bool Object::intersects(Ray const & ray, Intersection * intersection) { // We first move the ray to object space before computing the intersection Ray localRay(ray.from - this->position, ray.direction); if(this->hasRotation) { localRay.from = this->rotationMatrix * localRay.from; // No need to normalize because the rotation matrix already is localRay.direction = this->rotationMatrix * localRay.direction; } bool hasIntersection = computeIntersection(localRay, intersection); // Move back to world coordinates if(intersection != NULL) { if(this->hasRotation) { intersection->position = (this->rotationMatrixT * intersection->position); intersection->normal = (this->rotationMatrixT * intersection->normal); } intersection->position += this->position; } return hasIntersection; }
void computeIntersection(const std::string& wkt1, const std::string& wkt2, int expectedIntersectionNum, const std::string& expectedWKT, double distanceTolerance) //throws ParseException { GeomPtr g1(reader.read(wkt1)); GeomPtr g2(reader.read(wkt2)); LineString* l1ptr = dynamic_cast<LineString*>(g1.get()); LineString* l2ptr = dynamic_cast<LineString*>(g2.get()); ensure(0 != l1ptr); ensure(0 != l2ptr); LineString& l1 = *l1ptr; LineString& l2 = *l2ptr; std::vector<Coordinate> pt; pt.push_back(l1.getCoordinateN(0)); pt.push_back(l1.getCoordinateN(1)); pt.push_back(l2.getCoordinateN(0)); pt.push_back(l2.getCoordinateN(1)); GeomPtr g(reader.read(expectedWKT)); std::auto_ptr<CoordinateSequence> cs ( g->getCoordinates() ); std::vector<Coordinate> intPt; for (size_t i=0; i<cs->size(); ++i) intPt.push_back(cs->getAt(i)); computeIntersection(pt, expectedIntersectionNum, intPt, distanceTolerance); }
IGL_INLINE void igl::copyleft::boolean::mesh_boolean_cork( const Eigen::PlainObjectBase<DerivedVA > & VA, const Eigen::PlainObjectBase<DerivedFA > & FA, const Eigen::PlainObjectBase<DerivedVB > & VB, const Eigen::PlainObjectBase<DerivedFB > & FB, const MeshBooleanType & type, Eigen::PlainObjectBase<DerivedVC > & VC, Eigen::PlainObjectBase<DerivedFC > & FC) { CorkTriMesh A,B,C; // pointer to output so it's easy to redirect on degenerate cases CorkTriMesh *ret = &C; to_cork_mesh(VA,FA,A); to_cork_mesh(VB,FB,B); switch(type) { case MESH_BOOLEAN_TYPE_UNION: if(A.n_triangles == 0) { ret = &B; }else if(B.n_triangles == 0) { ret = &A; }else { computeUnion(A,B,ret); } break; case MESH_BOOLEAN_TYPE_INTERSECT: if(A.n_triangles == 0 || B.n_triangles == 0) { ret->n_triangles = 0; ret->n_vertices = 0; }else { computeIntersection(A,B,ret); } break; case MESH_BOOLEAN_TYPE_MINUS: if(A.n_triangles == 0) { ret->n_triangles = 0; ret->n_vertices = 0; }else if(B.n_triangles == 0) { ret = &A; }else { computeDifference(A,B,ret); } break; case MESH_BOOLEAN_TYPE_XOR: if(A.n_triangles == 0) { ret = &B; }else if(B.n_triangles == 0) { ret = &A; }else { computeSymmetricDifference(A,B,&C); } break; case MESH_BOOLEAN_TYPE_RESOLVE: resolveIntersections(A,B,&C); break; default: assert(false && "Unknown type"); return; } from_cork_mesh(*ret,VC,FC); freeCorkTriMesh(&A); freeCorkTriMesh(&B); freeCorkTriMesh(&C); }
void ValueRange::computeIntersection (ValueRangeAccess dst, const ConstValueRangeAccess& a, const ConstValueRangeAccess& b) { DE_ASSERT(dst.getType() == a.getType() && dst.getType() == b.getType()); if (a.getType().isStruct()) { int numMembers = (int)a.getType().getMembers().size(); for (int ndx = 0; ndx < numMembers; ndx++) computeIntersection(dst.member(ndx), a.member(ndx), b.member(ndx)); } else if (a.getType().isArray()) { int numElements = (int)a.getType().getNumElements(); for (int ndx = 0; ndx < numElements; ndx++) computeIntersection(dst.arrayElement(ndx), a.arrayElement(ndx), b.arrayElement(ndx)); } else { int numElements = (int)a.getType().getNumElements(); switch (a.getType().getBaseType()) { case VariableType::TYPE_FLOAT: for (int ndx = 0; ndx < numElements; ndx++) { float aMin = a.component(ndx).getMin().asFloat(); float aMax = a.component(ndx).getMax().asFloat(); float bMin = b.component(ndx).getMin().asFloat(); float bMax = b.component(ndx).getMax().asFloat(); dst.component(ndx).getMin() = de::max(aMin, bMin); dst.component(ndx).getMax() = de::min(aMax, bMax); } break; case VariableType::TYPE_INT: case VariableType::TYPE_SAMPLER_2D: case VariableType::TYPE_SAMPLER_CUBE: for (int ndx = 0; ndx < numElements; ndx++) { int aMin = a.component(ndx).getMin().asInt(); int aMax = a.component(ndx).getMax().asInt(); int bMin = b.component(ndx).getMin().asInt(); int bMax = b.component(ndx).getMax().asInt(); dst.component(ndx).getMin() = de::max(aMin, bMin); dst.component(ndx).getMax() = de::min(aMax, bMax); } break; case VariableType::TYPE_BOOL: for (int ndx = 0; ndx < numElements; ndx++) { bool aMin = a.component(ndx).getMin().asBool(); bool aMax = a.component(ndx).getMax().asBool(); bool bMin = b.component(ndx).getMin().asBool(); bool bMax = b.component(ndx).getMax().asBool(); dst.component(ndx).getMin() = aMin || bMin; dst.component(ndx).getMax() = aMax && bMax; } break; default: DE_ASSERT(DE_FALSE); } } }
void ValueRange::computeIntersection (ValueRange& dst, const ConstValueRangeAccess& a, const ConstValueRangeAccess& b) { computeIntersection(dst.asAccess(), a, b); }