public void FindIntersectionTest(Vector2 l1_p1, Vector2 l1_p2, Vector2 l2_p1, Vector2 l2_p2, int expectedIntersectionType, IntersectionResult expectedIntersectionResult) { int intersectionType = UnityVectorExtensions.FindIntersection(l1_p1, l1_p2, l2_p1, l2_p2, out Vector2 intersection); Assert.That(intersectionType, Is.EqualTo(expectedIntersectionType)); switch (expectedIntersectionResult) { case IntersectionResult.Zero: Assert.That(intersection, Is.EqualTo(Vector2.zero).Using(Vector2EqualityComparer.Instance)); break; case IntersectionResult.Infinity: Assert.That(float.IsInfinity(intersection.x), Is.True); Assert.That(float.IsInfinity(intersection.y), Is.True); break; case IntersectionResult.l1_p1: Assert.That(intersection, Is.EqualTo(l1_p1).Using(Vector2EqualityComparer.Instance)); break; case IntersectionResult.l1_p2: Assert.That(intersection, Is.EqualTo(l1_p2).Using(Vector2EqualityComparer.Instance)); break; case IntersectionResult.l2_p1: Assert.That(intersection, Is.EqualTo(l2_p1).Using(Vector2EqualityComparer.Instance)); break; case IntersectionResult.l2_p2: Assert.That(intersection, Is.EqualTo(l2_p2).Using(Vector2EqualityComparer.Instance)); break; } }
protected override void OnPolygonComplete(Polygon2f input) { polygon = input; polygon.BuildIndices(); polygon.BuildHoleIndices(); result = null; }
// If N0 and N1 are parallel, either the planes are parallel and separated // or the same plane. In both cases, 'false' is returned. Otherwise, // the intersection line is // L(t) = t*Cross(N0,N1)/|Cross(N0,N1)| + c0*N0 + c1*N1 // for some coefficients c0 and c1 and for t any real number (the line // parameter). Taking dot products with the normals, // d0 = Dot(N0,L) = c0*Dot(N0,N0) + c1*Dot(N0,N1) = c0 + c1*d // d1 = Dot(N1,L) = c0*Dot(N0,N1) + c1*Dot(N1,N1) = c0*d + c1 // where d = Dot(N0,N1). These are two equations in two unknowns. The // solution is // c0 = (d0 - d*d1)/det // c1 = (d1 - d*d0)/det // where det = 1 - d^2. public bool Find() { if (Result != IntersectionResult.NotComputed) { return(Result != IntersectionResult.NoIntersection); } double dot = plane0.Normal.Dot(plane1.Normal); if (Math.Abs(dot) >= 1 - MathUtil.ZeroTolerance) { double cDiff = dot >= 0 ? Plane0.Constant - Plane1.Constant : Plane0.Constant + Plane1.Constant; if (Math.Abs(cDiff) < MathUtil.ZeroTolerance) { Type = IntersectionType.Plane; Result = IntersectionResult.NoIntersection; Plane = new Plane3d(plane0.Normal, plane0.Constant); } Type = IntersectionType.Empty; Result = IntersectionResult.NoIntersection; return(false); } double invDet = 1 / (1 - dot * dot); double c0 = (plane0.Constant - dot * plane1.Constant) * invDet; double c1 = (plane1.Constant - dot * plane0.Constant) * invDet; Quantity = 1; Type = IntersectionType.Line; Line = new Line3d(c0 * plane0.Normal + c1 * plane1.Normal, plane0.Normal.UnitCross(plane1.Normal)); return(true); }
//求出轴网和基准线的相交点,以点的位置比例和轴网建立字典 public IDictionary <double, Grid> GetInterGridDict(IList <Element> girdsElements, Line baseCurve) { IDictionary <double, Grid> dictParaGrid = new Dictionary <double, Grid>(); //创建字典,double为相交点在基准线上的比例位置, Grid为相交轴线 foreach (Element ele in girdsElements) //求出各个轴网与所画直线的关系 { Grid grid_tmep = ele as Grid; Line grid_curve = grid_tmep.Curve as Line; XYZ direction = grid_curve.Direction; XYZ middleXyz = (grid_curve.GetEndPoint(0) + grid_curve.GetEndPoint(1)) / 2;//求出线段的中点 double d = 10000; XYZ startPoint = middleXyz + direction * d; XYZ endPoint = middleXyz - direction * d; Line grid_curve_newLine = Line.CreateBound(startPoint, endPoint); IntersectionResultArray results; SetComparisonResult result = baseCurve.Intersect(grid_curve_newLine, out results); if (result == SetComparisonResult.Overlap) //判断基准线是否与轴网相交 { if (results != null && results.Size == 1) //判断交点的数量是否为1 { double intersectPara; IntersectionResult iResult = results.get_Item(0); //发现无法直接获取相交点在基准线上的二维比例位置 XYZ intersectXYZ = iResult.XYZPoint; //得到基准线和轴网的交点 IntersectionResult projectXyz = baseCurve.Project(intersectXYZ); //获得交点在基准线上的投影点 intersectPara = projectXyz.Parameter; //将投影点转化为在基准线上的一维距离比例位置 dictParaGrid.Add(intersectPara, grid_tmep); } } } return(dictParaGrid); }
public void DoorRenumbering(Curve curve) { List <LocationPoint> points = new List <LocationPoint>(); Dictionary <Element, double> sort = new Dictionary <Element, double>(); foreach (Element element in elements) { FamilyInstance door = element as FamilyInstance; XYZ point = door.GetTransform().Origin; if (point == null) { continue; } IntersectionResult closestPoint = curve.Project(point); sort.Add(element, curve.ComputeNormalizedParameter(closestPoint.Parameter)); } List <Element> sorted = sort.OrderBy(x => x.Value).Select(x => x.Key).ToList(); using (Transaction t = new Transaction(doc, "Rename Mark Values")) { t.Start(); foreach (Element el in sorted) { el.LookupParameter("Mark").Set(String.Format("{0}{1}{2}", prefix, increment.ToString(format), suffix)); increment++; } t.Commit(); } }
/// <summary> /// 两射线求交点 /// </summary> /// <param name="rayOrigin1"></param> /// <param name="rayDirection1"></param> /// <param name="rayOrigin2"></param> /// <param name="rayDirection2"></param> /// <returns></returns> public static IntersectionResult RayToRayIntersection(Vector2 rayOrigin1, Vector2 rayDirection1, Vector2 rayOrigin2, Vector2 rayDirection2) { IntersectionResult result = new IntersectionResult(); rayDirection1 = rayDirection1.normalized; rayDirection2 = rayDirection2.normalized; float r, s, d; if (rayDirection1 != rayDirection2) { d = Cross(rayDirection1, rayDirection2); if (d != 0) { Vector2 rayOrigin2ToRayOrigin1 = rayOrigin1 - rayOrigin2; r = Cross(rayDirection2, rayOrigin2ToRayOrigin1) / d; s = Cross(rayDirection1, rayOrigin2ToRayOrigin1) / d; if (r >= 0) { if (s >= 0) { Vector2 intersectionPoint = rayOrigin1 + rayDirection1 * r; result.AddIntersectionPoint(intersectionPoint); } } } } return(result); }
public bool Find() { if (Result != IntersectionResult.NotComputed) { return(Result == IntersectionResult.Intersects); } // [RMS] if either line direction is not a normalized vector, // results are garbage, so fail query if (segment.Direction.IsNormalized == false) { Type = IntersectionType.Empty; Result = IntersectionResult.InvalidQuery; return(false); } SegmentParam0 = -segment.Extent; SegmentParam1 = segment.Extent; DoClipping(ref SegmentParam0, ref SegmentParam1, segment.Center, segment.Direction, box, solid, ref Quantity, ref Point0, ref Point1, ref Type); Result = (Type != IntersectionType.Empty) ? IntersectionResult.Intersects : IntersectionResult.NoIntersection; return(Result == IntersectionResult.Intersects); }
private void GetIntersectionPoints() { IntersectionResultArray iresArray1; SetComparisonResult result1 = Line1.Intersect(Line3, out iresArray1); IntersectionResult ires1 = iresArray1.get_Item(0); Point1 = ires1.XYZPoint; IntersectionResultArray iresArray2; SetComparisonResult result2 = Line1.Intersect(Line4, out iresArray2); IntersectionResult ires2 = iresArray2.get_Item(0); Point2 = ires2.XYZPoint; IntersectionResultArray iresArray3; SetComparisonResult result3 = Line2.Intersect(Line3, out iresArray3); IntersectionResult ires3 = iresArray3.get_Item(0); Point3 = ires3.XYZPoint; IntersectionResultArray iresArray4; SetComparisonResult result4 = Line2.Intersect(Line4, out iresArray4); IntersectionResult ires4 = iresArray4.get_Item(0); Point4 = ires4.XYZPoint; }
/***************************************************/ /**** Public methods ****/ /***************************************************/ public static bool IsInside(this XYZ point, Solid solid, double tolerance) { if (solid == null || solid.Volume < tolerance) { return(false); } SolidCurveIntersectionOptions sco = new SolidCurveIntersectionOptions(); sco.ResultType = SolidCurveIntersectionMode.CurveSegmentsInside; XYZ[] vectors = { XYZ.BasisX, XYZ.BasisY, XYZ.BasisZ }; foreach (XYZ vector in vectors) { Line l = Line.CreateBound(point - vector, point + vector); SolidCurveIntersection sci = solid.IntersectWithCurve(l, sco); if (sci == null) { continue; } for (int i = 0; i < sci.SegmentCount; i++) { Curve c = sci.GetCurveSegment(i); IntersectionResult ir = c.Project(point); if (ir != null && ir.Distance <= tolerance) { return(true); } } } return(false); }
private XYZ GetPointIntersecWithWall(Wall wall, Line cuttingLine, out bool isOvelapWithAnotherWindown) { isOvelapWithAnotherWindown = false; List <Solid> solids = GetSolidFromWall(wall); foreach (Solid solid in solids) { if (solid.Faces != null && solid.Faces.Size > 0) { foreach (Face face in solid.Faces) { SetComparisonResult result = face.Intersect(cuttingLine, out IntersectionResultArray intersectionResultArray); if (result == SetComparisonResult.Overlap || result == SetComparisonResult.Subset) { if (intersectionResultArray != null) { for (int i = 0; i < intersectionResultArray.Size; i++) { IntersectionResult intersectionResult = intersectionResultArray.get_Item(i); if (intersectionResult.XYZPoint != null) { return(intersectionResult.XYZPoint); } } } else { isOvelapWithAnotherWindown = true; } } } } } return(null); }
public override IIntersectionResult Intersection(Vector3d direction, Vector3d position) { Vector3d spherePositionProjected = ProjectSpherePosition(direction, position); if (spherePositionProjected == null) { return(null); } Vector3d distance = (_position - position) - spherePositionProjected; if (distance.Length() > _radius) { return(null); } double c = System.Math.Sqrt(_radius * _radius - distance.Length() * distance.Length()); double i1 = ((_position - position).Dot(direction) - c); double i2 = ((_position - position).Dot(direction) + c); IntersectionResult intersectionResult = new IntersectionResult(); intersectionResult.Intersection = position + direction * i1; intersectionResult.IntersectionDistance = (intersectionResult.Intersection - position).Length(); intersectionResult.Object = this; return(intersectionResult); }
private static PointData ConvertToPointData(Face revitFace, FMEPoint fmePoint) { PointData pointData = null; try { string[] coordinates = fmePoint.Coordinate.Split(','); XYZ xyz = null; if (coordinates.Length == 3) { xyz = new XYZ(double.Parse(coordinates[0]), double.Parse(coordinates[1]), double.Parse(coordinates[2])); } UV uv = null; if (null != revitFace && null != xyz) { IntersectionResult intersectionResult = revitFace.Project(xyz); if (null != intersectionResult) { uv = intersectionResult.UVPoint; } } pointData = new PointData(uv, xyz, fmePoint.PointValue); } catch (Exception ex) { string message = ex.Message; } return(pointData); }
// Find-intersection query. The point of intersection is // P = origin + t*direction. public bool Find() { var DdN = line.Direction.Dot(plane.Normal); var signedDistance = plane.DistanceTo(line.Origin); if (Math.Abs(DdN) > MathUtil.ZeroTolerance) { // The line is not parallel to the plane, so they must intersect. lineParameter = -signedDistance / DdN; Type = IntersectionType.Point; Result = IntersectionResult.Intersects; return true; } // The Line and plane are parallel. Determine if they are numerically // close enough to be coincident. if (Math.Abs(signedDistance) <= MathUtil.ZeroTolerance) { // The line is coincident with the plane, so choose t = 0 for the // parameter. lineParameter = 0; Type = IntersectionType.Line; Result = IntersectionResult.Intersects; return true; } Type = IntersectionType.Empty; Result = IntersectionResult.NoIntersection; return false; }
private static IList <double> CreateRoughParametricTessellation(Curve curve) { IList <XYZ> originalTessellation = curve.Tessellate(); int numPoints = originalTessellation.Count; int numTargetPoints = Math.Min(numPoints, 12); int numInteriorPoints = numTargetPoints - 2; IList <double> roughTessellation = new List <double>(numTargetPoints); // Skip the first point as redundant. IntersectionResult result = null; for (int ii = 0; ii < numInteriorPoints; ii++) { XYZ initialPoint = originalTessellation[(int)(numPoints - 2) * (ii + 1) / numInteriorPoints]; result = curve.Project(initialPoint); roughTessellation.Add(result.Parameter); } XYZ finalPoint = originalTessellation[numPoints - 1]; result = curve.Project(finalPoint); roughTessellation.Add(result.Parameter); return(roughTessellation); }
// Bullet pattern generation "borrowed" from user Felsir on gamedev.stackexchange // from the following post https://gamedev.stackexchange.com/questions/124688/how-to-create-shockwave-of-objects-in-other-shapes-than-circle private Vector2[] CreateBulletPattern(int segments, double offset, int numberofbullets) { List <Linesegment> polygon = CreateRadialPolygon(segments, offset); List <Vector2> bulletdirections = new List <Vector2>(); double bulletangle = (2 * Math.PI) / numberofbullets; for (int i = 0; i < numberofbullets; i++) { foreach (Linesegment l in polygon) { //do an intersection; if the line intersects add a bullet to the pattern. IntersectionResult r = ProcessIntersection(l, Vector2.Zero, i * bulletangle); if (r.intersection) { //check if the intersectionpoint already is in the result- //this may be if the intersectionpoint is one of the endpoints of the line segment. if (!bulletdirections.Contains(r.intersectionPoint)) { bulletdirections.Add(r.intersectionPoint); } } } } return(bulletdirections.ToArray()); }
public bool Test() { double DdN = line.Direction.Dot(plane.Normal); if (Math.Abs(DdN) > MathUtil.ZeroTolerance) { // The line is not parallel to the plane, so they must intersect. // The line parameter is *not* set, since this is a test-intersection // query. Quantity = 1; Type = IntersectionType.Point; return(true); } // The line and plane are parallel. Determine if they are numerically // close enough to be coincident. double signedDistance = plane.DistanceTo(line.Origin); if (Math.Abs(signedDistance) <= MathUtil.ZeroTolerance) { Quantity = 1; Type = IntersectionType.Line; return(true); } Result = IntersectionResult.NoIntersection; Type = IntersectionType.Empty; return(false); }
public bool Find() { if (Result != IntersectionResult.NotComputed) { return(Result == IntersectionResult.Intersects); } // [RMS] if either line direction is not a normalized vector, // results are garbage, so fail query if (ray.Direction.IsNormalized == false) { Type = IntersectionType.Empty; Result = IntersectionResult.InvalidQuery; return(false); } RayParam0 = 0.0; RayParam1 = double.MaxValue; IntrLine3AxisAlignedBox3.DoClipping(ref RayParam0, ref RayParam1, ref ray.Origin, ref ray.Direction, ref box, true, ref Quantity, ref Point0, ref Point1, ref Type); Result = (Type != IntersectionType.Empty) ? IntersectionResult.Intersects : IntersectionResult.NoIntersection; return(Result == IntersectionResult.Intersects); }
private List <Line> GetSquare(Line infLine0, Line infLine1, Line infLine2, Line infLine3) { IntersectionResultArray iresArray1; SetComparisonResult result1 = infLine0.Intersect(infLine2, out iresArray1); IntersectionResult ires1 = iresArray1.get_Item(0); XYZ point1 = ires1.XYZPoint; IntersectionResultArray iresArray2; SetComparisonResult result2 = infLine0.Intersect(infLine3, out iresArray2); IntersectionResult ires2 = iresArray2.get_Item(0); XYZ point2 = ires2.XYZPoint; IntersectionResultArray iresArray3; SetComparisonResult result3 = infLine1.Intersect(infLine2, out iresArray3); IntersectionResult ires3 = iresArray3.get_Item(0); XYZ point3 = ires3.XYZPoint; IntersectionResultArray iresArray4; SetComparisonResult result4 = infLine1.Intersect(infLine3, out iresArray4); IntersectionResult ires4 = iresArray4.get_Item(0); XYZ point4 = ires4.XYZPoint; List <Line> retLines = new List <Line>(); retLines.Add(Line.CreateBound(point1, point2)); retLines.Add(Line.CreateBound(point2, point4)); retLines.Add(Line.CreateBound(point4, point3)); retLines.Add(Line.CreateBound(point3, point1)); return(retLines); }
/// <summary> /// 射线与线段的交点 /// </summary> /// <param name="rayOrigin"></param> /// <param name="rayDirection"></param> /// <param name="lineStart"></param> /// <param name="lineEnd"></param> /// <returns></returns> public static IntersectionResult RayToLineSegmentIntersection(Vector2 rayOrigin, Vector2 rayDirection, Vector2 lineStart, Vector2 lineEnd) { IntersectionResult result = new IntersectionResult(); Vector2 v1 = rayOrigin - lineStart; Vector2 v2 = lineEnd - lineStart; Vector2 v3 = new Vector2(-rayDirection.y, rayDirection.x); var dot = Vector2.Dot(v2, v3); if (Math.Abs(dot) < float.Epsilon) { return(result); } var t1 = Cross(v2, v1) / dot; var t2 = Vector2.Dot(v1, v3) / dot; if (t1 >= 0.0 && (t2 >= 0.0 && t2 <= 1.0)) { result.AddIntersectionPoint(rayOrigin + t1 * rayDirection); } return(result); }
/// <summary> /// Add a new vertice in order in the list of vertices of the polygon given the IntersectionResultArray. /// </summary> /// <param name="points"></param> /// <param name="resultArray"></param> /// <param name="curve"></param> private static CircularLinkedListNode <UV> AddPointsInList(CircularLinkedList <UV> points, IntersectionResultArray resultArray, Curve curve) { UV p0 = VectorManipulator.ProjectInPlaneXY(curve.GetEndPoint(0)); CircularLinkedListNode <UV> newNode = null; CircularLinkedListNode <UV> node = FindPoint(points, p0); IntersectionResultArrayIterator iterator = resultArray.ForwardIterator(); iterator.Reset(); while (iterator.MoveNext()) { IntersectionResult result = iterator.Current as IntersectionResult; UV intersectionPoint = VectorManipulator.ProjectInPlaneXY(result.XYZPoint); newNode = points.AddAfter(node, intersectionPoint); } if (newNode.Next.Value.IsAlmostEqualTo(newNode.Value)) { points.Remove(newNode.Next.Value); } else if (newNode.Previous.Value.IsAlmostEqualTo(newNode.Value)) { points.Remove(newNode.Previous.Value); } return(newNode); }
private static void IncrementalRaycast( Vector3 start, Vector3 end, ProcessIntersection onIntersect, ShouldContinueRayCast shouldContinue ) { RaycastHit hitInfo; Vector3 ray = end - start; Vector3 dx = ray.normalized; Vector3 remaining = end - start; dx.Scale(new Vector3(.01f, .01f, .01f)); while (Physics.Raycast(start, dx, out hitInfo, remaining.magnitude, instance.collisionMask)) { remaining -= (hitInfo.point - start); start = (hitInfo.point + dx); //hit object must have an obstacle script if (hitInfo.collider.transform.GetComponent <Obstacle>() != null) { IntersectionResult result = new IntersectionResult(hitInfo); onIntersect(result); if (!shouldContinue(result)) { break; } } } }
/// <summary> /// 射线与圆相交交点 /// </summary> /// <param name="rayOrigin"></param> /// <param name="rayDirection"></param> /// <param name="circleCenter"></param> /// <param name="radius"></param> /// <returns></returns> public static IntersectionResult RayToCircleIntersection(Vector2 rayOrigin, Vector2 rayDirection, Vector2 circleCenter, float radius) { IntersectionResult result = new IntersectionResult(); rayDirection = rayDirection.normalized; Vector2 rayOriginToCircleCenter = circleCenter - rayOrigin; float rayOriginToCircleCenterLength = rayOriginToCircleCenter.sqrMagnitude; float dot = Vector2.Dot(rayDirection, rayOriginToCircleCenter.normalized); Vector2 pointOnRayVerticalWithCircleCenter = rayOrigin + rayDirection * (dot * Mathf.Sqrt(rayOriginToCircleCenterLength)); float squareDistanceToCenter = Vector2.Dot(pointOnRayVerticalWithCircleCenter - circleCenter, pointOnRayVerticalWithCircleCenter - circleCenter); if (squareDistanceToCenter > radius * radius) { return(result); } if (squareDistanceToCenter == radius * radius) { result.AddIntersectionPoint(pointOnRayVerticalWithCircleCenter); return(result); } float distanceToIntersection = 0f; float distanceToCenter = 0f; if (squareDistanceToCenter == 0) { distanceToIntersection = radius; } else { distanceToCenter = (float)Math.Sqrt(squareDistanceToCenter); distanceToIntersection = (float)Math.Sqrt(radius * radius - squareDistanceToCenter); } float lineSegmentLength = 1 / Mathf.Sqrt(rayOriginToCircleCenterLength); rayOriginToCircleCenter *= lineSegmentLength; rayOriginToCircleCenter *= distanceToIntersection; Vector2 solution1 = pointOnRayVerticalWithCircleCenter + rayOriginToCircleCenter; if (Vector2.Distance(solution1, rayOrigin) > 0) { result.AddIntersectionPoint(solution1); } Vector2 solution2 = pointOnRayVerticalWithCircleCenter - rayOriginToCircleCenter; if (Vector2.Distance(solution2, rayOrigin) > 0) { result.AddIntersectionPoint(solution2); } return(result); }
public override void Evaluate(FSharpList <Value> args, Dictionary <PortData, Value> outPuts) { var xyz = (XYZ)((Value.Container)args[0]).Item; var inputArg = ((Value.Container)args[1]).Item; XYZ pt; UV uv; double d; Edge e; double et; var face = inputArg is Face ? (Face)inputArg : null; if (face == null && !(inputArg is Plane)) { throw new Exception(" Project Point On Face needs Face or Plane as argument no. 1"); } if (face == null) { var pln = (Plane)inputArg; uv = new UV( pln.XVec.DotProduct(xyz - pln.Origin), pln.YVec.DotProduct(xyz - pln.Origin)); pt = pln.Origin + uv[0] * pln.XVec + uv[1] * pln.YVec; d = xyz.DistanceTo(pt); e = null; et = 0.0; } else { IntersectionResult ir = face.Project(xyz); pt = ir.XYZPoint; uv = ir.UVPoint; d = ir.Distance; e = null; et = 0; try { e = ir.EdgeObject; } catch { } try { et = ir.EdgeParameter; } catch { } } pts.Add(pt); outPuts[_xyzPort] = Value.NewContainer(xyz); outPuts[_uvPort] = Value.NewContainer(uv); outPuts[_dPort] = Value.NewNumber(d); outPuts[_edgePort] = Value.NewContainer(e); outPuts[_edgeTPort] = Value.NewNumber(et); }
private double?GetTrimParameter(IFCData trim, IFCCurve basisCurve, IFCTrimmingPreference trimPreference, bool secondAttempt) { bool preferParam = !(trimPreference == IFCTrimmingPreference.Cartesian); if (secondAttempt) { preferParam = !preferParam; } double vertexEps = MathUtil.VertexEps; IFCAggregate trimAggregate = trim.AsAggregate(); foreach (IFCData trimParam in trimAggregate) { if (!preferParam && (trimParam.PrimitiveType == IFCDataPrimitiveType.Instance)) { IFCAnyHandle trimParamInstance = trimParam.AsInstance(); XYZ trimParamPt = IFCPoint.ProcessScaledLengthIFCCartesianPoint(trimParamInstance); if (trimParamPt == null) { IFCImportFile.TheLog.LogWarning(basisCurve.Id, "Invalid trim point for basis curve.", false); continue; } try { IntersectionResult result = basisCurve.Curve.Project(trimParamPt); if (result.Distance < vertexEps) { return(result.Parameter); } IFCImportFile.TheLog.LogWarning(basisCurve.Id, "Cartesian value for trim point not on the basis curve.", false); } catch { IFCImportFile.TheLog.LogWarning(basisCurve.Id, "Cartesian value for trim point not on the basis curve.", false); } } else if (preferParam && (trimParam.PrimitiveType == IFCDataPrimitiveType.Double)) { double trimParamDouble = trimParam.AsDouble(); if (basisCurve.Curve.IsCyclic) { trimParamDouble = IFCUnitUtil.ScaleAngle(trimParamDouble); } return(trimParamDouble); } } // Try again with opposite preference. if (!secondAttempt) { return(GetTrimParameter(trim, basisCurve, trimPreference, true)); } return(null); }
private Segment closeIfCollinear(Segment s1, int end1, Segment s2, int end2) { Line ln1 = s1.Curve as Line; Line ln2 = s2.Curve as Line; if (ln1 == null) { return(null); } if (ln2 == null) { return(null); } double ang = ln1.Direction.AngleTo(ln2.Direction); if ((ang < 0.01) || (ang > Math.PI * 0.9)) { // it is collinear or close } else { return(null); } // midpoint has changed, so we need to refigure: XYZ p1a = ln1.GetEndPoint(0); XYZ p1b = ln1.GetEndPoint(1); XYZ p2a = ln2.GetEndPoint(0); XYZ p2b = ln2.GetEndPoint(1); // need to make the lines unbound ln1 = Line.CreateUnbound(ln1.Origin, ln1.Direction); ln2 = Line.CreateUnbound(ln2.Origin, ln2.Direction); XYZ s1MidPoint = new XYZ((p1a.X + p1b.X) / 2.0, (p1a.Y + p1b.Y) / 2.0, (p1a.Z + p1b.Z) / 2.0); XYZ s2MidPoint = new XYZ((p2a.X + p2b.X) / 2.0, (p2a.Y + p2b.Y) / 2.0, (p2a.Z + p2b.Z) / 2.0); IntersectionResult result1 = ln1.Project(s2MidPoint); IntersectionResult result2 = ln2.Project(s1MidPoint); if ((result1.Distance < 0.02) && (result2.Distance < 0.02)) { // collinear or close: Line stitch = Line.CreateBound(s1.Curve.GetEndPoint(end1), s2.Curve.GetEndPoint(end2)); Segment fix = new Segment() { Curve = stitch, Draw = true, Length = stitch.Length }; return(fix); } return(null); }
/* * Might cause memory leaks if interrupted before NativeArrays are disposed */ private static void ParallelIncrementalRaycast( List <ParallelIncrementalRaycastData> paths ) { List <ParallelIncrementalRaycastData> remainingPaths = new List <ParallelIncrementalRaycastData>(paths); NativeArray <RaycastHit> results = default(NativeArray <RaycastHit>); NativeArray <RaycastCommand> commands = default(NativeArray <RaycastCommand>); do { results = new NativeArray <RaycastHit>(remainingPaths.Count, Allocator.TempJob); commands = new NativeArray <RaycastCommand>(remainingPaths.Count, Allocator.TempJob); for (int i = 0; i < remainingPaths.Count; i++) { commands[i] = new RaycastCommand( remainingPaths[i].start, remainingPaths[i].dx, remainingPaths[i].remaining.magnitude, instance.collisionMask ); } JobHandle handle = RaycastCommand.ScheduleBatch(commands, results, 1, default(JobHandle)); handle.Complete(); for (int i = 0; i < remainingPaths.Count; i++) { ParallelIncrementalRaycastData data = remainingPaths[i]; RaycastHit batchedHit = results[i]; data.hit = batchedHit; if (batchedHit.collider == null) { continue; } data.remaining -= (batchedHit.point - data.start); data.start = (batchedHit.point + data.dx); if (batchedHit.collider.transform.GetComponent <Obstacle>() != null) { IntersectionResult result = new IntersectionResult(batchedHit); data.onIntersect(result); } } remainingPaths.RemoveAll( path => !path.continueCondition(path.result) || path.hit.collider == null ); results.Dispose(); commands.Dispose(); } while (remainingPaths.Count > 0); }
/// <summary> /// Compute the distance between two planar faces. /// </summary> /// <param name="face1">Face 1</param> /// <param name="face2">Face 2</param> /// <returns>Distance of the two planar faces</returns> private static double GetDistance(PlanarFace face1, PlanarFace face2) { BoundingBoxUV boxUV = face2.GetBoundingBox(); UV center = (boxUV.Max + boxUV.Min) * 0.5; XYZ centerPt = face2.Evaluate(center); IntersectionResult result = face1.Project(centerPt); return(face1.Project(centerPt).Distance); }
public void Update() { IntersectionResults.Clear(); IntersectionResult previousResult = new IntersectionResult() { OutgoingRay = new Ray(IncidentRay) }; double lastRefractiveIndex = RefractiveIndices.AIR; Vector translationFromLensCenter = new Vector(0.0, 0.0); int maxIntersections = Elements.Count; for (int i = 0; i < maxIntersections; i++) { IntersectionResult result = new IntersectionResult(); OpticalElement element = Elements[i]; result.IncidentRay = new Ray(previousResult.OutgoingRay); Vector toLocal = element.TranslationToLocal(); // compute intersection Point intersection = null; Ray rayIncidentToElement = result.IncidentRay.Translate(translationFromLensCenter + toLocal); result.Intersected = element.IntersectRay(rayIncidentToElement, out intersection); result.Normal = Vector.FromPoint(intersection); intersection = intersection - (translationFromLensCenter + toLocal); if (!result.Intersected) { break; } result.Intersection = intersection; // compute refracted ray Vector outgoingDirection; if (Math.Abs(lastRefractiveIndex - element.NextRefractiveIndex) > double.Epsilon) { outgoingDirection = result.IncidentRay.Direction.Length * Vector.refract(result.IncidentRay.Direction, result.Normal, lastRefractiveIndex, element.NextRefractiveIndex); } else { // there's no border between different media and thus no refraction outgoingDirection = result.IncidentRay.Direction; } result.OutgoingRay = new Ray(result.Intersection, outgoingDirection); result.Refracted = true; // TODO: differ refraction and TIR IntersectionResults.Add(result); previousResult = result; lastRefractiveIndex = element.NextRefractiveIndex; translationFromLensCenter.X += element.DistanceToNext; } }
/// <summary> /// Place an instance of the given family symbol /// on a selected face of an existing 3D element. /// </summary> FamilyInstance PlaceFamilyInstanceOnFace( UIDocument uidoc, FamilySymbol symbol) { Document doc = uidoc.Document; Reference r = uidoc.Selection.PickObject( ObjectType.Face, "Please pick a point on " + " a face for family instance insertion"); Element e = doc.GetElement(r.ElementId); GeometryObject obj = e.GetGeometryObjectFromReference(r); if (obj is PlanarFace) { PlanarFace planarFace = obj as PlanarFace; // Handle planar face case ... } else if (obj is CylindricalFace) { CylindricalFace cylindricalFace = obj as CylindricalFace; // Handle cylindrical face case ... } // Better than specialised individual handlers // for each specific case, handle the general // case in a generic fashion. Debug.Assert( ElementReferenceType.REFERENCE_TYPE_SURFACE == r.ElementReferenceType, "expected PickObject with ObjectType.Face to " + "return a surface reference"); Face face = obj as Face; UV q = r.UVPoint; #if DEBUG XYZ p = r.GlobalPoint; IntersectionResult ir = face.Project(p); UV q2 = ir.UVPoint; Debug.Assert(q.IsAlmostEqualTo(q2), "expected same UV point"); #endif // DEBUG Transform t = face.ComputeDerivatives(q); XYZ v = t.BasisX; // or BasisY, or whatever... return(doc.Create.NewFamilyInstance(r, p, v, symbol)); }
private bool isAlreadyCreated(Segment seg, IList <Tuple <XYZ, ModelCurve> > already) { //double midTolerance = 0.5 / 12.0; double endTolerance = 1.0 / 12.0; double endOffsetTolerance = 2.0 / 12.0; XYZ mid = seg.Curve.Evaluate(0.5, true); Line segLine = seg.Curve as Line; if (segLine == null) { return(false); } foreach (var item in already) { Curve crv = (item.Item2.GeometryCurve); if ((crv is Line) == false) { continue; } Line ln = crv as Line; IntersectionResult res = ln.Project(mid); if (res.Distance <= endTolerance) { // it is a close projection. // check angle double angle = ln.Direction.AngleTo(segLine.Direction); if ((angle < 0.01) || (angle > Math.PI * 0.95)) { // collinear } else { continue; } // now we need to look at how close the endpoints are XYZ end1 = segLine.GetEndPoint(0); XYZ end2 = segLine.GetEndPoint(1); IntersectionResult res1 = ln.Project(end1); IntersectionResult res2 = ln.Project(end2); if ((res1.Distance <= endOffsetTolerance) && (res2.Distance < endOffsetTolerance)) { return(true); } } } return(false); }
// intersction entre deux droite du plan public static IntersectionResult FindIntersection(StraightLine l0, StraightLine l1) { Vector2 delta = l1.point - l0.point; Vector3 crossVector = Vector3.Cross (l0.tangent, l1.tangent); IntersectionResult ir = new IntersectionResult (); if (!Utils.Approximately (crossVector.z, 0)) { // unique intersection point ir.intersectionType = IntersectionType.UniqueIntersection; ir.intersectionCount = 1; Vector3 delta1CrossVector = Vector3.Cross (delta, l1.tangent); float l0Factor = delta1CrossVector.z / crossVector.z; Vector2 intersectedPoint = l0.point + l0Factor * l0.tangent; ir.intersectedPoints = new Vector2 [1]; ir.intersectedPoints[0] = intersectedPoint; } else { Vector3 delta0CrossVector = Vector3.Cross (l0.tangent, delta); if (Utils.Approximately (delta0CrossVector.z, 0)) { // infinitely many points ir.intersectionType = IntersectionType.InfinityIntersections; ir.intersectionCount = -1; } else { // lines are parallel, no intersection ir.intersectionType = IntersectionType.NoIntersection; ir.intersectionCount = 0; } } return ir; }
/// <summary> /// Returns the intersection of the parallel with a line. /// </summary> /// <param name="refline">The reference line.</param> /// <param name="parpos">Search position that coincides with the parallel.</param> /// <param name="line">The line to intersect with.</param> /// <returns>The intersection (if any). In cases where the line intersects the /// parallel more than once, you get the intersection that is closest to the /// search position.</returns> internal static IPosition GetIntersect(LineFeature refline, IPosition parpos, LineFeature line) { // Make sure the intersection is undefined. IPosition result = null; // Return if the parallel point is undefined. if (parpos==null) return null; // If the reference line is a circular arc (or a section based on an arc), get the curve info. ArcFeature arc = refline.GetArcBase(); if (arc != null) { Circle circle = arc.Circle; double radius = circle.Radius; IPointGeometry centre = circle.Center; bool iscw = arc.IsClockwise; // Construct a circle that passes through the search position double parrad = Geom.Distance(centre, parpos); // Intersect the circle with the line to intersect with. IntersectionResult xres = new IntersectionResult(line); uint nx = xres.Intersect(centre, parrad); if (nx==0) return null; // If there is only one intersection, that's what we want. if (nx==1) return xres.Intersections[0].P1; // Get the intersection that is closest to the search position. xres.GetClosest(parpos, out result, 0.0); } else { // Get the bearing from the start to the end of the reference line. IPosition spos = refline.StartPoint; IPosition epos = refline.EndPoint; double bearing = Geom.BearingInRadians(spos, epos); // Project the parallel line to positions that are a long way away (but make sure we // don't end up with negative numbers). Window searchWindow = new Window(line.Extent); searchWindow.Union(refline.Extent); searchWindow.Union(parpos); double dist = Geom.Distance(searchWindow.Min, searchWindow.Max); IPosition start = Geom.Polar(parpos, bearing+Constants.PI, dist); IPosition end = Geom.Polar(parpos, bearing, dist); // Intersect the line segment with the line to intersect with. IntersectionResult xres = new IntersectionResult(line); IPointGeometry sg = new PointGeometry(start); IPointGeometry eg = new PointGeometry(end); uint nx = xres.Intersect(sg, eg); if (nx==0) return null; // If there is only one intersection, that's what we want. if (nx==1) return xres.Intersections[0].P1; // Get the intersection that is closest to the search position xres.GetClosest(parpos, out result, 0.0); } return result; }
/// <summary> /// Intersects this direction with a line. /// </summary> /// <param name="line">The line to intersect with.</param> /// <param name="closeTo">The point that the intersection should be closest to. /// Specify null if you don't care. In that case, if there are multiple intersections, /// you get the intersection that is closest to one of 3 points: the start of the /// direction line, the start of the line, or the end of the line.</param> /// <param name="xsect">The position of the intersection (if any). Null if not found.</param> /// <param name="closest">The default point that is closest to the intersection. Null if /// intersection wasn't found.</param> /// <returns>True if intersection was found.</returns> internal bool Intersect( LineFeature line , PointFeature closeTo , out IPosition xsect , out PointFeature closest) { // Initialize results xsect = null; closest = null; // Define the length of the direction line as the length // of a diagonal that crosses the map's extent. IWindow mapWin = SpatialController.Current.MapModel.Extent; Debug.Assert(mapWin!=null); // If the window is currently undefined (e.g. during deserialization), // just use a really big distance. // TODO: This is a hack, but hopefully it may be shortlived, because // new logic is in the works for handling updates. double dist = (mapWin.IsEmpty ? 100000.0 : Geom.Distance(mapWin.Min, mapWin.Max)); // Define the position of the direction line. DON'T use the from- // point, because there may be an offset to the direction. IPosition fromPos = this.StartPosition; IPosition toPos = Geom.Polar(fromPos, this.Bearing.Radians, dist); // Construct a corresponding line segment. ITerminal start = new FloatingTerminal(fromPos); ITerminal end = new FloatingTerminal(toPos); SegmentGeometry seg = new SegmentGeometry(start, end); // Intersect the line segment with the other one. IntersectionResult xres = new IntersectionResult(line); uint nx = seg.Intersect(xres); if (nx==0) return false; // Determine which terminal point is the best. Start with the // ends of the intersected line. double mindsq = Double.MaxValue; if (xres.GetCloserPoint(line.StartPoint, ref mindsq, ref xsect)) closest = line.StartPoint; if (xres.GetCloserPoint(line.EndPoint, ref mindsq, ref xsect)) closest = line.EndPoint; // Check whether the direction from-point is any closer (the position may be // different from the start of the direction line, because the direction may // have an offset). if (xres.GetCloserPoint(this.From, ref mindsq, ref xsect)) closest = this.From; // If a close-to point has been specified, that overrides // everything else (however, doing the above has the desired // effect of defining the best of the default points). In // this case, we allow an intersection that coincides with // the line being intersected. // -- actually, we don't, since GetClosest uses a > 0 test if (closeTo != null) { xres.GetClosest(closeTo, out xsect, 0.0); /* IPosition xCloseTo; xres.GetClosest(closeTo, out xCloseTo, 0.0); if (xCloseTo != null) xsect = xCloseTo; */ } return (xsect!=null); }
private void Stream(ArrayList data, IntersectionResult intrResult) { data.Add(new Snoop.Data.ClassSeparator(typeof(IntersectionResult))); data.Add(new Snoop.Data.Double("Distance", intrResult.Distance)); data.Add(new Snoop.Data.Object("Edge object", intrResult.EdgeObject)); data.Add(new Snoop.Data.Double("Edge parameter", intrResult.EdgeParameter)); data.Add(new Snoop.Data.Double("Parameter", intrResult.Parameter)); data.Add(new Snoop.Data.Uv("UV Point", intrResult.UVPoint)); data.Add(new Snoop.Data.Xyz("XYZ Point", intrResult.XYZPoint)); }
/// <summary> /// Returns the intersection of the parallel with a line. A prior call to Calculate is required. /// </summary> /// <param name="line">The line to intersect with.</param> /// <param name="isEndParallel">Is the intersection biased towards the end of the parallel?</param> /// <returns>The intersection (if any). In cases where the line intersects the parallel /// more than once, you get an arbitrary intersection.</returns> internal IPosition GetIntersect(LineFeature line, bool isEndParallel) { // Make sure the intersection is undefined. IPosition result = null; // Return if the parallel points are undefined. if (m_Par1==null || m_Par2==null) return null; // If the reference line is a circular arc, get the curve info. ArcFeature arc = m_Line.GetArcBase(); if (arc != null) { Circle circle = arc.Circle; double radius = circle.Radius; IPointGeometry centre = circle.Center; bool iscw = arc.IsClockwise; // Construct a circle that passes through // the parallel points (assumed to have the same distance // with respect to the centre of the circle). double parrad = Geom.Distance(centre, m_Par1); // Intersect the circle with the line to intersect with. IntersectionResult xres = new IntersectionResult(line); uint nx = xres.Intersect(centre, parrad); if (nx==0) return null; // If there is only one intersection, that's what we want. if (nx==1) return xres.Intersections[0].P1; // Get the intersection that is closest to the parallel point // that has the bias. if (isEndParallel) xres.GetClosest(m_Par2, out result, 0.0); else xres.GetClosest(m_Par1, out result, 0.0); } else { // Get the bearing from the start to the end of the parallel. double bearing = Geom.BearingInRadians(m_Par1, m_Par2); // Get the ground dimension of a line that crosses the // extent of the draw window. double dist = MaxDiagonal; // Project the parallel line to positions that are well // beyond the draw extent. IPosition start = Geom.Polar(m_Par1, bearing+Constants.PI, dist); IPosition end = Geom.Polar(m_Par2, bearing, dist); // Intersect the line segment with the line to intersect with. IntersectionResult xres = new IntersectionResult(line); IPointGeometry sg = PointGeometry.Create(start); IPointGeometry eg = PointGeometry.Create(end); uint nx = xres.Intersect(sg, eg); if (nx==0) return null; // If there is only one intersection, that's what we want. if (nx==1) return xres.Intersections[0].P1; // Get the intersection that is closest to the parallel point // that has the bias. if (isEndParallel) xres.GetClosest(m_Par2, out result, 0.0); else xres.GetClosest(m_Par1, out result, 0.0); } return result; }