public void CanCreate_AndThrowExceptions() { var ray = new Ray2d(Point2d.Origin, Vector2d.WorldX); Assert.Equal(Point2d.Origin, ray.Origin); Assert.Equal(Vector2d.WorldX, ray.Direction); Assert.Throws <ArgumentNullException>(() => new Ray2d(Point2d.Origin, null)); Assert.Throws <ArgumentNullException>(() => new Ray2d(null, Vector2d.WorldY)); }
private List <ShadowBoundaryPoint> GetBoundaryPoints(List <Point2d> buildingVertexes, Vector2d vecShadow) { List <ShadowBoundaryPoint> boundaryPts = new List <ShadowBoundaryPoint>(); // крайние точки тени - с мин и макс расстоянием на перпендикулярном векторе к лучу var vecFront = vecShadow.GetPerpendicularVector(); var vecFrontNormal = vecFront.GetNormal(); var firstPt = buildingVertexes[0]; Ray2d rayShadow = new Ray2d(firstPt, vecShadow); Vector2d vec1ToRay = new Vector2d(); foreach (var buildVertex in buildingVertexes) { var bPt = new ShadowBoundaryPoint(buildVertex); var ptInRay = rayShadow.GetNormalPoint(buildVertex).Point; var vecToRay = ptInRay - buildVertex; if (vec1ToRay.Length == 0) { vec1ToRay = vecToRay; } else { bPt.LenToRay = vecToRay.Length * (vecToRay.IsCodirectionalTo(vec1ToRay)? 1:-1); } boundaryPts.Add(bPt); } var ptsOrderByLen = boundaryPts.OrderBy(p => p.LenToRay); var minBPt = ptsOrderByLen.First(); var maxBPt = ptsOrderByLen.Last(); var indexMinBPt = boundaryPts.IndexOf(minBPt); var indexMaxBPt = boundaryPts.IndexOf(maxBPt); if (indexMinBPt > indexMaxBPt) { var temp = indexMinBPt; indexMinBPt = indexMaxBPt; indexMaxBPt = temp; } var vecFromMinBptToMax = maxBPt.Point - minBPt.Point; // Определение внутренних и наружных точек здания по отношению к границе тени от этого здания (внешние и внутренние точки) var firstBptFromMinToMax = boundaryPts[indexMinBPt + 1]; var angleToRay = vecShadow.GetAngleTo(firstBptFromMinToMax.Point - minBPt.Point); var typeBPtFromMinToMax = angleToRay <= 90d.ToRadians() ? BoundaryPointType.Internal : BoundaryPointType.External; for (int i = 0; i <= indexMinBPt; i++) { boundaryPts[i].Type = typeBPtFromMinToMax; } var typeOtherBPt = typeBPtFromMinToMax == BoundaryPointType.External ? BoundaryPointType.Internal : BoundaryPointType.External; boundaryPts.Where(b => b.Type == BoundaryPointType.None).Iterate(b => b.Type = typeOtherBPt); return(boundaryPts); }
public void CodeRay2d(ref Ray2d v) { CodeV2d(ref v.Origin); CodeV2d(ref v.Direction); }
public FastRay2d(Ray2d ray) { Ray = ray; DirFlags = ray.Direction.DirFlags(); InvDir = 1.0 / ray.Direction; }
public static List <Point2d> GetProcessPoints1(Curve profile, int index, double step, double shift, bool isMinToolCoord, double?begin, double?end, bool isProfileStep = false) //, bool isExactlyBegin, bool isExactlyEnd) { var result = new List <Point2d>(); var start = 10000D; var rayVector = index == 0 ? -Vector2d.YAxis : -Vector2d.XAxis; var p0 = begin ?? Math.Max(profile.StartPoint[index], profile.EndPoint[index]); var p1 = end ?? Math.Min(profile.StartPoint[index], profile.EndPoint[index]); var dir = Math.Sign(p1 - p0); using (var curve = profile.ToCompositeCurve2d()) using (var ray = new Ray2d()) using (var intersector = new CurveCurveIntersector2d()) { var pos = p0; Point2d?point0 = null; var length = profile.Length(); int curveSign = dir * Math.Sign(curve.EndPoint[index] - curve.StartPoint[index]); double? dist = null; while (dir > 0 ? pos <p1 : pos> p1) { double?max = null; for (int i = 0; i <= 10; i++) { var rayPoint = GetPoint(pos + i * (shift / 10) * dir, start, index); ray.Set(rayPoint, rayVector); intersector.Set(curve, ray); if (intersector.NumberOfIntersectionPoints > 0) { var intersect = intersector.GetIntersectionPoint(0); max = Math.Max(max ?? double.MinValue, intersect[1 - index]); if (!point0.HasValue && i == 0) { point0 = intersect; } } } if (max.HasValue) { var toolCoord = pos + shift * dir * (isMinToolCoord ^ dir < 0 ? 0 : 1); result.Add(GetPoint(toolCoord, max.Value, index)); } if (isProfileStep && point0.HasValue) { if (!dist.HasValue) { dist = curve.GetLength(0, curve.GetParameterOf(point0.Value)); } dist += step * curveSign; if (dist < 0 || dist > length) { break; } var point = curve.EvaluatePoint(curve.GetParameterAtLength(0, dist.Value, true)); pos = point[index]; } else { pos += step * dir; } } } return(result); }
public void CodeRay2d(ref Ray2d v) { throw new NotImplementedException(); }
public void CodeRay2d(ref Ray2d v) { AddValue(v.ToString()); }
protected override void BuildProcessing(MillingCommandGenerator generator) { var toolThickness = Tool.Thickness.Value; var profile = ProcessingArea[0].GetCurve(); if (Delta != 0) { profile = (Curve)profile.GetOffsetCurves(Delta)[0]; } var zMax = profile.GetStartEndPoints().Max(p => p.Y); generator.SetZSafety(ZSafety, zMax); var xMax = 0D; using (var curve = profile.ToCompositeCurve2d()) using (var ray = new Ray2d()) using (var intersector = new CurveCurveIntersector2d()) { var angleC = 360; var gCode = 2; for (var z = StartZ; z > 0; z -= StepZ) { var xMin = RadiusMin; for (int i = 0; i < 3; i++) { ray.Set(new Point2d(0, z + i * toolThickness / 2), Vector2d.XAxis); intersector.Set(curve, ray); if (intersector.NumberOfIntersectionPoints == 1) { xMin = Math.Max(xMin, intersector.GetIntersectionPoint(0).X); } } if (xMin == 0) { throw new Exception("Нет точек пересечения с профилем"); } var x = Math.Max(xMin, RadiusMax - Penetration); var s = x - xMin; int passCount = (int)Math.Ceiling(s / Penetration); var dx = s > Consts.Epsilon ? s / passCount : 1; if (generator.IsUpperTool) { generator.Move(0, -x - ZSafety, angleC: 0, angleA: 90); } else { generator.Transition(y: -x - ZSafety, feed: CuttingFeed); } generator.Transition(z: z); do { var arc = new Arc(new Point3d(0, 0, z), x, Math.PI * 1.5, Math.PI * 1.5 - Consts.Epsilon); generator.Cutting(0, -x, z, PenetrationFeed); generator.GCommand(CommandNames.Cutting, gCode, angleC: angleC, curve: arc, center: arc.Center.To2d(), feed: CuttingFeed); angleC = 360 - angleC; gCode = 5 - gCode; x -= dx; }while (x >= xMin - Consts.Epsilon); xMax = Math.Max(xMin, RadiusMax); } generator.Transition(y: -xMax - ZSafety, feed: PenetrationFeed); generator.Uplifting(); } }