public static double Get(bool IsLeftComp, double r, Polyline line, Point2d TheIntersectPoint, int Index, Point2d StartPoint) { double oldBulge = line.GetBulgeAt(Index - 1); if (oldBulge == 0) return 0;//这里可能不对,可能有两个交点,而默认为一个交点 else { double delta = System.Math.Atan(System.Math.Abs(oldBulge)) * 2; //这里计算新的半径时,要考虑方向因素,可能新半径会更小,也可能会更大 //取决于路径的偏移方向,以及圆心的位置 double newRadius = line.GetPoint2dAt(Index - 1).GetDistanceTo(line.GetPoint2dAt(Index)) / 2 / System.Math.Sin(delta);//新弧的半径 if (IsLeftComp) { if (oldBulge < 0) newRadius += r; else newRadius -= r; } else { if (oldBulge > 0) newRadius += r; else newRadius -= r; } double newChord = StartPoint.GetDistanceTo(TheIntersectPoint); double newBulge = System.Math.Tan( System.Math.Asin(newChord / 2 / newRadius) / 2 ) * line.GetBulgeAt(Index - 1) / System.Math.Abs(line.GetBulgeAt(Index - 1)); return -newBulge; } }
public static LineSegment2d[] GetTangentsTo([NotNull] this CircularArc2d arc, Point2d pt) { // check if the point is inside the circle var center = arc.Center; if (pt.GetDistanceTo(center) <= arc.Radius) { return(null); } var vec = center.GetVectorTo(pt) / 2.0; var tmp = new CircularArc2d(center + vec, vec.Length); var inters = arc.IntersectWith(tmp); if (inters == null) { return(null); } var result = new LineSegment2d[2]; var v1 = inters[0] - center; var i = vec.X * v1.Y - vec.Y - v1.X > 0 ? 0 : 1; var j = i ^ 1; result[i] = new LineSegment2d(inters[0], pt); result[j] = new LineSegment2d(inters[1], pt); return(result); }
// Sampler函数用于检测用户的输入. protected override SamplerStatus Sampler(JigPrompts prompts) { Database db = HostApplicationServices.WorkingDatabase; // 定义一个点拖动交互类. JigPromptPointOptions optJigPoint = new JigPromptPointOptions("\n请指定五角星的一个角点:"); // 设置拖拽光标类型. optJigPoint.Cursor = CursorType.RubberBand; // 设置拖动光标基点. optJigPoint.BasePoint = mCenterPt; optJigPoint.UseBasePoint = true; // 用AcquirePoint函数得到用户输入的点. PromptPointResult resJigPoint1 = prompts.AcquirePoint(optJigPoint); Point3d curPt = resJigPoint1.Value; if (curPt != peakPt) { // 重新设置椭圆参数--------------------------------------------. // 五角星的中心. Point2d p0 = new Point2d(mCenterPt.X, mCenterPt.Y); // 计算五角星的第一个顶点坐标. Point2d p1 = new Point2d(curPt[0], curPt[1]); // 为计算其他9个顶点的坐标进行准备. double d1 = p1.GetDistanceTo(p0); double d2 = d1 * Math.Sin(Rad2Ang(18)) / Math.Sin(Rad2Ang(54)); Vector2d vec = p1 - p0; double ang = vec.Angle; // 计算五角星另外9个顶点的坐标. Point2d p2 = PolarPoint(p0, ang + Rad2Ang(36), d2); Point2d p3 = PolarPoint(p0, ang + Rad2Ang(72), d1); Point2d p4 = PolarPoint(p0, ang + Rad2Ang(108), d2); Point2d p5 = PolarPoint(p0, ang + Rad2Ang(144), d1); Point2d p6 = PolarPoint(p0, ang + Rad2Ang(180), d2); Point2d p7 = PolarPoint(p0, ang + Rad2Ang(216), d1); Point2d p8 = PolarPoint(p0, ang + Rad2Ang(252), d2); Point2d p9 = PolarPoint(p0, ang + Rad2Ang(288), d1); Point2d p10 = PolarPoint(p0, ang + Rad2Ang(324), d2); // 更新五角星各个顶点的坐标. ent.SetPointAt(0, p1); ent.SetPointAt(1, p2); ent.SetPointAt(2, p3); ent.SetPointAt(3, p4); ent.SetPointAt(4, p5); ent.SetPointAt(5, p6); ent.SetPointAt(6, p7); ent.SetPointAt(7, p8); ent.SetPointAt(8, p9); ent.SetPointAt(9, p10); peakPt = curPt; return(SamplerStatus.OK); } else { return(SamplerStatus.NoChange); } }
private List <Polyline> ArcToPolyline(List <Entity> list) { List <Polyline> listPoly = new List <Polyline>(); foreach (var ent in list) { //如果实体为圆弧 if (ent is Arc) { Arc arc = ent as Arc; double R = arc.Radius; Point3d startPoint = arc.StartPoint; Point3d endPoint = arc.EndPoint; Point2d p1, p2; p1 = new Point2d(startPoint.X, startPoint.Y); p2 = new Point2d(endPoint.X, endPoint.Y); Double L = p1.GetDistanceTo(p2); double H = R - Math.Sqrt(R * R - L * L / 4); Polyline poly = new Polyline(); poly.AddVertexAt(0, p1, 2 * H / L, 0, 0); poly.AddVertexAt(1, p2, 0, 0, 0); poly.Color = Autodesk.AutoCAD.Colors.Color.FromColor(System.Drawing.Color.Red); listPoly.Add(poly); } } return(listPoly); }
/// <summary> /// Найти ближайшее ребро, которое пересекает горизонтальный луч, направленный вправо из точки /// </summary> /// <param name="M"></param> /// <param name="ptOnEdge"></param> /// <returns></returns> private int[] GetEdgeOnHorizontalRay(Point2d M, out Point2d ptOnEdge) { int[] edge = null; Point2d?_ptOnEdge = null; double minDistToM = double.MaxValue; int numVert = Polygon.Count; Action <int[], Point2d, Point2d> onIntersectionFind = (currEdge, vert1, vert2) => { Point2d currPtOnEdge = ptOnHorizontalRay(M.Y, vert1, vert2); double currDistToM = currPtOnEdge.GetDistanceTo(M); if (currDistToM < minDistToM) { minDistToM = currDistToM; edge = currEdge; _ptOnEdge = currPtOnEdge; } }; for (int i = 0; i < numVert; i++) { int[] currEdge = new int[] { i, (i + 1) % numVert }; Point2d vert1 = GetPt2DAt(currEdge[0]); Point2d vert2 = GetPt2DAt(currEdge[1]); double isLeftVal = double.MinValue; if (vert1.Y <= M.Y) { if (vert2.Y > M.Y) { //Переход снизу вверх isLeftVal = Utils.IsLeft(vert1, vert2, M); if (isLeftVal > 0) { onIntersectionFind.Invoke(currEdge, vert1, vert2); } } } else if (vert2.Y <= M.Y) { //Переход сверху вниз isLeftVal = Utils.IsLeft(vert1, vert2, M); if (isLeftVal < 0) { onIntersectionFind.Invoke(currEdge, vert1, vert2); } } } if (_ptOnEdge.Value != null) { ptOnEdge = _ptOnEdge.Value; } else { ptOnEdge = Point2d.Origin; } return(edge); }
/// <summary> /// Gets the centroid of the circular arc. /// </summary> /// <param name="arc">The instance to which the method applies.</param> /// <returns>The centroid of the arc.</returns> public static Point2d Centroid(this CircularArc2d arc) { Point2d start = arc.StartPoint; Point2d end = arc.EndPoint; double area = arc.SignedArea(); double chord = start.GetDistanceTo(end); double angle = (end - start).Angle; return(arc.Center.Polar(angle - (Math.PI / 2.0), (chord * chord * chord) / (12.0 * area))); }
public int Compare(Point3d pt1_3d, Point3d pt2_3d) { Point2d pt1 = new Point2d(pt1_3d.X, pt1_3d.Y); Point2d pt2 = new Point2d(pt2_3d.X, pt2_3d.Y); double dist1 = pt1.GetDistanceTo(basePt); double dist2 = pt2.GetDistanceTo(basePt); return(dist1.CompareTo(dist2)); }
private static List <Polyline> ArcToPolyline(List <Entity> list) { List <Polyline> listPoly = new List <Polyline>(); foreach (var ent in list) { //如果实体为圆弧 if (ent is Arc) { Arc arc = ent as Arc; double R = arc.Radius; Point3d startPoint = arc.StartPoint; Point3d endPoint = arc.EndPoint; Point2d p1, p2; p1 = new Point2d(startPoint.X, startPoint.Y); p2 = new Point2d(endPoint.X, endPoint.Y); Double L = p1.GetDistanceTo(p2); double H = R - Math.Sqrt(R * R - L * L / 4); Polyline poly = new Polyline(); poly.AddVertexAt(0, p1, 2 * H / L, 0, 0); poly.AddVertexAt(1, p2, 0, 0, 0); //poly.Color = Autodesk.AutoCAD.Colors.Color.FromColor(System.Drawing.Color.Red); listPoly.Add(poly); } else if (ent is Polyline) { Polyline p = ent as Polyline; if (p.NumberOfVertices > 2) { for (int i = 0; i < p.NumberOfVertices; i++) { Polyline tempP = new Polyline(); tempP.AddVertexAt(0, p.GetPoint2dAt(i), 0, 0, 0); if (i + 1 < p.NumberOfVertices) { tempP.AddVertexAt(1, p.GetPoint2dAt(i + 1), 0, 0, 0); listPoly.Add(tempP); } } } else { listPoly.Add(p); } } } return(listPoly); }
/// <summary> /// TODO /// </summary> /// <param name="from"></param> /// <param name="to"></param> /// <returns></returns> public static bool IsEqualTo(this Point2d from, Point2d to) { try { return(Math.Abs(from.GetDistanceTo(to)).IsLessThanTol()); } catch (Exception) { return(from == to); } }
private static Entity DrawCircularArc(CircularArc arc, double defaultElevation, Point[] densifiedPoints) { PointN pointN = arc.FromPoint as PointN; PointN pointN2 = arc.ToPoint as PointN; PointN pointN3 = arc.CenterPoint as PointN; Point3d point3d = new Point3d(pointN.X, pointN.Y, pointN.Z); Point3d point3d2 = new Point3d(pointN3.X, pointN3.Y, pointN3.Z); Point3d point3d3 = new Point3d(pointN2.X, pointN2.Y, pointN2.Z); Point2d centerPoint = new Point2d(pointN3.X, pointN3.Y); Point2d point2d = new Point2d(pointN.X, pointN.Y); Math.Abs(centerPoint.GetDistanceTo(point2d)); CircularArc3d circArc; if (densifiedPoints != null) { int num = densifiedPoints.Length / 2; PointN pointN4 = (PointN)densifiedPoints[num]; if (arc.IsCounterClockwise) { PointN arg_CC_0 = (PointN)densifiedPoints[0]; PointN arg_D9_0 = (PointN)densifiedPoints[densifiedPoints.Length - 1]; } else { PointN arg_E4_0 = (PointN)densifiedPoints[0]; PointN arg_F1_0 = (PointN)densifiedPoints[densifiedPoints.Length - 1]; } Point3d point3d4 = new Point3d(pointN4.X, pointN4.Y, pointN4.Z); circArc = new CircularArc3d(point3d, point3d4, point3d3); } else { Point2d point2d2 = new Point2d(point3d.X, point3d.Y); Point2d point2d3 = new Point2d(point3d3.X, point3d3.Y); double num2 = GIS2CAD.CalcThetaFromVectors(point2d2, point2d3, centerPoint, arc.IsCounterClockwise); double num3 = Math.Tan(num2 / 4.0); if (!arc.IsCounterClockwise) { num3 *= -1.0; } CircularArc2d circularArc2d = new CircularArc2d(point2d2, point2d3, num3, false); Point2d[] samplePoints = circularArc2d.GetSamplePoints(3); Point3d point3d5 = new Point3d(samplePoints[1].X, samplePoints[1].Y, point3d2.Z); circArc = new CircularArc3d(point3d, point3d5, point3d3); } new Point3d(pointN3.X, pointN3.Y, pointN3.Z); Arc arc2 = GIS2CAD.CreateFromCircularArc(circArc); arc2.ColorIndex = (256); return(arc2); }
public Sierpinski(Point2d a, Point2d b, Point2d c) { Triangle = new Polyline(); A = a; B = b; C = c; this.Size = B.GetDistanceTo(A); Triangle.AddVertexAt(0, A, 0, 0, 0); Triangle.AddVertexAt(1, B, 0, 0, 0); Triangle.AddVertexAt(2, C, 0, 0, 0); Triangle.Closed = true; depth = 0; }
/// <summary> /// Inicializa la instancia de la clase <see cref="Sierpinski"/>. /// </summary> /// <param name="a">El primer punto del triángulo.</param> /// <param name="b">El segundo punto del triángulo.</param> /// <param name="c">El tercer punto del triángulo.</param> public Sierpinski(Point2d a, Point2d b, Point2d c) { Triangle = new Polyline(); A = a; B = b; C = c; this.Size = B.GetDistanceTo(A); Triangle.AddVertexAt(0, A, 0, 0, 0); Triangle.AddVertexAt(1, B, 0, 0, 0); Triangle.AddVertexAt(2, C, 0, 0, 0); Triangle.Closed = true; depth = 0; }
public List <Point2d> ConvexHull(List <Point2d> pts) { _p0 = pts.OrderBy(p => p.Y).ThenBy(p => p.X).First(); pts = pts.OrderByDescending(p => Cosine(p)).ThenBy(p => _p0.GetDistanceTo(p)).ToList(); for (int i = 1; i < pts.Count - 1; i++) { while (i > 0 && Clockwise(pts[i - 1], pts[i], pts[i + 1])) { pts.RemoveAt(i); i--; } } return(pts); }
/// <summary> /// Returns the parameter value of point. /// </summary> /// <param name="pt">The Point 2d whose get the PolylineSegment parameter at.</param> /// <returns>A double between 0.0 and 1.0, or -1.0 if the point does not lie on the segment.</returns> public double GetParameterOf(Point2d pt) { if (IsLinear) { LineSegment2d line = ToLineSegment(); return(line.IsOn(pt) ? _startPoint.GetDistanceTo(pt) / line.Length : -1.0); } else { CircularArc2d arc = ToCircularArc(); return(arc.IsOn(pt) ? arc.GetLength(arc.GetParameterOf(_startPoint), arc.GetParameterOf(pt)) / arc.GetLength(arc.GetParameterOf(_startPoint), arc.GetParameterOf(_endPoint)) : -1.0); } }
public static double Get(bool IsLeftComp, double r, Polyline line, Point2d TheIntersectPoint, int Index, Point2d StartPoint) { double oldBulge = line.GetBulgeAt(Index - 1); if (oldBulge == 0) { return(0);//这里可能不对,可能有两个交点,而默认为一个交点 } else { double delta = System.Math.Atan(System.Math.Abs(oldBulge)) * 2; //这里计算新的半径时,要考虑方向因素,可能新半径会更小,也可能会更大 //取决于路径的偏移方向,以及圆心的位置 double newRadius = line.GetPoint2dAt(Index - 1).GetDistanceTo(line.GetPoint2dAt(Index)) / 2 / System.Math.Sin(delta);//新弧的半径 if (IsLeftComp) { if (oldBulge < 0) { newRadius += r; } else { newRadius -= r; } } else { if (oldBulge > 0) { newRadius += r; } else { newRadius -= r; } } double newChord = StartPoint.GetDistanceTo(TheIntersectPoint); double newBulge = System.Math.Tan( System.Math.Asin(newChord / 2 / newRadius) / 2 ) * line.GetBulgeAt(Index - 1) / System.Math.Abs(line.GetBulgeAt(Index - 1)); return(-newBulge); } }
/// <summary> /// Returns the tangents between the active CircularArc2d instance complete circle and a point. /// </summary> /// <remarks> /// Tangents start points are on the object to which this method applies, end points on the point passed as argument. /// Tangents are always returned in the same order: the tangent on the left side of the line from the circular arc center /// to the point before the other one. /// </remarks> /// <param name="arc">The instance to which this method applies.</param> /// <param name="pt">The Point2d to which tangents are searched</param> /// <returns>An array of LineSegement2d representing the tangents (2) or null if there is none.</returns> public static LineSegment2d[] GetTangentsTo(this CircularArc2d arc, Point2d pt) { // check if the point is inside the circle Point2d center = arc.Center; if (pt.GetDistanceTo(center) <= arc.Radius) return null; Vector2d vec = center.GetVectorTo(pt) / 2.0; CircularArc2d tmp = new CircularArc2d(center + vec, vec.Length); Point2d[] inters = arc.IntersectWith(tmp); if (inters == null) return null; LineSegment2d[] result = new LineSegment2d[2]; Vector2d v1 = inters[0] - center; Vector2d v2 = inters[1] - center; int i = vec.X * v1.Y - vec.Y - v1.X > 0 ? 0 : 1; int j = i ^ 1; result[i] = new LineSegment2d(inters[0], pt); result[j] = new LineSegment2d(inters[1], pt); return result; }
/// <summary> /// Если вогнутые вершины попали в треугольник MIP /// выбирает видимую точку /// </summary> /// <param name="M"></param> /// <param name="candidateReflexPoints"></param> /// <returns></returns> private int GetVisiblePtFromReflexPts(Point2d M, List <int> candidateReflexPoints) { int ptIndex = -1; double angleToHor = double.MaxValue; double distToM = double.MaxValue; foreach (int i in candidateReflexPoints) { Point2d pt = GetPt2DAt(i); Vector2d currVector = pt - M; double currAngleToHor = currVector.GetAngleTo(Vector2d.XAxis); double currDistToM = pt.GetDistanceTo(M); if ((currAngleToHor < angleToHor) || (currAngleToHor == angleToHor && currDistToM < distToM)) { ptIndex = i; angleToHor = currAngleToHor; distToM = currDistToM; } } return(ptIndex); }
private double GetThickness() { double rezult = -1.0; int N = -1; #region Search_first_ARC_segment_and_save_index_in_N for (int i = 0; i < _basePolyLine.NumberOfVertices; i++) { if (Math.Abs(_basePolyLine.GetBulgeAt(i) - 0) > Double.Epsilon) { N = i; // save indeks i N break; // stop the cycle } } #endregion if ((N >= 0) && (N <= (_basePolyLine.NumberOfVertices - 1)))//??? N = 0 is impossible. The first segment. The first segment must be right { double dist = -1.0; int N1 = GetParalellArc(N, ref dist); if ((N1 > 0) && (N1 < (_basePolyLine.NumberOfVertices - 1))) { LineSegment2d seg = _basePolyLine.GetLineSegment2dAt(N); // find chord LineSegment2d seg1 = _basePolyLine.GetLineSegment2dAt(N1); // find chord //chords are opposite vectors Point2d p1 = seg.StartPoint; Point2d p2 = seg1.EndPoint; rezult = p1.GetDistanceTo(p2); } } return(rezult); }
///<summary> ///Bogenkleinpunkte ///</summary> public List <Point3d> calcBogenKleinpunkte3d(Point2d ptZentrum, double dRadius, Point3d ptAnfang, Point3d ptEnde, double dStich) { List <Point3d> lsPunkte = new List <Point3d>(); Point2d ptAnfang2d = new Point2d(ptAnfang.X, ptAnfang.Y); Point2d ptEnde2d = new Point2d(ptEnde.X, ptEnde.Y); //erforderliche Sehnenlänge berechnen myAutoCAD.myUtilities objUtil = new myAutoCAD.myUtilities(); double dSehne = objUtil.calcSehne(dRadius, dStich); //Berechnung Bogenlänge double dAbstandSE = ptAnfang2d.GetDistanceTo(ptEnde2d); double dPhi = 2 * Math.Asin(dAbstandSE / (2 * dRadius)); double dBL = dRadius * dPhi; //Berechnung der Bogenlänge für Kleinpunkte double dPhi1 = 0; dPhi1 = 2 * Math.Asin(dSehne / (2 * dRadius)); double dBL1 = dRadius * dPhi1; //Vorzeichen für Phi1 festlegen (je nach Drehsinn) double dAlphaStart = objUtil.RiWi(ptZentrum, ptAnfang2d); double dAlphaEnde = objUtil.RiWi(ptZentrum, ptEnde2d); if (dAlphaStart > dAlphaEnde) { dPhi1 = -dPhi1; } //Richtungswinkel Vector2d v2dRiWi = ptZentrum.GetVectorTo(ptAnfang2d); double dRiWi = v2dRiWi.Angle; dRiWi = objUtil.RiWi(ptZentrum, ptAnfang2d); //solange Endpunkt nicht erreicht ist, Kleinpunkte berechnen double dStation = dBL1; double dWinkel = dRiWi; //dH für Höheninterpolation double dH = (ptEnde.Z - ptAnfang.Z) / dBL * dBL1; double dz = 0; while (dStation < dBL) { dWinkel += dPhi1; //dx, dy und dz berechnen double dx = dRadius * Math.Sin(dWinkel); double dy = dRadius * Math.Cos(dWinkel); dz += dH; //Kleinpunkt berechnen Point3d ptPunkt = new Point3d(ptZentrum.X + dx, ptZentrum.Y + dy, ptAnfang.Z + dz); //Punkt zu Liste hinzufügen lsPunkte.Add(ptPunkt); dStation += dBL1; } return(lsPunkte); }
public void ExtractSpillwayPositions() { Document adoc = Application.DocumentManager.MdiActiveDocument; if (adoc == null) { return; } Database db = adoc.Database; Editor ed = adoc.Editor; List <Polyline3d> highlighted = new List <Polyline3d>(); try { Plane horizontalPlane = new Plane(Point3d.Origin, Vector3d.ZAxis); //Указать линию КПЧ и линии перелома откоса (они должны быть в соответствующих слоях) TypedValue[] tv = new TypedValue[] { new TypedValue(0, "POLYLINE"), new TypedValue(8, "КПЧ,ОТК") };//ограничение по слоям SelectionFilter flt = new SelectionFilter(tv); PromptSelectionOptions opts = new PromptSelectionOptions(); opts.MessageForAdding = "\nВыберите 3d-полилинии, обозначающие край проезжей части" + "и переломы откоса (только с одной стороны дороги). Линии должны быть в слоях КПЧ и ОТК"; PromptSelectionResult res = ed.GetSelection(opts, flt); if (res.Status == PromptStatus.OK) { SelectionSet sset = res.Value; //Отобрать только полилинии в нужных слоях Dictionary <string, List <Polyline3dInfo> > slopeLines = new Dictionary <string, List <Polyline3dInfo> >(); //Считать направление полилинии соответствующим направлению дороги bool? toTheRight = null;//водосброс справа от КПЧ Polyline3dInfo baseLine = null; using (Transaction tr = db.TransactionManager.StartTransaction()) { WrongPolylinesException wrongPolylinesException = new WrongPolylinesException(); //Отбор линий в служебных слоях foreach (SelectedObject acSSObj in sset) { Polyline3d currPoly = tr.GetObject(acSSObj.ObjectId, OpenMode.ForRead) as Polyline3d; if (currPoly != null) { if (currPoly.Layer.Equals("КПЧ") || currPoly.Layer.Equals("ОТК")) { List <Polyline3dInfo> polylines = null; slopeLines.TryGetValue(currPoly.Layer, out polylines); if (polylines == null) { polylines = new List <Polyline3dInfo>(); slopeLines.Add(currPoly.Layer, polylines); } polylines.Add(new Polyline3dInfo(currPoly.Layer, currPoly)); } } } //Проверить, что есть весь набор слоев - КПЧ, ОТК if (!slopeLines.ContainsKey("КПЧ") || !slopeLines.ContainsKey("ОТК")) { wrongPolylinesException.Mistakes = wrongPolylinesException.Mistakes | Mistake.NotEnoughLayers; } //Проверить, что в слое КПЧ находится только 1 полилиния List <Polyline3dInfo> checkList1 = null; slopeLines.TryGetValue("КПЧ", out checkList1); if (checkList1 == null || checkList1.Count != 1) { wrongPolylinesException.Mistakes = wrongPolylinesException.Mistakes | Mistake.TooManyLinesInOneLayer; } #region Проперка непересечения линий //Проверить что линии откоса не пересекают друг друга в плане //TODO: ВРЕМЕННО отказался от проверки взаимного пересечения линий откоса. Нужно учесть возможность частичного совпадения линий /* * List<Polyline3dInfo> slopeLinesList = slopeLines.Values.ToList().Aggregate((l1, l2) => * { * return l1.Concat(l2).ToList(); * }); * bool exitLoop = false; * for (int i = 0; i < slopeLinesList.Count; i++) * { * for (int j = i + 1; j < slopeLinesList.Count; j++) * { * Polyline3d poly1 = slopeLinesList[i].Poly3d; * Polyline3d poly2 = slopeLinesList[j].Poly3d; * Point3dCollection intersectPts = new Point3dCollection(); * poly1.IntersectWith(poly2, Intersect.OnBothOperands, * horizontalPlane, intersectPts, * new IntPtr(0), new IntPtr(0)); * * //TODO!!!!! Не считать точки пересечения если в точках пересечения происходит полное совпадение вершин двух полилиний * //В это случае скорее всего полилинии просто сливаются в одну. Это допустимо для коридора * * * * if (intersectPts.Count > 0) * { * * * * wrongPolylinesException.Mistakes = wrongPolylinesException.Mistakes | Mistake.LinesAreIntersecting; * exitLoop = true; * break; * } * } * if (exitLoop) * break; * } */ #endregion //Проверить, что все точки откоса расположены с одной стороны от КПЧ //Определить водосброс направо или налево //TODO: Проверить сонаправленность линий! (низкий приоритет) //Для всех кодов определить участки КПЧ. Параметры взаимного расположения расчитываются в горизонтальной проекции //По начальным точкам линий определить расположение линии справа или слева от КПЧ //базовая линия - КПЧ List <Polyline3dInfo> list = null; slopeLines.TryGetValue("КПЧ", out list); if (list != null && list.Count > 0) { baseLine = list.First(); foreach (KeyValuePair <string, List <Polyline3dInfo> > kvp in slopeLines) { if (!kvp.Key.Equals("КПЧ")) { foreach (Polyline3dInfo poly3dInfo in kvp.Value) { poly3dInfo.BaseLine = baseLine.Poly2d; poly3dInfo.ComputeParameters(); poly3dInfo.ComputeOrientation(); //проверка, что все линии с одной стороны от базовой if (toTheRight != null) { if (toTheRight != poly3dInfo.ToTheRightOfBaseLine) { wrongPolylinesException.Mistakes = wrongPolylinesException.Mistakes | Mistake.WrongOrientation; } } else { toTheRight = poly3dInfo.ToTheRightOfBaseLine; } } } } } if (wrongPolylinesException.Mistakes != Mistake.None) { throw wrongPolylinesException; } #region Test //ed.WriteMessage("\nОшибок нет\ntoTheRight = " + toTheRight); ////Начертить круги в точках начала и конца полилиний //BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; //BlockTableRecord ms // = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); //foreach (KeyValuePair<string, List<Polyline3dInfo>> kvp in slopeLines) //{ // if (!kvp.Key.Equals("КПЧ")) // { // foreach (Polyline3dInfo poly3dInfo in kvp.Value) // { // Point3d pt1 = poly3dInfo.Poly3d.GetPointAtParameter(poly3dInfo.StartParameter); // Point3d pt2 = poly3dInfo.Poly3d.GetPointAtParameter(poly3dInfo.EndParameter); // Point3d pt3 = baseLine.Poly3d.GetPointAtParameter(poly3dInfo.StartParameterBase); // Point3d pt4 = baseLine.Poly3d.GetPointAtParameter(poly3dInfo.EndParameterBase); // foreach (Point3d pt in new Point3d[] { pt1, pt2, pt3, pt4 }) // { // using (Circle circle = new Circle(pt, Vector3d.ZAxis, 1)) // { // circle.Color = Color.FromColorIndex(ColorMethod.ByAci, 1); // ms.AppendEntity(circle); // tr.AddNewlyCreatedDBObject(circle, true); // } // } // using (Line line = new Line(pt1, pt3)) // { // line.Color = Color.FromColorIndex(ColorMethod.ByAci, 1); // ms.AppendEntity(line); // tr.AddNewlyCreatedDBObject(line, true); // } // using (Line line = new Line(pt2, pt4)) // { // line.Color = Color.FromColorIndex(ColorMethod.ByAci, 1); // ms.AppendEntity(line); // tr.AddNewlyCreatedDBObject(line, true); // } // } // } //} #endregion tr.Commit(); } //Включать подсветку 3d полилиний, которые участвуют в расчете highlighted.Clear(); foreach (KeyValuePair <string, List <Polyline3dInfo> > kvp in slopeLines) { foreach (Polyline3dInfo p3dI in kvp.Value) { p3dI.Poly3d.Highlight(); highlighted.Add(p3dI.Poly3d); } } int spillwayNum = 1; PositionData positionData = new PositionData(); while (true) { //Указать точку расположения водосброса PromptPointResult pPtRes; PromptPointOptions pPtOpts = new PromptPointOptions(""); pPtOpts.Message = "\nУкажите точку расположения водосброса: "; pPtRes = adoc.Editor.GetPoint(pPtOpts); if (pPtRes.Status == PromptStatus.OK) { Point3d pickedPt = new Point3d(pPtRes.Value.X, pPtRes.Value.Y, 0); Point3d nearestPtOnBase = baseLine.Poly2d.GetClosestPointTo(pickedPt, true); //найти ближайшую точку базовой линии double pickedParameterBase = baseLine.Poly2d.GetParameterAtPoint(nearestPtOnBase); //параметр базовой линии в этой точке //Найти все линии откоса, которые расположены в районе данного параметра //Предполагается, что для каждого кода есть только одна такая List <Polyline3dInfo> pickedPtSlopeLines = slopeLines["ОТК"].FindAll(l => l.StartParameterBase <= pickedParameterBase && l.EndParameterBase >= pickedParameterBase); if (pickedPtSlopeLines.Count > 1)//Проверить, что найдены минимум 2 линии перелома откоса { //Найти ближайшую линию к базовой линии - это бровка Polyline3dInfo edgeLine = null; double minDist = double.MaxValue; foreach (Polyline3dInfo p3dI in pickedPtSlopeLines) { Point3d ptOnLine = p3dI.Poly2d.GetClosestPointTo(nearestPtOnBase, false); double distance = ptOnLine.DistanceTo(nearestPtOnBase); if (distance < minDist) { minDist = distance; edgeLine = p3dI; } } Point3d nearestPtOnEdge = edgeLine.Poly2d.GetClosestPointTo(pickedPt, true); //найти ближайшую точку бровки double pickedParameterEdge = edgeLine.Poly2d.GetParameterAtPoint(nearestPtOnEdge); //параметр бровки в этой точке //Найти касательную к бровке Vector3d tangentVector = edgeLine.Poly2d.GetFirstDerivative(pickedParameterEdge); double rotateAngle = toTheRight.Value ? -Math.PI / 2 : Math.PI / 2; Vector3d spillWayVector = tangentVector.RotateBy(rotateAngle, Vector3d.ZAxis).GetNormal();//вектор водосброса, перпендикулярный бровке Line spillWayAxis = new Line(nearestPtOnEdge, nearestPtOnEdge + spillWayVector); Point3dCollection intersections = new Point3dCollection(); baseLine.Poly2d.IntersectWith(spillWayAxis, Intersect.ExtendArgument, horizontalPlane, intersections, new IntPtr(0), new IntPtr(0)); if (intersections.Count > 0) { Point3d basePt = intersections[0];//Точка пересечения оси водосброса с КПЧ //Найти точки пересечения перпендикуляра к ОТК0 и остальными линиями откоса //Отсортировать все линии по удаленности от КПЧ в этой точке SortedDictionary <Point3d, Polyline3dInfo> intersectionPts = new SortedDictionary <Point3d, Polyline3dInfo>(new PtsSortComparer(basePt)); pickedPtSlopeLines.Add(baseLine); foreach (Polyline3dInfo p3dI in pickedPtSlopeLines) { intersections.Clear(); p3dI.Poly2d.IntersectWith(spillWayAxis, Intersect.ExtendArgument, horizontalPlane, intersections, new IntPtr(0), new IntPtr(0)); if (intersections.Count > 0) { intersectionPts.Add(intersections[0], p3dI); } } if (intersectionPts.Count == pickedPtSlopeLines.Count)//Проверить, что все пересечения найдены { //intersectionPts содержит все линии с точками пересечения в нужном порядке, //но все точки пересечения лежат на плоскости XY //Расчитать трехмерные точки Point3dCollection pts = new Point3dCollection(); foreach (KeyValuePair <Point3d, Polyline3dInfo> kvp in intersectionPts) { Point3d pt2d = kvp.Key; pt2d = kvp.Value.Poly2d.GetClosestPointTo(pt2d, false);//по какой-то причине в некоторых случаях без этой строки вылетала ошибка при получении параметра double param = kvp.Value.Poly2d.GetParameterAtPoint(pt2d); Point3d pt3d = kvp.Value.Poly3d.GetPointAtParameter(param); pts.Add(pt3d); } using (Transaction tr = db.TransactionManager.StartTransaction()) { //Регистрация приложения Utils.RegisterApp(db, tr); ObjectId layerId = Utils.CreateLayerIfNotExists("ВОДОСБРОС", db, tr, null, Color.FromColorIndex(ColorMethod.ByAci, 150), LineWeight.LineWeight030); BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); //Вычерчивание 3d полилинии по линии водосброса using (Polyline3d poly3d = new Polyline3d()) { poly3d.LayerId = layerId; poly3d.PolyType = Poly3dType.SimplePoly; ms.AppendEntity(poly3d); tr.AddNewlyCreatedDBObject(poly3d, true); foreach (Point3d pt in pts) { PolylineVertex3d vertex = new PolylineVertex3d(pt); poly3d.AppendVertex(vertex); tr.AddNewlyCreatedDBObject(vertex, true); } //В расширенные данные записать название водосброса poly3d.XData = new ResultBuffer( new TypedValue(1001, Constants.AppName), new TypedValue(1000, spillwayNum.ToString())); } tr.Commit(); } Vector3d baseVector = Vector3d.YAxis; int sign = Math.Sign(baseVector.CrossProduct(spillWayVector).Z); double rotation = spillWayVector.GetAngleTo(baseVector) * sign; //в радианах rotation = rotation * 180 / (Math.PI); //в градусах List <Slope> slopes = new List <Slope>(); //Сохраниение расположения водосброса и всех уклонов for (int i = 0; i < pts.Count - 1; i++) { Point3d pt1 = pts[i]; Point3d pt2 = pts[i + 1]; Point2d pt1_2d = new Point2d(pt1.X, pt1.Y); Point2d pt2_2d = new Point2d(pt2.X, pt2.Y); double len = pt1_2d.GetDistanceTo(pt2_2d); if (len > 0) { double s = (pt2.Z - pt1.Z) / len; slopes.Add(new Slope() { S = s, Len = len }); } } SpillwayPosition spillwayPosition = new SpillwayPosition() { Name = spillwayNum.ToString(), X = pts[0].X, Y = pts[0].Y, Z = pts[0].Z, Z_Rotation = rotation, ToTheRight = toTheRight.Value, Slopes = slopes }; spillwayNum++; positionData.SpillwayPositions.Add(spillwayPosition); } } } } else { //ed.WriteMessage("\nвыбор закончен"); break; } } //ed.WriteMessage("\nпродолжение выполнения"); //Сериализация расположений. Сохранить xml в папку рядом с файлом if (positionData.SpillwayPositions.Count > 0) { //TODO: Учесть возможные ошибки из-за отсутствия прав string filename = null; int n = 0; do { filename = Path.Combine(Path.GetDirectoryName(adoc.Name), Path.GetFileNameWithoutExtension(adoc.Name) /*"SpillwayPositions"*/ + "_" + n + ".xml"); n++; } while (File.Exists(filename)); XmlSerializer xmlSerializer = new XmlSerializer(typeof(PositionData)); using (StreamWriter sw = new StreamWriter(filename)) { xmlSerializer.Serialize(sw, positionData); } //Cообщение о том, что все выполнено ed.WriteMessage("\nПоложение водосбросов сохранено в файле " + filename); } } } catch (System.Exception ex) { //Utils.ErrorToCommandLine(ed, "Ошибка при извлечении расположений водосбросов", ex); CommonException(ex, "Ошибка при извлечении расположений водосбросов"); } finally { foreach (Polyline3d p3d in highlighted) { p3d.Unhighlight(); } } }
private double Cosine(Point2d pt) { double d = _p0.GetDistanceTo(pt); return(d == 0.0 ? 1.0 : Math.Round((pt.X - _p0.X) / d, 9)); }
public void BD2() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = HostApplicationServices.WorkingDatabase; Editor ed = doc.Editor; string clayername = db.GetCurrentLayerName(); string xckPath = Tools.GetCurrentPath() + @"\BaseDwgs\常用图块.dwg"; string blkname = "LED筒灯"; ed.WriteMessage("\n百福工具箱——快速通道照明灯具"); //输入天花灯具的起始点和终止点 PromptPointResult ppr1 = ed.GetPoint("\n请选择起始点"); if (ppr1.Status == PromptStatus.OK) { Point2d spt = new Point2d(ppr1.Value.X, ppr1.Value.Y); PromptPointOptions ppo = new PromptPointOptions("\n请选择终止点") { BasePoint = ppr1.Value, UseBasePoint = true }; PromptPointResult ppr2 = ed.GetPoint(ppo); if (ppr2.Status == PromptStatus.OK) { Point2d ept = new Point2d(ppr2.Value.X, ppr2.Value.Y); double dis = spt.GetDistanceTo(ept); PromptDoubleOptions pdo = new PromptDoubleOptions("\n请输入间距,默认为1200mm") { AllowNegative = false, //不允许输入负数 DefaultValue = 1200 //设置默认值 }; PromptDoubleResult pdr = ed.GetDouble(pdo); if (pdr.Status == PromptStatus.OK) { double jj = pdr.Value; int n = (int)(dis / jj); jj = dis / n; while (jj >= 1200) { n++; jj = dis / n; } Vector2d vec = (ept - spt) / n; Point3d insertPoint = new Point3d(spt.X, spt.Y, 0); db.SetCurrentLayer("BF-灯具"); for (int i = 1; i <= n; i++) { insertPoint = new Point3d(insertPoint.X + vec.X, insertPoint.Y + vec.Y, 0); using (Transaction trans = db.TransactionManager.StartTransaction()) { LayerTable lt = (LayerTable)trans.GetObject(db.LayerTableId, OpenMode.ForRead); db.ImportBlocksFromDWG(xckPath, blkname); ObjectId spaceId = db.CurrentSpaceId;//获取当前空间(模型空间或图纸空间) spaceId.InsertBlockReference("BF-灯具", blkname, insertPoint, new Scale3d(1), 0); trans.Commit(); } } ed.WriteMessage($"\n筒灯间距是{string.Format("{0:F2}", jj)}mm"); } } } db.SetCurrentLayer(clayername); }
public void TcJianTou() { this.point2dCollection_0 = new Point2dCollection(); this.point3d_1 = CAD.GetPoint("选择插入点: "); Point3d point3d; if (!(this.point3d_1 == point3d)) { Point2dCollection point2dCollection = this.point2dCollection_0; Point2d point2d; point2d..ctor(this.point3d_1.X, this.point3d_1.Y); point2dCollection.Add(point2d); Polyline polyline = new Polyline(); short num; for (;;) { num = checked ((short)(this.point2dCollection_0.Count - 1)); if (num >= 1) { Class36.smethod_64(polyline.ObjectId); polyline = new Polyline(); polyline.SetDatabaseDefaults(); short num2 = 0; short num3 = num; short num4 = num2; for (;;) { short num5 = num4; short num6 = num3; if (num5 > num6) { break; } polyline.AddVertexAt((int)num4, this.point2dCollection_0[(int)num4], 0.0, 0.0, 0.0); num4 += 1; } CAD.AddEnt(polyline); } short num7 = this.GangJin(); if (num7 != 1) { break; } this.point3d_1 = this.point3d_2; Point2dCollection point2dCollection2 = this.point2dCollection_0; point2d..ctor(this.point3d_2.X, this.point3d_2.Y); point2dCollection2.Add(point2d); } num = checked ((short)(this.point2dCollection_0.Count - 1)); if (num >= 1) { Class36.smethod_64(polyline.ObjectId); polyline = new Polyline(); polyline.SetDatabaseDefaults(); short num8 = 0; short num9 = num; short num10 = num8; for (;;) { short num11 = num10; short num6 = num9; if (num11 > num6) { break; } polyline.AddVertexAt((int)num10, this.point2dCollection_0[(int)num10], 0.0, 0.0, 0.0); num10 += 1; } Point2d p = this.point2dCollection_0[(int)num]; Point2d point2d2 = this.point2dCollection_0[(int)(checked (num - 1))]; double angle = p.GetVectorTo(point2d2).Angle; double num12 = p.GetDistanceTo(point2d2); num12 = Math.Min(num12, 400.0); Point2d point2dAngle = CAD.GetPoint2dAngle(p, num12, angle * 180.0 / 3.1415926535897931); polyline.AddVertexAt((int)num, this.point2dCollection_0[(int)num], 0.0, 0.0, 90.0); polyline.AddVertexAt((int)(checked (num + 1)), point2dAngle, 0.0, 90.0, 0.0); CAD.AddEnt(polyline); } } }
TP4() { gp.pnt3d1 = Pub.pnt3dO; gp.pnt3d2 = Pub.pnt3dO; ps = PromptStatus.Cancel; object mode = 0; BaseObjs.acadActivate(); Vector3d v3d = Vector3d.XAxis; try { elev = UserInput.getCogoPoint("\nPick Cogo Point 1: ", out idCgPnt1, ObjectId.Null, osMode: 8); if (elev == "") { return; } else { gp.pnt3d1 = idCgPnt1.getCogoPntCoordinates(); } elev = UserInput.getCogoPoint("\nPick Cogo Point 2: ", out idCgPnt2, ObjectId.Null, osMode: 8); if (elev == "") { return; } else { gp.pnt3d2 = idCgPnt2.getCogoPntCoordinates(); } mode = SnapMode.getOSnap(); SnapMode.setOSnap(8); gp.pnt3dX = Pub.pnt3dO; gp.pnt3dT = Pub.pnt3dO; System.Windows.Forms.Keys mods = System.Windows.Forms.Control.ModifierKeys; bool shift = (mods & System.Windows.Forms.Keys.Shift) > 0; bool control = (mods & System.Windows.Forms.Keys.Control) > 0; gp.shift = shift; gp.pnt3dT = gPnt.getPoint("\nSelect Target location (CogoPoint for xSlope and distance / pick side to enter xSlope and distance: ", "cmdTP"); if (gp.pnt3dT == Pub.pnt3dO) { return; } else if (gp.pnt3dT.Z == 0) { gp.pnt3dX = gc.calcBasePnt3d(gp.pnt3dT, gp.pnt3d1, gp.pnt3d2); if (gp.pnt3dX == Pub.pnt3dO) { return; } escaped = UserInput.getUserInputDoubleAsString("\nEnter Cross Slope (+ or -): ", out xSlope, xSlope); if (escaped) { return; } escaped = UserInput.getUserInputDoubleAsString("\nEnter Width: ", out width, width); if (escaped) { return; } double dist = gp.pnt3d1.getDistance(gp.pnt3d2); double distX = gp.pnt3d1.getDistance(gp.pnt3dX); Point2d pnt2dX = gp.pnt3dX.Convert2d(BaseObjs.xyPlane); Point2d pnt2dT = gp.pnt3dT.Convert2d(BaseObjs.xyPlane); double distT = pnt2dX.GetDistanceTo(pnt2dT); gp.pnt3dT = new Point3d(gp.pnt3dT.X, gp.pnt3dT.Y, gp.pnt3dX.Z + distT * double.Parse(xSlope)); v3d = gp.pnt3dT - gp.pnt3dX; v3d *= double.Parse(width) / distT; } else { gp.pnt3dX = gc.calcBasePnt3d(gp.pnt3dT, gp.pnt3d1, gp.pnt3d2); if (gp.pnt3dX == Pub.pnt3dO) { return; } CgPnt.setPoint(gp.pnt3dX, out pntNum, "CPNT-ON"); v3d = gp.pnt3dT - gp.pnt3dX; } } catch (System.Exception ex) { BaseObjs.writeDebug(ex.Message + " cmdTP.cs: line: 336"); } finally { SnapMode.setOSnap((int)mode); } ObjectId idPoly = ObjectId.Null; Point3d pnt3d3 = idCgPnt2.getCogoPntCoordinates() + v3d; ObjectId idCgPnt3 = pnt3d3.setPoint(out pntNum); Point3d pnt3d4 = idCgPnt1.getCogoPntCoordinates() + v3d; ObjectId idCgPnt4 = pnt3d4.setPoint(out pntNum); List <ObjectId> idCgPnts = new List <ObjectId> { idCgPnt1, idCgPnt2 }; BrkLine.makeBreakline(apps.lnkBrks, "cmdTP4", out idPoly, idCgPnts); idCgPnts = new List <ObjectId> { idCgPnt2, idCgPnt3 }; BrkLine.makeBreakline(apps.lnkBrks, "cmdTP4", out idPoly, idCgPnts); idCgPnts = new List <ObjectId> { idCgPnt3, idCgPnt4 }; BrkLine.makeBreakline(apps.lnkBrks, "cmdTP4", out idPoly, idCgPnts); idCgPnts = new List <ObjectId> { idCgPnt4, idCgPnt1 }; BrkLine.makeBreakline(apps.lnkBrks, "cmdTP4", out idPoly, idCgPnts); }
private static Entity DrawPart(Segment[] segs, Point[] points, Point[] densifiedPoints, bool closePart, bool hasZ, double defaultElevation) { double num = 0.0; if (segs != null) { if (segs.Length == 1) { CircularArc circularArc = segs[0] as CircularArc; EllipticArc ellipticArc = segs[0] as EllipticArc; BezierCurve bezierCurve = segs[0] as BezierCurve; ArcGIS10Types.Line line = segs[0] as ArcGIS10Types.Line; if (circularArc != null) { if (((PointN)circularArc.FromPoint).X == ((PointN)circularArc.ToPoint).X && ((PointN)circularArc.FromPoint).Y == ((PointN)circularArc.ToPoint).Y) { return(GIS2CAD.DrawCircle(circularArc, defaultElevation)); } return(GIS2CAD.DrawCircularArc(circularArc, defaultElevation, densifiedPoints)); } else if (ellipticArc != null) { if (!ellipticArc.IsCounterClockwise) { return(AGSEllipticalArc.ToCadSpline(ellipticArc, defaultElevation)); } return(AGSEllipticalArc.ToCadEllipse(ellipticArc, defaultElevation)); } else { if (line != null) { return(GIS2CAD.DrawPolyline(densifiedPoints, false)); } if (bezierCurve != null) { return(GIS2CAD.DrawPolyline(densifiedPoints, closePart)); } } } else if (segs.Length > 1) { PointN pointN = segs[0].FromPoint as PointN; num = pointN.Z; if (num == 0.0) { num = defaultElevation; } if (GIS2CAD.CanBeDrawnAsPolyline(segs)) { var polyline = new Autodesk.AutoCAD.DatabaseServices.Polyline(); polyline.ColorIndex = (256); int num2 = 0; PointN pointN2 = (PointN)segs[0].ToPoint; for (int i = 0; i < segs.Length; i++) { Segment segment = segs[i]; CircularArc circularArc2 = segment as CircularArc; var line2 = segment as ArcGIS10Types.Line; if (line2 != null) { PointN pointN3 = (PointN)line2.FromPoint; polyline.AddVertexAt(num2++, new Point2d(pointN3.X, pointN3.Y), 0.0, -1.0, -1.0); pointN2 = (PointN)line2.ToPoint; } else if (circularArc2 != null) { PointN pointN4 = (PointN)circularArc2.CenterPoint; PointN pointN5 = (PointN)circularArc2.FromPoint; PointN pointN6 = (PointN)circularArc2.ToPoint; new Point2d(pointN5.X - pointN4.X, pointN5.Y - pointN4.Y); new Point2d(pointN6.X - pointN4.X, pointN6.Y - pointN4.Y); Point2d point2d = new Point2d(pointN5.X, pointN5.Y); Point2d centerPoint = new Point2d(pointN4.X, pointN4.Y); Point2d point2d2 = new Point2d(pointN6.X, pointN6.Y); double num3 = Math.Abs(centerPoint.GetDistanceTo(point2d)); double num4 = Math.Abs(point2d.GetDistanceTo(point2d2)); double num5 = num3; double num6 = num3; double d = (num5 * num5 + num6 * num6 - num4 * num4) / (2.0 * num5 * num6); double num7 = Math.Acos(d); num7 = GIS2CAD.CalcThetaFromVectors(point2d, point2d2, centerPoint, circularArc2.IsCounterClockwise); double num8 = Math.Tan(num7 / 4.0); if (!circularArc2.IsCounterClockwise) { num8 *= -1.0; } polyline.AddVertexAt(num2++, point2d, num8, -1.0, -1.0); pointN2 = pointN6; } } polyline.AddVertexAt(num2, new Point2d(pointN2.X, pointN2.Y), 0.0, -1.0, -1.0); if (closePart) { polyline.Closed = (true); } return(polyline); } return(GIS2CAD.Draw3dPline(densifiedPoints, closePart)); } } else if (points != null) { if (points.Length == 2) { var line3 = new Autodesk.AutoCAD.DatabaseServices.Line(); line3.ColorIndex = (256); GIS2CAD.AdjustZ(ref points, defaultElevation); Point3d startPoint = GIS2CAD.ToCadPoint3d((PointN)points[0]); Point3d endPoint = GIS2CAD.ToCadPoint3d((PointN)points[1]); line3.StartPoint = (startPoint); line3.EndPoint = (endPoint); return(line3); } if (points.Length > 0) { if (!GIS2CAD.IsPlanar(points)) { try { Document document = AfaDocData.ActiveDocData.Document; var database = document.Database; var transactionManager = document.TransactionManager; using (document.LockDocument()) { using (Transaction transaction = transactionManager.StartTransaction()) { BlockTable blockTable = (BlockTable)transaction.GetObject(database.BlockTableId, 0); BlockTableRecord blockTableRecord = (BlockTableRecord)transaction.GetObject(blockTable[(BlockTableRecord.ModelSpace)], (OpenMode)1); Polyline3d polyline3d = new Polyline3d(); polyline3d.ColorIndex = (256); blockTableRecord.AppendEntity(polyline3d); transaction.AddNewlyCreatedDBObject(polyline3d, true); Point[] array = points; for (int j = 0; j < array.Length; j++) { PointN srcPt = (PointN)array[j]; PolylineVertex3d polylineVertex3d = new PolylineVertex3d(GIS2CAD.ToCadPoint3d(srcPt)); polyline3d.AppendVertex(polylineVertex3d); transaction.AddNewlyCreatedDBObject(polylineVertex3d, true); } if (closePart) { polyline3d.Closed = (true); } document.TransactionManager.QueueForGraphicsFlush(); document.TransactionManager.FlushGraphics(); document.Editor.UpdateScreen(); transaction.Commit(); return(polyline3d); } } } catch (System.Exception ex) { string arg_526_0 = ex.Message; } } var polyline2 = new Autodesk.AutoCAD.DatabaseServices.Polyline(); polyline2.ColorIndex = (256); polyline2.Elevation = (num); num = ((PointN)points[0]).Z; if (num == 0.0) { num = defaultElevation; } int num9 = 0; Point[] array2 = points; for (int k = 0; k < array2.Length; k++) { PointN pointN7 = (PointN)array2[k]; polyline2.AddVertexAt(num9++, new Point2d(pointN7.X, pointN7.Y), 0.0, -1.0, -1.0); } if (closePart) { polyline2.Closed = (true); } return(polyline2); } } return(null); }
// overload no scale factor or set the view - just make the layout public void LayoutAndViewport(Database db, string layoutName, out ObjectId rvpid, string deviceName, string mediaName, out ObjectId id) { // set default values rvpid = new ObjectId(); bool flagVp = false; // flag to create a new floating view port double viewSize = (double)Application.GetSystemVariable("VIEWSIZE"); double height = viewSize; double width = viewSize; Point2d loCenter = new Point2d(); // layout center point Point2d vpLowerCorner = new Point2d(); Point2d vpUpperCorner = new Point2d(); Document doc = Application.DocumentManager.MdiActiveDocument; LayoutManager lm = LayoutManager.Current; id = lm.CreateLayout(layoutName); using (Transaction tr = db.TransactionManager.StartTransaction()) { Layout lo = tr.GetObject(id, OpenMode.ForWrite, false) as Layout; if (lo != null) { lm.CurrentLayout = lo.LayoutName; // make it current! #region do some plotting settings here for the paper size... ObjectId loid = lm.GetLayoutId(lo.LayoutName); PlotInfo pi = new PlotInfo(); pi.Layout = loid; PlotSettings ps = new PlotSettings(false); PlotSettingsValidator psv = PlotSettingsValidator.Current; psv.RefreshLists(ps); psv.SetPlotConfigurationName(ps, deviceName, mediaName); psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Layout); psv.SetPlotPaperUnits(ps, PlotPaperUnit.Inches); psv.SetUseStandardScale(ps, true); psv.SetStdScaleType(ps, StdScaleType.ScaleToFit); // use this as default pi.OverrideSettings = ps; PlotInfoValidator piv = new PlotInfoValidator(); piv.Validate(pi); lo.CopyFrom(ps); PlotConfig pc = PlotConfigManager.CurrentConfig; // returns data in millimeters... MediaBounds mb = pc.GetMediaBounds(mediaName); Point2d p1 = mb.LowerLeftPrintableArea; Point2d p3 = mb.UpperRightPrintableArea; Point2d p2 = new Point2d(p3.X, p1.Y); Point2d p4 = new Point2d(p1.X, p3.Y); // convert millimeters to inches double mm2inch = 25.4; height = p1.GetDistanceTo(p4) / mm2inch; width = p1.GetDistanceTo(p2) / mm2inch; vpLowerCorner = lo.PlotOrigin; vpUpperCorner = new Point2d(vpLowerCorner.X + width, vpLowerCorner.Y + height); LineSegment2d seg = new LineSegment2d(vpLowerCorner, vpUpperCorner); loCenter = seg.MidPoint; #endregion if (lo.GetViewports().Count == 1) // Viewport was not created by default { // the create by default view ports on new layouts it // is off we need to mark a flag to generate a new one // in another transaction - out of this one flagVp = true; } else if (lo.GetViewports().Count == 2) // create Viewports by default it is on { // extract the last item from the collection // of view ports inside of the layout int i = lo.GetViewports().Count - 1; ObjectId vpId = lo.GetViewports()[i]; if (!vpId.IsNull) { Viewport vp = tr.GetObject(vpId, OpenMode.ForWrite, false) as Viewport; if (vp != null) { vp.Height = height; // change height vp.Width = width; // change width vp.CenterPoint = new Point3d(loCenter.X, loCenter.Y, 0.0); // change center //vp.ColorIndex = 1; // debug // zoom to the Viewport extents Zoom(new Point3d(vpLowerCorner.X, vpLowerCorner.Y, 0.0), new Point3d(vpUpperCorner.X, vpUpperCorner.Y, 0.0), new Point3d(), 1.0); rvpid = vp.ObjectId; // return the output ObjectId to out... } } } } tr.Commit(); } // end of transaction // we need another transaction to create a new paper space floating Viewport if (flagVp) { using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); BlockTableRecord btr_ps = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.PaperSpace], OpenMode.ForWrite); Viewport vp = new Viewport(); vp.Height = height; // set the height vp.Width = width; // set the width vp.CenterPoint = new Point3d(loCenter.X, loCenter.Y, 0.0); // set the center //vp.ColorIndex = 2; // debug btr_ps.AppendEntity(vp); tr.AddNewlyCreatedDBObject(vp, true); vp.On = true; // make it accessible! // zoom to the Viewport extents Zoom(new Point3d(vpLowerCorner.X, vpLowerCorner.Y, 0.0), new Point3d(vpUpperCorner.X, vpUpperCorner.Y, 0.0), new Point3d(), 1.0); rvpid = vp.ObjectId; // return the ObjectId to the out... tr.Commit(); } // end of transaction } }
public override bool WorldDraw( Autodesk.AutoCAD.GraphicsInterface.Drawable drawable, Autodesk.AutoCAD.GraphicsInterface.WorldDraw wd) { base.WorldDraw(drawable, wd); Polyline pline = (Polyline)drawable; double length = pline.Length; int numberOfLabels = (int)(length / labelDist); if (numberOfLabels == 0) { numberOfLabels = 1; } for (int i = 0; i < numberOfLabels + 1; i++) { #region Size label double dist = labelDist * i; if (numberOfLabels == 1) { dist = length / 2; } Point3d pt = pline.GetPointAtDist(dist); int dn = IntersectUtilities.PipeSchedule.GetPipeDN(pline); string system = IntersectUtilities.PipeSchedule.GetPipeType(pline) == IntersectUtilities.PipeSchedule.PipeTypeEnum.Twin ? "T" : "E"; string label = $"DN{dn}-{system}"; Vector3d deriv = pline.GetFirstDerivative(pt); deriv = deriv.GetNormal(); Vector3d perp = deriv.GetPerpendicularVector(); wd.Geometry.Text( pt + perp * labelOffset, Vector3d.ZAxis, deriv, label, true, style); //pt + perp * labelOffset, Vector3d.ZAxis, deriv, labelHeight, 1.0, 0.0, label); //wd.Geometry.Text( // pt + perp * labelOffset, Vector3d.ZAxis, deriv, labelHeight, 1.0, 0.0, label); #endregion } #region Buerør label int nrOfVertices = pline.NumberOfVertices; for (int j = 0; j < pline.NumberOfVertices - 1; j++) { //Guard against already cut out curves double b = pline.GetBulgeAt(j); if (b == 0) { continue; } Point2d fP = pline.GetPoint2dAt(j); Point2d sP = pline.GetPoint2dAt(j + 1); double u = fP.GetDistanceTo(sP); double radius = u * ((1 + b.Pow(2)) / (4 * Math.Abs(b))); double minRadius = IntersectUtilities.PipeSchedule.GetPipeMinElasticRadius(pline, false); bool isInSituBuk = IntersectUtilities.PipeSchedule.IsInSituBent(pline); //If radius is less than minRadius a buerør is detected //Split the pline in segments delimiting buerør and append Point3d fP3d = new Point3d(fP.X, fP.Y, 0); Point3d sP3d = new Point3d(sP.X, sP.Y, 0); double fL = pline.GetDistAtPoint(fP3d); double sL = pline.GetDistAtPoint(sP3d); Vector3d vec = pline.GetFirstDerivative(fP3d); vec = vec.GetNormal(); vec = vec.GetPerpendicularVector(); Point3d pt1 = fP3d + vec; Point3d pt2 = fP3d - vec; wd.Geometry.WorldLine(pt1, pt2); vec = pline.GetFirstDerivative(sP3d); vec = vec.GetNormal(); vec = vec.GetPerpendicularVector(); pt1 = sP3d + vec; pt2 = sP3d - vec; wd.Geometry.WorldLine(pt1, pt2); string label; if (radius > minRadius) { label = $"Elastisk R{radius.ToString("0.##")}"; } else { double arcLength = sL - fL; if (isInSituBuk) { label = $"In-situ buk R{radius.ToString("0.##")} L{arcLength.ToString("0.##")}"; } else { double angle = arcLength / ((Math.PI / 180) * radius); label = $"Buerør R{radius.ToString("0.##")} L{arcLength.ToString("0.##")} A{angle.ToString("0.##")}"; } } CircularArc2d arc = pline.GetArcSegment2dAt(j); Point2d[] samples = arc.GetSamplePoints(3); Point3d midPt = new Point3d(samples[1].X, samples[1].Y, 0); Vector3d deriv = pline.GetFirstDerivative(midPt); deriv = deriv.GetNormal(); Vector3d perp = deriv.GetPerpendicularVector(); if (b > 0) { perp = -perp; } //wd.Geometry.Text( // midPt + perp * (labelOffset + labelHeight + 0.7), Vector3d.ZAxis, deriv, labelHeight, 1.0, 0.0, label); wd.Geometry.Text( midPt + perp * (labelOffset + labelHeight + 0.7), Vector3d.ZAxis, deriv, label, true, style); } #endregion return(true); }
public static void AddSpline() { if (!Ativacao()) { MessageBox.Show("Esta API não está ativada. Entre em contato com a SELTTE!"); return; } pt1x = GetPoint(); // Caso não se clique em lugar algum, o comando é finalizado if (pt1x.X == 0.0 && pt1x.Y == 0.0) { Editor editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor; editor.WriteMessage("\n-> Cancelado!\n"); return; } pt2x = GetPoint(); // Caso não se clique em lugar algum, o comando é finalizado if (pt2x.X == 0.0 && pt2x.Y == 0.0) { Editor editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor; editor.WriteMessage("\n-> Cancelado!\n"); return; } pt1 = new Point2d(pt1x.X, pt1x.Y); pt2 = new Point2d(pt2x.X, pt2x.Y); if (pt1.X > pt2.X || pt1.Y > pt2.Y) { Point2d ptx = pt1; pt1 = pt2; pt2 = ptx; } // Get the current document and database Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; Editor ed = acDoc.Editor; // Start a transaction using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // Open the Block table for read BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // Open the Block table record Model space for write BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; double anglePt1Pt2 = pt1.GetVectorTo(pt2).Angle; if (anglePt1Pt2 > Math.PI) { anglePt1Pt2 -= Math.PI; } //PolarPoints(pt1.Add((pt2.Subtract(pt1.GetAsVector()) / 4).GetAsVector()), pt1.GetVectorTo(pt2).GetAngleTo(pt2.GetAsVector()) + Math.PI / 2, 10); Point2d pt3 = PolarPoints(pt1.Add(pt1.GetVectorTo(pt2) / 4), anglePt1Pt2 + Math.PI / 2, pt1.GetDistanceTo(pt2) * 0.1); Point2d pt4 = PolarPoints(pt2.Subtract((pt2.Subtract(pt1.GetAsVector()) / 4).GetAsVector()), anglePt1Pt2 - Math.PI / 2, pt1.GetDistanceTo(pt2) * 0.1); Point3d pt5 = new Point3d(pt1.X, pt1.Y, 0); // pt1 em 3d Point3d pt6 = new Point3d(pt3.X, pt3.Y, 0); // pt3 em 3d Point3d pt7 = new Point3d(pt4.X, pt4.Y, 0); // pt4 em 3d Point3d pt8 = new Point3d(pt2.X, pt2.Y, 0); // pt2 em 3d // Define the fit points for the spline Point3dCollection ptColl = new Point3dCollection { pt5, pt6, pt7, pt8 }; // Create a spline through (0, 0, 0), (5, 5, 0), and (10, 0, 0) with a // start and end tangency of (0.5, 0.5, 0.0) using (Spline acSpline = new Spline(ptColl, new Point3d(0.0000, 0.0000, 0.0000).GetAsVector(), new Point3d(0.0000, 0.0000, 0.0000).GetAsVector(), 0, 0.0)) { // Add the new object to the block table record and the transaction acBlkTblRec.AppendEntity(acSpline); acTrans.AddNewlyCreatedDBObject(acSpline, true); } acDoc.SendStringToExecute("Trim ", true, false, false); // Save the new line to the database acTrans.Commit(); } }
/// <summary> /// 判断2d点是否在线段上 /// </summary> /// <param name="p"></param> /// <param name="line"></param> /// <returns></returns> public bool IsPointOnLine(Point2d p, Line line) { var flag = p.GetDistanceTo(line.StartPoint.toPoint2d()) + p.GetDistanceTo(line.EndPoint.toPoint2d()) - line.Length < 0.00001; return(flag); }
//private bool joinedEdge = false;//test public void CalcPipePosition(Transaction tr, ObjectId tinSurfId, double defaultDepth, bool sameDepthEveryPt, BlockTableRecord ms) { //Нужно учитывать размеры колодцев при расчете положения ребра! //Колодцы бывают просто цилиндрические и просто коробчатые //Учитывать Rotation, BoundingShape, InnerDiameterOrWidth, InnerLength //Уточнить кривую в плане по которой идет труба с учетом размеров колодца //TODO: Как учесть, что блок прямоугольного колодца может не соответствовать колодцу по направлениям длины и ширины???? PointOnCurve2d startSplitPt = null; PointOnCurve2d endSplitPt = null; CivilDB.Structure strStart = null; CivilDB.Structure strEnd = null; if (!StartNode.StructId.IsNull) { strStart = (CivilDB.Structure)tr.GetObject(StartNode.StructId, OpenMode.ForRead); //уточнить положение начала кривой в начале с учетом размеров колодца! startSplitPt = GetSplitPt(strStart, true); } if (!EndNode.StructId.IsNull) { strEnd = (CivilDB.Structure)tr.GetObject(EndNode.StructId, OpenMode.ForRead); //уточнить положение конца кривой в начале с учетом размеров колодца! endSplitPt = GetSplitPt(strEnd, false); } if (startSplitPt != null && endSplitPt != null && startSplitPt.Parameter >= endSplitPt.Parameter) { //колодцы стоят вплотную друг к другу или залезают друг на друга. Места для трубы на остается return; } //проход по составляющим кривой с отбрасыванием частей, отсекаемых колодцами //Curve2d.GetSplitCurves работает неправильно //Curve2d.Explode тоже не помогает if (startSplitPt == null) { AddPtToPipePositionList(new XYZ(PositionCurve.StartPoint)); } Curve2d[] segments = PositionCurve.GetCurves(); double currParam = 0; foreach (Curve2d seg in segments) { Interval interval = seg.GetInterval(); double len = seg.GetLength(interval.LowerBound, interval.UpperBound); currParam += len; //Если есть точка разбиения в начале и она еще не достигнута if (startSplitPt != null) { if (startSplitPt.Parameter < currParam) { //точка разбиения находится на этой кривой. Ее нужно добавить в список AddPtToPipePositionList(new XYZ(startSplitPt.Point)); startSplitPt = null; } else { //точка отсечения начала еще не достигнута, переход к следующей кривой continue; } } if (endSplitPt != null && endSplitPt.Parameter < currParam) { //точка разбиения находится на этой кривой. Ее нужно добавить в список AddPtToPipePositionList(new XYZ(endSplitPt.Point)); endSplitPt = null; break;//обход точек заканчивается } AddPtToPipePositionList(new XYZ(seg.EndPoint)); } //Задание глубин заложения ребер по концам //- если не задана глубина заложения на одном из концов, сделать их равными //- если не задана глубина на обоих концах задать обоим концам глубину по умолчанию согласно вводу в окне CivilDB.TinSurface tinSurf = (CivilDB.TinSurface)tr.GetObject(tinSurfId, OpenMode.ForRead); double startElevByData = double.NegativeInfinity; double endElevByData = double.NegativeInfinity; if (StartPipeJunctionData != null && StartPipeJunctionData.JunctionLevel != double.NegativeInfinity) { startElevByData = StartPipeJunctionData.JunctionLevel; XYZ xyz = PipePositionList.First(); xyz.Z = startElevByData; } if (EndPipeJunctionData != null && EndPipeJunctionData.JunctionLevel != double.NegativeInfinity) { endElevByData = EndPipeJunctionData.JunctionLevel; XYZ xyz = PipePositionList.Last(); xyz.Z = endElevByData; } if (startElevByData != double.NegativeInfinity && endElevByData == double.NegativeInfinity) { XYZ xyz = PipePositionList.Last(); xyz.Z = startElevByData; } else if (startElevByData == double.NegativeInfinity && endElevByData != double.NegativeInfinity) { XYZ xyz = PipePositionList.First(); xyz.Z = endElevByData; } else if (startElevByData == double.NegativeInfinity && endElevByData == double.NegativeInfinity) { XYZ xyz1 = PipePositionList.First(); SetElevBySurf(defaultDepth, tinSurf, xyz1); XYZ xyz2 = PipePositionList.Last(); SetElevBySurf(defaultDepth, tinSurf, xyz2); } //- но не допускать, чтобы труба опускалась ниже дна колодца double sartElevByStr = double.NegativeInfinity; double endElevByStr = double.NegativeInfinity; if (strStart != null && strStart.SumpElevation > PipePositionList.First().Z) { sartElevByStr = strStart.SumpElevation; PipePositionList.First().Z = sartElevByStr; } if (strEnd != null && strEnd.SumpElevation > PipePositionList.Last().Z) { endElevByStr = strEnd.SumpElevation; PipePositionList.Last().Z = endElevByStr; } //после корректировки уточнить отметку соседней точки если по ней нет данных if (sartElevByStr != double.NegativeInfinity && endElevByData == double.NegativeInfinity) { XYZ xyz = PipePositionList.Last(); xyz.Z = sartElevByStr; } else if (startElevByData == double.NegativeInfinity && endElevByStr != double.NegativeInfinity) { XYZ xyz = PipePositionList.First(); xyz.Z = endElevByStr; } //Убедиться, что если в одном узле без колодца стыкуются несколько ребер, //то в месте стыковки обязательно у всех ребер должна быть одинаковая отметка double neighborJunctElev = GetNeigborJuncElev(StartNode); XYZ startPos = PipePositionList.First(); if (neighborJunctElev != double.NegativeInfinity && startPos.Z != neighborJunctElev) { startPos.Z = neighborJunctElev; } neighborJunctElev = GetNeigborJuncElev(EndNode); XYZ endPos = PipePositionList.Last(); if (neighborJunctElev != double.NegativeInfinity && endPos.Z != neighborJunctElev) { endPos.Z = neighborJunctElev; } //Задание отметок промежуточных точек на ребрах сети (интерполяция либо относительно поверхности) if (PipePositionList.Count > 2) { if (sameDepthEveryPt) { //одинаковая глубина относительно поверхности земли //метод TinSurface.SampleElevations работает не так как надо! Он не дает подробного учета рельефа! //точки полилинии for (int i = 1; i < PipePositionList.Count - 1; i++) { XYZ xyz = PipePositionList[i]; SetElevBySurf(defaultDepth, tinSurf, xyz); } //Помимо углов поворотов нужно добавить промежуточные точки через 1 м для учета рельефа! List <XYZ> positionListExtended = new List <XYZ>(); positionListExtended.Add(PipePositionList.First()); for (int i = 1; i < PipePositionList.Count; i++) { XYZ xyz0 = PipePositionList[i - 1]; XYZ xyz1 = PipePositionList[i]; double len = xyz1.Position2d.GetDistanceTo(xyz0.Position2d); Vector2d vector = (xyz1.Position2d - xyz0.Position2d).GetNormal(); double currLen = 1; while (currLen < len) { //добавление промежуточных точек Point2d pt = xyz0.Position2d + vector * currLen; XYZ intermediateXYZ = new XYZ(pt); SetElevBySurf(defaultDepth, tinSurf, intermediateXYZ); positionListExtended.Add(intermediateXYZ); currLen += 1; } positionListExtended.Add(xyz1); } PipePositionList = positionListExtended; } else { //интерполяция между началом и концом double startElev = startPos.Z; double endElev = endPos.Z; double elevDiff = endElev - startElev; double currLength = 0; for (int i = 1; i < PipePositionList.Count - 1; i++) { XYZ xyz = PipePositionList[i]; Point2d prevPt = PipePositionList[i - 1].Position2d; currLength += prevPt.GetDistanceTo(xyz.Position2d); xyz.Z = startElev + (elevDiff * currLength / pipeHorizontalLength); } } } }