public static bool IsPointOnHatchByRay(this Hatch hatch, Point3d pt, Tolerance tolerance, Database db) { var hId = hatch.Id; try { if (hatch.Id.IsNull) { using var t = db.TransactionManager.StartTransaction(); var cs = db.CurrentSpaceId.GetObjectT <BlockTableRecord>(OpenMode.ForWrite); var hClone = (Hatch)hatch.Clone(); hId = cs.AppendEntity(hClone); t.AddNewlyCreatedDBObject(hClone, true); t.Commit(); } using var r = hId.CreateRegionFromHatch(); using var ray = new Ray { BasePoint = pt, UnitDir = new Vector3d(0.235, 0.7458, 0) }; var pts = new Point3dCollection(); ray.IntersectWith(r, Intersect.OnBothOperands, new Plane(), pts, IntPtr.Zero, IntPtr.Zero); return(pts.Count > 0 && (pts.Count.IsOdd() || pts.Cast <Point3d>().Any(p => p.IsEqualTo(pt)))); } finally { if (!hId.IsNull) { #pragma warning disable 618 using var h = hId.Open(OpenMode.ForWrite, false, true) as Hatch; #pragma warning restore 618 h?.Erase(); } } }
public static List <Point3d> Intersects([NotNull] this Polyline pl1, Polyline pl2) { var pts = new Point3dCollection(); pl1.IntersectWith(pl2, Intersect.OnBothOperands, new Plane(), pts, IntPtr.Zero, IntPtr.Zero); return(pts.Cast <Point3d>().ToList()); }
public static List <Point2d> IntersectWithOnPlane([NotNull] this Entity ent, [NotNull] Entity entOther, Intersect extent) { var ptsCol = new Point3dCollection(); ent.IntersectWith(entOther, extent, new Plane(), ptsCol, IntPtr.Zero, IntPtr.Zero); return(ptsCol.Cast <Point3d>().Select(s => s.Convert2d()).ToList()); }
public static void ViewContourElevation() { var pt1 = Interaction.GetPoint("\n截线起点"); if (pt1.IsNull()) { return; } var pt2 = Interaction.GetLineEndPoint("\n截线终点", pt1); if (pt2.IsNull()) { return; } var line = NoDraw.Line(pt1, pt2); var ids = QuickSelection.SelectAll().QWhere(x => x.GetCode() == "730101" || x.GetCode() == "730102").ToList(); var temps = new List <ObjectId>(); ids.QForEach <Curve>(cv => { if (cv != null) { var points = new Point3dCollection(); Algorithms.IntersectWith3264(line, cv, Intersect.OnBothOperands, points); var text = cv.ObjectId.GetData(DictName.CmDrawing, KeyName.Elevation); points.Cast <Point3d>().ForEach(p => { temps.Add(Draw.Text(text, 2.5, p)); }); } }); Interaction.GetString("\n按ESC退出"); temps.QForEach(x => x.Erase()); }
public static void Show(Point3dCollection array) { var sb = new StringBuilder(); array.Cast <Point3d>().ToList().ForEach(p => sb.AppendLine(p.ToString())); Show(sb.ToString()); }
/// <summary> /// Разделение площадки на ячейки /// </summary> private List <Tile> DividePlace() { List <Tile> resTiles = new List <Tile>(); // Построение вертик и гор линий по границе полилинии с заданным шагом var ext = pl.GeometricExtents; var horTiles = Divide(ext.MinPoint.X, ext.MaxPoint.X); var verticTiles = Divide(ext.MinPoint.Y, ext.MaxPoint.Y); using (var plane = new Plane()) { foreach (var horT in horTiles) { // Построение вертик линии using (var verticLine = new Line(new Point3d(horT, ext.MinPoint.Y, 0), new Point3d(horT, ext.MaxPoint.Y, 0))) { // пересечение вертик линии c контуром var ptsIntersect = new Point3dCollection(); verticLine.IntersectWith(pl, Intersect.OnBothOperands, plane, ptsIntersect, IntPtr.Zero, IntPtr.Zero); if (ptsIntersect.Count == 0) { continue; } if (ptsIntersect.Count == 1) { //var pt = new Point2d(horT,ptsIntersect[0].Y); //resTiles.Add(new Tile(pt)); } else { var pts = ptsIntersect.Cast <Point3d>().OrderBy(o => o.Y); var ptIntersectLower = pts.First(); foreach (var ptIntersectTop in pts.Skip(1)) { var ptMid = ptIntersectLower.Center(ptIntersectTop); if (pl.IsPointInsidePolygon(ptMid)) { foreach (var vertT in verticTiles) { if (vertT >= ptIntersectTop.Y) { break; } else if (vertT - ptIntersectLower.Y >= stepQuart) { var pt = new Point2d(horT, vertT); resTiles.Add(new Tile(pt, step, step)); } } } ptIntersectLower = ptIntersectTop; } } } } } return(resTiles); }
public static void RemoveDuplicate([NotNull] this Point3dCollection pts, Tolerance tol) { var ptsClean = RemoveDuplicate(pts.Cast <Point3d>().ToList(), tol); pts.Clear(); foreach (var pt in ptsClean) { pts.Add(pt); } }
/// <summary> /// Попадает ли точка внутрь полилинии. /// Предполагается, что полилиния имеет замкнутый контур. /// Подходит для полилиний с дуговыми сегментами. /// Работает медленнее чем IsPointInsidePolygon(), примерно в 10 раз. /// </summary> /// <param name="pt"></param> /// <param name="onIsInside">Если исходная точка лежит на полилинии, то считать, что она внутри или нет: True - внутри, False - снаружи.</param> /// <param name="pl"></param> /// <exception cref="Exceptions.ErrorException">Не удалось определить за несколько попыток.</exception> public static bool IsPointInsidePolyline([NotNull] this Polyline pl, Point3d pt, bool onIsInside = false) { using (var ray = new Ray()) { ray.BasePoint = pt; var vec = new Vector3d(0, 1, pt.Z); ray.SecondPoint = pt + vec; using (var ptsIntersects = new Point3dCollection()) { bool isContinue; var isPtOnPolyline = false; var countWhile = 0; do { using (var plane = new Plane()) { pl.IntersectWith(ray, Intersect.OnBothOperands, plane, ptsIntersects, IntPtr.Zero, IntPtr.Zero); } isContinue = ptsIntersects.Cast <Point3d>().Any(p => { if (pt.IsEqualTo(p)) { isPtOnPolyline = true; return(true); } var param = pl.GetParameterAtPointTry(p); return(Math.Abs(param % 1) < 0.0001); }); if (isPtOnPolyline) { return(onIsInside); } if (isContinue) { vec = vec.RotateBy(0.01, Vector3d.ZAxis); ray.SecondPoint = pt + vec; ptsIntersects.Clear(); countWhile++; if (countWhile > 3) { throw new ErrorException(new Errors.Error( "Не определено попадает ли точка внутрь полилинии.", pt.GetRectangleFromCenter(3), Matrix3d.Identity, System.Drawing.SystemIcons.Error)); } } } while (isContinue); return(NetLib.MathExt.IsOdd(ptsIntersects.Count)); } } }
public static bool IsPointInsidePolylineByRay([NotNull] Ray ray, Point3d pt, Curve c, Tolerance tolerance) { var pts = new Point3dCollection(); ray.IntersectWith(c, Intersect.OnBothOperands, new Plane(), pts, IntPtr.Zero, IntPtr.Zero); if (pts.Count > 0 && pts.Cast <Point3d>().All(p => c.IsVertex(p, tolerance.EqualPoint))) { // Повернуть луч и повторить ray.TransformBy(Matrix3d.Rotation(5d.ToRadians(), Vector3d.ZAxis, ray.BasePoint)); return(IsPointInsidePolylineByRay(ray, pt, c, tolerance)); } return(pts.Count.IsOdd() || IsPointOnPolyline(c, pt, tolerance)); }
private List <Point2d> GetZeroLineIntersects(MapBuilding build) { var pts = new List <Point2d>(); using (var lineZero = new Line(ptCalc, new Point3d(ptCalc.X + 100, ptCalc.Y, 0))) { var ptsIntersects = new Point3dCollection(); using (var plane = new Plane()) { lineZero.IntersectWith(build.Contour, Intersect.ExtendThis, plane, ptsIntersects, IntPtr.Zero, IntPtr.Zero); pts = ptsIntersects.Cast <Point3d>().Select(s => s.Convert2d()).ToList(); } } return(pts); }
public static void PolySplit() { var ids = Interaction.GetSelection("\nSelect polyline", "LWPOLYLINE"); var newPolys = new List <Polyline>(); var pm = new ProgressMeter(); pm.Start("Processing..."); pm.SetLimit(ids.Length); ids.QOpenForWrite <Polyline>(list => { foreach (var poly in list) { var intersectPoints = new Point3dCollection(); foreach (var poly1 in list) { if (poly1 != poly) { poly.IntersectWith3264(poly1, Intersect.OnBothOperands, intersectPoints); } } var ipParams = intersectPoints .Cast <Point3d>() .Select(ip => poly.GetParamAtPointX(ip)) .OrderBy(param => param) .ToArray(); if (intersectPoints.Count > 0) { var curves = poly.GetSplitCurves(new DoubleCollection(ipParams)); foreach (var curve in curves) { newPolys.Add(curve as Polyline); } } else // mod 20130227 Add to newPolys regardless of whether an intersection exists, otherwise dangling lines would be gone. { newPolys.Add(poly.Clone() as Polyline); } pm.MeterProgress(); } }); pm.Stop(); if (newPolys.Count > 0) { newPolys.ToArray().AddToCurrentSpace(); ids.QForEach(entity => entity.Erase()); } Interaction.WriteLine("Broke {0} to {1}.", ids.Length, newPolys.Count); }
public static void PolySplit() { ObjectId[] ids = Interaction.GetSelection("\nSelect polyline", "LWPOLYLINE"); List <Polyline> newPolys = new List <Polyline>(); ProgressMeter pm = new ProgressMeter(); pm.Start("Processing..."); pm.SetLimit(ids.Length); ids.QOpenForWrite <Polyline>(list => { foreach (var poly in list) { Point3dCollection intersectPoints = new Point3dCollection(); foreach (var poly1 in list) { if (poly1 != poly) { poly.IntersectWith3264(poly1, Intersect.OnBothOperands, intersectPoints); } } var ipParams = intersectPoints.Cast <Point3d>().Select(ip => poly.GetParamAtPointX(ip)).OrderBy(param => param).ToArray(); if (intersectPoints.Count > 0) { var curves = poly.GetSplitCurves(new DoubleCollection(ipParams)); foreach (var curve in curves) { newPolys.Add(curve as Polyline); } } else // mod 20130227 不管有无交点,都要添加到newPolys,否则孤立线将消失。 { newPolys.Add(poly.Clone() as Polyline); } pm.MeterProgress(); } }); pm.Stop(); if (newPolys.Count > 0) { newPolys.ToArray().AddToCurrentSpace(); ids.QForEach(x => x.Erase()); } Interaction.WriteLine("Broke {0} to {1}.", ids.Length, newPolys.Count); }
/// <summary> /// Определение зон теней от дома, который выше расчетной линии тени - по линии через 0 /// </summary> /// <param name="build"></param> /// <returns></returns> private IIlluminationArea GetBuildingZeroLineShadows(MapBuilding build) { using (var lineZero = new Line(ptCalc, new Point3d(ptCalc.X + 100, ptCalc.Y, 0))) { #if TEST //EntityHelper.AddEntityToCurrentSpace(lineZero); #endif var ptsIntersects = new Point3dCollection(); using (var plane = new Plane()) { lineZero.IntersectWith(build.Contour, Intersect.ExtendThis, plane, ptsIntersects, IntPtr.Zero, IntPtr.Zero); var pts = build.Contour.GetPoints().Where(p => p.Y < ptCalc.Y).ToList(); pts.AddRange(ptsIntersects.Cast <Point3d>().Select(s => s.Convert2d())); if (pts.Any()) { var ilumShadow = GetIllumShadow(pts); return(ilumShadow); } } } return(null); }
public static bool DetectDuplicatePoint(Point3dCollection points, Point3d point) { return(points.Cast <Point3d>().Any(existing => DetectDuplicatePoint(existing, point))); }
private bool CorrectStartAnglesByOwnerZeroHorLineIntersects(out List <Point3d> ptsIntersectShadow) { ptsIntersectShadow = new List <Point3d> (); bool isCorrect = true; var contour = buildingOwner.Contour; // Линия через точку ноль - Горизонтально using (var lineZero = new Line(ptCalc, new Point3d(ptCalc.X + 1, ptCalc.Y, 0))) { // Линия тени - пересечение собственного дома с ней? double yShadowLine; var ptHeightCalc = GetPtCalcHeight(); var buildHeightCalc = GetHeightCalcBuilding(ptHeightCalc, buildingOwner.HeightCalc); using (var lineShadow = GetLineShadow(buildHeightCalc)) { yShadowLine = lineShadow.StartPoint.Y; #if TEST //EntityHelper.AddEntityToCurrentSpace(lineShadow); #endif using (var ptsIntersect = new Point3dCollection()) { using (var plane = new Plane()) { contour.IntersectWith(lineShadow, Intersect.OnBothOperands, plane, ptsIntersect, IntPtr.Zero, IntPtr.Zero); ptsIntersectShadow = ptsIntersect.Cast <Point3d>().ToList(); } // !!!??? Если есть пересечения с линией тени, тогда нужно разделить полилинию дома на собственную часть и внешнюю (которую считать отдельно) } if (ptsIntersectShadow.Count > 1) { // Отсечение части дома - по точкам пересечения. List <Polyline> plsSecant; if (contour.Separate(ptCalc, ptsIntersectShadow, out plHead, out plsSecant)) { if (plHead != null) { contour = plHead; } // из отсеченных частей сделать здания для дальнейшего расчета - когда будут перебираться внешние дома при расчете точки if (plsSecant != null && plsSecant.Any()) { secantBuildings = MapBuilding.CreateFakeBuildings(plsSecant, buildingOwner); } } } } #if TEST //EntityHelper.AddEntityToCurrentSpace(lineZero); #endif List <Point3d> ptsIntersectZero; using (var ptsIntersect = new Point3dCollection()) { contour.IntersectWith(lineZero, Intersect.ExtendArgument, new Plane(), ptsIntersect, IntPtr.Zero, IntPtr.Zero); ptsIntersectZero = ptsIntersect.Cast <Point3d>().OrderBy(o => o.X).ToList(); } // Разделить точки левее стартовой и правее (Запад/Восток) - для каждой петли свойестороны найти максимальный ограничивающий угол. double westAngle; if (GetStartAngleBySideIntersects(contour, ptsIntersectZero, ptsIntersectShadow, yShadowLine, false, true, false, out westAngle)) { if (westAngle < StartAnglesIllum.AngleEndOnPlane) { StartAnglesIllum.AngleEndOnPlane = westAngle; } } else { isCorrect = false; } double eastAngle; if (GetStartAngleBySideIntersects(contour, ptsIntersectZero, ptsIntersectShadow, yShadowLine, true, true, false, out eastAngle)) { if (eastAngle > StartAnglesIllum.AngleStartOnPlane) { StartAnglesIllum.AngleStartOnPlane = eastAngle; } } else { isCorrect = false; } } return(isCorrect); }
private List <IIlluminationArea> GetBuildingLineShadowBoundary(MapBuilding build, Line lineShadow, Intersect intersectMode) { var resIlumsShadows = new List <IIlluminationArea>(); if (lineShadow.Length < 1) { return(resIlumsShadows); } // Дом на границе тени, нужно строить линию пересечения с домом var ptsIntersects = new Point3dCollection(); using (var plane = new Plane()) { lineShadow.IntersectWith(build.Contour, intersectMode, plane, ptsIntersects, IntPtr.Zero, IntPtr.Zero); } // Точки пересечения дома с нулевой линей var ptsZeroIntersects = GetZeroLineIntersects(build); // Между каждыми точками пересечения определение петли полилинии и определение тени if (ptsIntersects.Count > 1) { var ptsItersectSort = ptsIntersects.Cast <Point3d>().OrderBy(o => o.X); var ptIntersectPrew = ptsItersectSort.First(); foreach (var ptIntersect in ptsItersectSort.Skip(1)) { // Если средняя точка внутри полилинии if (build.Contour.IsPointInsidePolygon(ptIntersect.Center(ptIntersectPrew))) { // Точки петли выше try { var ptsLoopAbove = build.Contour.GetLoopSideBetweenHorizontalIntersectPoints( ptIntersectPrew, ptIntersect, true, true). Where(p => p.Y <= ptCalc.Y && p.Y >= lineShadow.StartPoint.Y).ToList(); ptsLoopAbove.AddRange(ptsZeroIntersects); var ilumShadow = GetIllumShadow(ptsLoopAbove); if (ilumShadow != null) { resIlumsShadows.Add(ilumShadow); } } catch (Exception ex) { Logger.Log.Error(ex, "В методе GetBuildingLineShadowBoundary вызов build.Contour.GetLoopSideBetweenHorizontalIntersectPoints()"); } } ptIntersectPrew = ptIntersect; } } //// Точки выше найденного пересечения //var ptsContour = build.Contour.GetPoints(); //var ptsAboveLine = ptsContour.Where(p => p.Y >= lineShadow.StartPoint.Y).ToList(); //foreach (Point3d item in ptsIntersects) //{ // ptsAboveLine.Add(item.Convert2d()); //} //var ilumShadow = GetIllumShadow(ptsAboveLine); //if (ilumShadow != null) //{ // resIlumsShadows.Add(ilumShadow); //} return(resIlumsShadows); }
/// <summary> /// Removes duplicated points in the collection according to the specified tolerance. /// </summary> /// <param name="source">The instance to which the method applies.</param> /// <param name="tolerance">The tolerance to be used in equality comparison.</param> /// <returns>A sequence of disitnct points.</returns> public static IEnumerable <Point3d> RemoveDuplicates(this Point3dCollection source, Tolerance tolerance) { return(source.Cast <Point3d>().Distinct(new Point3dComparer())); }
/// <summary> /// Removes duplicated points in the collection using Tolerance.Global. /// </summary> /// <param name="source">The instance to which the method applies.</param> /// <returns>A sequence of distinct points.</returns> public static IEnumerable <Point3d> RemoveDuplicates(this Point3dCollection source) { return(source.Cast <Point3d>().RemoveDuplicates(Tolerance.Global)); }
/// <summary> /// Gets the extents 3d for the point collection. /// </summary> /// <param name="pts">The instance to which the method applies.</param> /// <returns>An Extents3d instance.</returns> /// <exception cref="ArgumentException"> /// ArgumentException is thrown if the collection is null or empty.</exception> public static Extents3d ToExtents3d(this Point3dCollection pts) { return(pts.Cast <Point3d>().ToExtents3d()); }