private void add_Trama_ifs_i(string SPName, LineI lineI) { try { // Agregamos los parámetros this.addInParameter("@ORIGEN", lineI.origen); this.addInParameter("@LINE_TYPE", lineI.line_type); this.addInParameter("@INVOICE_NO", lineI.invoice_no); this.addInParameter("@ITEM_ID", lineI.item_id); this.addInParameter("@VAT_CODE", lineI.vat_code); this.addInParameter("@NET_CURR_AMOUNT", lineI.net_curr_amount); this.addInParameter("@NUMBER_REFERENCE", lineI.number_reference); this.addInParameter("@MAN_TAX_LIABILITY_DATE", lineI.man_tax_liability_date); this.addInParameter("@BRANCH", lineI.branch); this.addInParameter("@INVOICE_TYPE", lineI.invoice_type); this.addInParameter("@NET_DOM_AMOUNT", lineI.net_dom_amount); this.addInParameter("@VAT_CURR_AMOUNT", lineI.vat_curr_amount); this.addInParameter("@VAT_DOM_AMOUNT", lineI.vat_dom_amount); this.addInParameter("@REFERENCE", lineI.reference); this.addInParameter("@DELIV_TYPE_ID", lineI.deliv_type_id); this.addInParameter("@SERIES_REFERENCE", lineI.series_reference); // Ejecutamos el método this.executeSPWithoutResults(SPName); } catch (Exception ex) { throw ex; } }
private void BuildRoad(GridPoint a, GridPoint b) { List <GridPoint> path = new List <GridPoint>(50); path.Add(a); path.AddRange(GameGen.GridPlacement.ConnectPoints(a, b)); //List<GridPoint> path = GameGen.GridPlacement.ConnectPoints(a, b); //path[path.Count - 1].ChunkRoad = new ChunkRoad(ChunkRoad.RoadType.Paved); GameGen.GridPlacement.GridPoints[path[path.Count - 1].GridPos.x, path[path.Count - 1].GridPos.z].ChunkRoad = new ChunkRoad(path[path.Count - 1].ChunkPos, ChunkRoad.RoadType.Paved); for (int i = 0; i < path.Count - 1; i++) { path[i].ChunkRoad = new ChunkRoad(path[i].ChunkPos, ChunkRoad.RoadType.Paved); GameGen.GridPlacement.GridPoints[path[i].GridPos.x, path[i].GridPos.z].ChunkRoad = new ChunkRoad(path[i].ChunkPos, ChunkRoad.RoadType.Paved); Vec2i v1 = path[i].ChunkPos; Vec2i v2 = path[i + 1].ChunkPos; LineI li = new LineI(v1, v2); foreach (Vec2i v in li.ConnectPoints()) { if (GameGen.TerGen.ChunkBases[v.x, v.z].ChunkFeature is ChunkRiverNode) { GameGen.TerGen.ChunkBases[v.x, v.z].SetChunkFeature(new ChunkRiverBridge(v)); } GameGen.TerGen.ChunkBases[v.x, v.z].SetChunkFeature(new ChunkRoad(v, ChunkRoad.RoadType.Paved)); } } }
public IFSRegister MapLineIToIFSFile(LineI lineI) { try{ return(new IFSRegister() { sorterA = int.Parse(lineI.origen), sorterB = lineI.invoice_no, columns = new string[] { lineI.line_type, lineI.invoice_no, lineI.item_id, lineI.vat_code, String.Format("{0:0.00}", double.Parse(lineI.net_curr_amount)), lineI.net_dom_amount, String.Format("{0:0.00}", double.Parse(lineI.vat_curr_amount)), lineI.vat_dom_amount, lineI.reference, lineI.deliv_type_id, lineI.series_reference, lineI.number_reference, lineI.man_tax_liability_date /*, * lineI.branch, * lineI.invoice_type*/// ← Ocultado porque son parámetros que están de más } }); } catch (Exception ex) { this._ILogService.Error(ex.Message); } return(null); }
public void LocateCollinearReverse() { LineD reverseDiagD = diagD.Reverse(); Assert.AreEqual(LineLocation.End, reverseDiagD.LocateCollinear(new PointD(0, 0))); Assert.AreEqual(LineLocation.Start, reverseDiagD.LocateCollinear(new PointD(2, 2))); Assert.AreEqual(LineLocation.After, reverseDiagD.LocateCollinear(new PointD(-1, -1))); Assert.AreEqual(LineLocation.Between, reverseDiagD.LocateCollinear(new PointD(1, 1))); Assert.AreEqual(LineLocation.Before, reverseDiagD.LocateCollinear(new PointD(3, 3))); Assert.AreEqual(LineLocation.Between, reverseDiagD.LocateCollinear(new PointD(0, 1))); Assert.AreEqual(LineLocation.Between, reverseDiagD.LocateCollinear(new PointD(1, 0))); LineF reverseDiagF = diagF.Reverse(); Assert.AreEqual(LineLocation.End, reverseDiagF.LocateCollinear(new PointF(0, 0))); Assert.AreEqual(LineLocation.Start, reverseDiagF.LocateCollinear(new PointF(2, 2))); Assert.AreEqual(LineLocation.After, reverseDiagF.LocateCollinear(new PointF(-1, -1))); Assert.AreEqual(LineLocation.Between, reverseDiagF.LocateCollinear(new PointF(1, 1))); Assert.AreEqual(LineLocation.Before, reverseDiagF.LocateCollinear(new PointF(3, 3))); Assert.AreEqual(LineLocation.Between, reverseDiagF.LocateCollinear(new PointF(0, 1))); Assert.AreEqual(LineLocation.Between, reverseDiagF.LocateCollinear(new PointF(1, 0))); LineI reverseDiagI = diagI.Reverse(); Assert.AreEqual(LineLocation.End, reverseDiagI.LocateCollinear(new PointI(0, 0))); Assert.AreEqual(LineLocation.Start, reverseDiagI.LocateCollinear(new PointI(2, 2))); Assert.AreEqual(LineLocation.After, reverseDiagI.LocateCollinear(new PointI(-1, -1))); Assert.AreEqual(LineLocation.Between, reverseDiagI.LocateCollinear(new PointI(1, 1))); Assert.AreEqual(LineLocation.Before, reverseDiagI.LocateCollinear(new PointI(3, 3))); Assert.AreEqual(LineLocation.Between, reverseDiagI.LocateCollinear(new PointI(0, 1))); Assert.AreEqual(LineLocation.Between, reverseDiagI.LocateCollinear(new PointI(1, 0))); }
/// <summary> /// Places a roof over the specified building. /// The roof will only cover the tile specified by 'roofTileID'. If this is null, /// then a roof over the total building will be created /// </summary> /// <param name="vox"></param> /// <param name="build"></param> /// <param name="roofTileID"></param> public static void AddRoof(GenerationRandom genRan, BuildingVoxels vox, Building build, Voxel roofVox, int roofStartY = 5, Tile roofTileReplace = null) { if (roofTileReplace == null) { Vec2i dir = genRan.RandomQuadDirection(); dir.x = Mathf.Abs(dir.x); dir.z = Mathf.Abs(dir.z); Vec2i start = new Vec2i(build.Width / 2 * dir.x, build.Height / 2 * dir.z); Vec2i end = start + new Vec2i(dir.z * build.Width, dir.x * build.Height); LineI t = new LineI(start, end); float maxDist = Mathf.Max(t.Distance(new Vec2i(0, 0)), t.Distance(new Vec2i(build.Width - 1, 0)), t.Distance(new Vec2i(0, build.Height - 1)), t.Distance(new Vec2i(build.Width - 1, build.Height - 1))); int maxHeight = genRan.RandomInt(4, 6); float scale = maxHeight / (maxDist + 1); //float scale = 0.7f; for (int x = 0; x < build.Width; x++) { for (int z = 0; z < build.Height; z++) { int height = (int)Mathf.Clamp((maxDist - t.Distance(new Vec2i(x, z)) + 1) * scale, 1, World.ChunkHeight - 1); for (int y = 0; y < height; y++) { vox.AddVoxel(x, Mathf.Clamp(roofStartY + y, 0, World.ChunkHeight - 1), z, roofVox); } } } } }
/// <summary> /// 计算点P到线L垂足 /// </summary> /// <param name="P">线P</param> /// <param name="L">点L</param> /// <returns>返回垂足点</returns> public static PointD Perpendicular(PointI P, LineI L) { Double r = PerpendicularPosition(P, L); PointD result = new PointD(); result.X = L.Starting.X + r * (L.End.X - L.Starting.X); result.Y = L.Starting.Y + r * (L.End.Y - L.Starting.Y); return(result); }
private void GenerateRiver(Vec2i start) { Vec2i end = null; for (int i = 1; i < 100; i++) { if (end != null) { break; } for (int j = 0; j < DIRS.Length; j++) { Vec2i pos = start + DIRS[j] * i; if (GameGenerator2.InBounds(pos)) { if (GameGen.TerGen.ChunkBases[pos.x, pos.z].Biome == ChunkBiome.ocean) { end = pos; break; } } } } if (end == null) { return; } LineI li = new LineI(start, end); List <Vec2i> basic = li.ConnectPoints(); float val1 = GenRan.Random(0.1f, 0.001f); float val2 = GenRan.Random(0.1f, 0.001f); int val3 = GenRan.RandomInt(8, 32); int val4 = GenRan.RandomInt(8, 32); for (int i = 0; i < basic.Count; i++) { basic[i] += new Vec2i((int)(val3 * Mathf.Sin(i * val1)), (int)(val4 * Mathf.Sin(i * val2))); } for (int i = 0; i < basic.Count - 1; i++) { Vec2i v1 = basic[i]; Vec2i v2 = basic[i + 1]; LineI i2 = new LineI(v1, v2); foreach (Vec2i v in i2.ConnectPoints()) { GameGen.TerGen.ChunkBases[v.x, v.z].SetChunkFeature(new ChunkRiverNode(v)); } } return; }
protected void updateLines() { LineN.Clear(); LineM.Clear(); LineI.Clear(); for (double i = 0.1; i <= 1.2; i += 0.1) { LineN.Add(new KeyValuePair <double, double>(CalculateM(i) * CalculateN(i), CalculateN(i))); LineM.Add(new KeyValuePair <double, double>(CalculateM(i) * CalculateN(i), CalculateM(i))); LineI.Add(new KeyValuePair <double, double>(CalculateM(i) * CalculateN(i), i)); } }
/// <summary> /// 获取线段L与圆C的交点集合 /// </summary> /// <param name="L">线段L</param> /// <param name="C">圆C</param> /// <returns>返回交点集合.</returns> public static PointD[] Intersection(LineI L, CircleI C) { List <PointD> result = new List <PointD>(); Int32? has = HasIntersection(L, C); if (has == 0 || has == null) { return(result.ToArray()); } //Points P (x,y) on a line defined by two points P1 (x1,y1,z1) and P2 (x2,y2,z2) is described by //P = P1 + u (P2 - P1) //or in each coordinate //x = x1 + u (x2 - x1) //y = y1 + u (y2 - y1) //z = z1 + u (z2 - z1) //A sphere centered at P3 (x3,y3,z3) with radius r is described by //(x - x3)2 + (y - y3)2 + (z - z3)2 = r2 //Substituting the equation of the line into the sphere gives a quadratic equation of the form //a u2 + b u + c = 0 //where: //a = (x2 - x1)2 + (y2 - y1)2 + (z2 - z1)2 //b = 2[ (x2 - x1) (x1 - x3) + (y2 - y1) (y1 - y3) + (z2 - z1) (z1 - z3) ] //c = x32 + y32 + z32 + x12 + y12 + z12 - 2[x3 x1 + y3 y1 + z3 z1] - r2 //The solutions to this quadratic are described by PointD PD = PointAlgorithm.Substract(L.Starting, L.End); Double a = PD.X * PD.X + PD.Y * PD.Y; Double b = 2 * ((L.End.X - L.Starting.X) * (L.Starting.X - C.Center.X) + (L.End.Y - L.Starting.Y) * (L.Starting.Y - C.Center.Y)); Double c = C.Center.X * C.Center.X + C.Center.Y * C.Center.Y + L.Starting.X * L.Starting.X + L.Starting.Y * L.Starting.Y - 2 * (C.Center.X * L.Starting.X + C.Center.Y * L.Starting.Y) - C.Radius * C.Radius; Double u1 = ((-1) * b + System.Math.Sqrt(b * b - 4 * a * c)) / (2 * a); Double u2 = ((-1) * b - System.Math.Sqrt(b * b - 4 * a * c)) / (2 * a); //交点 PointD P1 = new PointD(L.Starting.X + u1 * (L.End.X - L.Starting.X), L.Starting.Y + u1 * (L.End.Y - L.Starting.Y)); PointD P2 = new PointD(L.Starting.X + u2 * (L.End.X - L.Starting.X), L.Starting.Y + u2 * (L.End.Y - L.Starting.Y)); if (LineAlgorithm.OnLine(L, P1) == true) { result.Add(P1); } if (LineAlgorithm.OnLine(L, P2) == true && P1.Equals(P2) == false) { result.Add(P2); } return(result.ToArray()); }
/// <summary> /// Draws movement arrows on the specified <see cref="MapView"/>, connecting the specified /// units with the specified target location.</summary> /// <param name="mapView"> /// The <see cref="MapView"/> to draw on.</param> /// <param name="units"> /// An <see cref="IList{T}"/> containing the moving <see cref="Unit"/> objects.</param> /// <param name="target"> /// The coordinates of the <see cref="Site"/> that is the target of the move.</param> /// <param name="checkRegion"> /// <c>true</c> to only draw arrows if <paramref name="target"/> lies within the <see /// cref="MapView.SelectedRegion"/> of the specified <paramref name="mapView"/>; otherwise, /// <c>false</c>.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="mapView"/> or <paramref name="units"/> is a null reference.</exception> /// <remarks><para> /// <b>DrawMoveArrows</b> adds a sequence of arrows from the <see cref="Entity.Site"/> of /// the first element in the specified <paramref name="units"/> collection to the specified /// <paramref name="target"/> site, following the path returned by <see /// cref="Finder.FindMovePath"/>. /// </para><para> /// <b>DrawMoveArrows</b> always clears the <see cref="MapView.MoveArrows"/> collection of /// the specified <paramref name="mapView"/>, even if no elements are added for whatever /// reason.</para></remarks> public static void DrawMoveArrows(MapView mapView, IList <Entity> units, PointI target, bool checkRegion) { if (mapView == null) { ThrowHelper.ThrowArgumentNullException("mapView"); } if (units == null) { ThrowHelper.ThrowArgumentNullException("units"); } // check that we have any units mapView.MoveArrows.Clear(); if (units.Count == 0) { goto showArrows; } // check that source & target are different Site sourceSite = units[0].Site; if (sourceSite.Location == target) { goto showArrows; } // check that target is valid, if desired if (checkRegion && !mapView.InSelectedRegion(target)) { goto showArrows; } // find exact path we're going to take WorldState world = mapView.WorldState; Site targetSite = world.GetSite(target); var path = Finder.FindMovePath(world, units, sourceSite, targetSite, false); // draw arrows for steps along path, if any if (path != null) { IList <PointI> sites = path.Nodes; for (int i = 0; i < sites.Count - 1; i++) { LineI line = new LineI(sites[i], sites[i + 1]); mapView.MoveArrows.Add(line); } } showArrows: mapView.ShowArrows(); }
/// <summary> /// 判断折线的偏转方向/线段拐向 /// </summary> /// <param name="L">L线段</param> /// <param name="R">R点</param> /// <returns>返回偏转方向</returns> /// <remarks> /// 假设L线的是 P->Q PQ为线的2个顶点 /// 返回值 大于 0 , 则PQ在R点拐向右侧后得到QR,等同于点R在PQ线段的右侧 /// 返回值 小于 0 , 则PQ在R点拐向左侧后得到QR,等同于点R在PQ线段的左侧 /// 返回值 等于 0 , 则P,Q,R三点共线。 /// </remarks> public static Int32 Position(LineI L, PointI R) { //formular //折线段的拐向判断方法可以直接由矢量叉积的性质推出。对于有公共端点的线段PQ和QR,通过计算(R - P) * (Q - P)的符号便可以确定折线段的拐向 //基本算法是(R-P)计算相对于P点的R点坐标,(Q-P)计算相对于P点的Q点坐标。 //(R-P) * (Q-P)的计算结果是计算以P为相对原点,点R与点Q的顺时针,逆时针方向。 //PointI P = L.Starting; //PointI Q = L.End; //PointI RP = PointAlgorithm.Substract(R, P);//R-P //PointI QP = PointAlgorithm.Substract(Q, P);//Q-P //return PointAlgorithm.Multiple(RP, QP); return(PointAlgorithm.Multiple(L.Starting, L.End, R)); }
/// <summary> /// 点P是否在多边形区域内 /// </summary> /// <param name="PG">多边形PL</param> /// <param name="P">点P</param> /// <returns>如果点P在区域内返回True,否则返回False.</returns> /// <remarks>此处不考虑平行边的情况</remarks> public static Boolean InPolygon(PolygonI PG, PointI P) { //count ← 0; //以P为端点,作从右向左的射线L; //for 多边形的每条边s // do if P在边s上 // then return true; // if s不是水平的 // then if s的一个端点在L上 // if 该端点是s两端点中纵坐标较大的端点 // then count ← count+1 // else if s和L相交 // then count ← count+1; //if count mod 2 = 1 // then return true; //else return false; Int32 count = 0; LineI L = new LineI(P, new PointI(Int32.MaxValue, P.Y)); foreach (LineI S in PG) { if (LineAlgorithm.OnLine(S, P) == true) { return(true); } if (LineAlgorithm.Gradient(S) != 0)//不是水平线段 { if (LineAlgorithm.OnLine(L, S.Starting) || LineAlgorithm.OnLine(L, S.End)) { if (LineAlgorithm.OnLine(L, S.Starting) && S.Starting.Y > S.End.Y) { ++count; } if (LineAlgorithm.OnLine(L, S.End) && S.End.Y > S.Starting.Y) { ++count; } } else if (LineAlgorithm.HasIntersection(S, L) > 0) { ++count; } } } //如果X的水平射线和多边形的交点数是奇数个则点在多边形内,否则不在区域内。 if (count % 2 == 0) { return(false); } return(true); }
/// <summary> /// 计算点P到线L的最近点,该点在线上。不一定是垂足,应为垂足不一定在线上。 /// </summary> /// <param name="P">点P</param> /// <param name="L">线L</param> /// <returns>返回最近点</returns> public static PointD ClosestPoint(PointI P, LineI L) { Double r = PerpendicularPosition(P, L); if (r < 0)//最近点是起点 { return(L.Starting); } if (r > 1)//最近点是终点 { return(L.End); } return(Perpendicular(P, L)); }
/// <summary> /// 判断线段L是否在圆内 /// </summary> /// <param name="C">圆C</param> /// <param name="L">线段L</param> /// <returns>如果在圆内返回True,否则返回False。</returns> public static Boolean InCircle(CircleI C, LineI L) { //判断点是否在圆内: //计算圆心到该点的距离,如果小于等于半径则该点在圆内。 if (PointAlgorithm.Distance(L.Starting, C.Center) > C.Radius) { return(false); } if (PointAlgorithm.Distance(L.End, C.Center) > C.Radius) { return(false); } return(true); }
/// <summary> /// 判断L1与L2是否相交 /// </summary> /// <param name="L1">线段L1</param> /// <param name="L2">线段L2</param> /// <returns>线段相交返回交点数目,否则返回0,如果有无数个交点则返回null.</returns> public static Int32?HasIntersection(LineI L1, LineI L2) { //如果两线段相交,则两线段必然相互跨立对方。 //若P1P2跨立Q1Q2 ,则矢量 ( P1 - Q1 ) 和( P2 - Q1 )位于矢量( Q2 - Q1 ) 的两侧, //即( P1 - Q1 ) × ( Q2 - Q1 ) * ( P2 - Q1 ) × ( Q2 - Q1 ) < 0。 //上式可改写成( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) > 0。当 ( P1 - Q1 ) × ( Q2 - Q1 ) = 0 时, //说明 ( P1 - Q1 ) 和 ( Q2 - Q1 )共线,但是因为已经通过快速排斥试验,所以 P1 一定在线段 Q1Q2上;同理,( Q2 - Q1 ) ×(P2 - Q1 ) = 0 说明 P2 一定在线段 Q1Q2上。 //所以判断P1P2跨立Q1Q2的依据是:( P1 - Q1 ) × ( Q2 - Q1 ) * ( P2 - Q1 ) × ( Q2 - Q1 ) <= 0。 //同理判断Q1Q2跨立P1P2的依据是:( Q1 - P1 ) × ( P2 - P1 ) * ( Q2 - P1 ) × ( P2 - P1 ) <= 0。 if ((Position(L1, L2.Starting, L2.End) == 0) && (Position(L2, L1.Starting, L1.End) == 0)) //两线四点 共线 { List <PointI> Points = new List <PointI>(); //排除点和线顶点相交的情况 if (true == OnLine(L1, L2.Starting)) { Points.Add(L2.Starting); } if (true == OnLine(L1, L2.End)) { Points.Add(L2.End); } if (true == OnLine(L2, L1.Starting)) { Points.Add(L1.Starting); } if (true == OnLine(L2, L1.End)) { Points.Add(L1.End); } if (Points.Count == 2) { if (Points[0].Equals(Points[1])) { return(1); } return(null); } else if (Points.Count > 2) { return(null); } return(0); } if ((Position(L1, L2.Starting, L2.End) <= 0) && (Position(L2, L1.Starting, L1.End) <= 0)) { return(1); } return(0); }
/// <summary> /// 判断点是否在线上 /// </summary> /// <param name="L">线L</param> /// <param name="P">点P</param> /// <returns>返回True表示在线段上,否则返回False。</returns> public static Boolean OnLine(LineI L, PointI P) { //先判断点P是否和线L共线 if (Position(L, P) == 0) { MinMax <Int32> MX = new MinMax <Int32>(L.Starting.X, L.End.X); MinMax <Int32> MY = new MinMax <Int32>(L.Starting.Y, L.End.Y); //特别要注意的是,由于需要考虑水平线段和垂直线段两种特殊情况,min(xi,xj)<=xk<=max(xi,xj)和min(yi,yj)<=yk<=max(yi,yj)两个条件必须同时满足才能返回真值。 if (((MX.Min <= P.X) && (P.X <= MX.Max)) && ((MY.Min <= P.Y) && (P.Y <= MY.Max))) { return(true); } } return(false); }
/// <summary> /// Draws attack arrows on the specified <see cref="MapView"/>, connecting the specified /// units with the specified target location.</summary> /// <param name="mapView"> /// The <see cref="MapView"/> to draw on.</param> /// <param name="units"> /// An <see cref="IList{T}"/> containing the attacking <see cref="Unit"/> objects.</param> /// <param name="target"> /// The coordinates of the <see cref="Site"/> that is the target of the attack.</param> /// <param name="checkRegion"> /// <c>true</c> to only draw arrows if <paramref name="target"/> lies within the <see /// cref="MapView.SelectedRegion"/> of the specified <paramref name="mapView"/>; /// otherwise, <c>false</c>.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="mapView"/> or <paramref name="units"/> is a null reference.</exception> /// <remarks><para> /// <b>DrawAttackArrows</b> adds one arrow from each unique <see cref="Entity.Site"/> in the /// specified <paramref name="units"/> collection to the specified <paramref name="target"/> /// site. /// </para><para> /// <b>DrawAttackArrows</b> always clears the <see cref="MapView.AttackArrows"/> collection /// of the specified <paramref name="mapView"/>, even if no elements are added for whatever /// reason.</para></remarks> public static void DrawAttackArrows(MapView mapView, IList <Entity> units, PointI target, bool checkRegion) { if (mapView == null) { ThrowHelper.ThrowArgumentNullException("mapView"); } if (units == null) { ThrowHelper.ThrowArgumentNullException("units"); } // check that we have any units mapView.AttackArrows.Clear(); if (units.Count == 0) { goto showArrows; } // check that target is valid, if desired if (checkRegion && !mapView.InSelectedRegion(target)) { goto showArrows; } // draw arrows from selected units to target for (int i = 0; i < units.Count; i++) { Entity unit = units[i]; if (unit.Site == null) { continue; } // draw one arrow per unit site LineI line = new LineI(unit.Site.Location, target); if (line.Start != line.End && !mapView.AttackArrows.Contains(line)) { mapView.AttackArrows.Add(line); } } showArrows: mapView.ShowArrows(); }
/// <summary> /// 计算点P到线段L所在直线的距离 /// </summary> /// <param name="P">点P</param> /// <param name="L">线段L</param> /// <returns>返回距离</returns> public static Double Distance(PointI P, LineI L) { //formula //d=abs(a*x0+b*y0+c)/sqrt(a*a+b*b) //|(x3-x2)*(y1-y2)-(y3-y2)*(x1-x2)| //((x3-x2)(x3-x2)+(y3-y2)*(y3-y2)) //if (p2.x == p3.x) // return abs(p1.y - p2.y); //if (p2.y == p3.y) // return abs(p1.x - p2.x); //return abs(a * p1.x + b * p1.y + c) / sqrt(a * a + b * b); //这里:a=(p3.y-p2.y),b=(p2.x-p3.x),c=p3.x*p2.y-p2.x*p3.x //return (Double)((L.End.X - L.Starting.X) * (P.Y - L.Starting.Y) - (L.End.Y - L.Starting.Y) * (P.X - L.Starting.X)) // / System.Math.Sqrt((L.End.X - L.Starting.X) * (L.End.X - L.Starting.X) + (L.End.Y - L.Starting.Y) * (L.End.Y - L.Starting.Y)); return(System.Math.Abs(Multiple(L.Starting, L.End, P)) / Distance(L.Starting, L.End)); }
public OperationResult saveLineI(LineI lineI) { /* * Author Billy Arredondo * Create date 02-feb-2017 * Modify date 02-feb-2017 * Function Ingresar a la tabla TRAMA_IFS_I un sólo registro. * El registro está modelado por LineH */ try { this.add_Trama_ifs_i("[ifsDocsMost].[add_Trama_ifs_i]", lineI); return(new OperationResult()); } catch (Exception ex) { _iLogService.Error(ex.Message); return(null); } }
/// <summary> /// 判断线段与矩形的交点个数 /// </summary> /// <param name="L">线段L</param> /// <param name="R">线段R</param> /// <returns>相交返回交点数目,否则返回0,如果有无数个交点则返回null</returns> public static Int32?HasIntersection(LineI L, RectangleI R) { Int32 count = 0; foreach (LineI S in R) { Int32?result = HasIntersection(L, S); if (result == null) { return(null); } count += (Int32)result; } foreach (PointI P in R.GetVertexs()) { if (OnLine(L, P) == true) { count--; } } return(count); }
/// <summary> /// 判断折线PL与线段L的交点个数 /// </summary> /// <param name="L">线段L</param> /// <param name="PL">折线PL</param> /// <returns>相交返回交点数目,否则返回0</returns> public static Int32?HasIntersection(LineI L, PolylineI PL) { Int32 count = 0; foreach (LineI S in PL) { Int32?result = HasIntersection(L, S); if (result == null) { return(null); } count += (Int32)result; } for (Int32 i = 1; i < PL.Points.Count - 1; ++i)//排除折线的开始和结束顶点 { if (OnLine(L, PL.Points[i]) == true) { count--; } } return(count); }
/// <summary> /// 判断多边形PG与线段L的交点个数 /// </summary> /// <param name="L">线段L</param> /// <param name="PG">多边形PG</param> /// <returns>相交返回交点数目,否则返回0</returns> public static Int32?HasIntersection(LineI L, PolygonI PG) { Int32 count = 0; foreach (LineI S in PG) { Int32?result = HasIntersection(L, S); if (result == null) { return(null); } count += (Int32)result; } foreach (PointI P in PG.Vertex) { if (OnLine(L, P) == true) { count--; } } return(count); }
/// <summary> /// 计算点P在线L的垂足位置 /// </summary> /// <param name="P">点P</param> /// <param name="L">线L</param> /// <returns>返回垂足位置</returns> /// <remarks> /// 返回值 等于0 垂足=L.End /// 返回值 等于1 垂足=L.Starting /// 返回值 小于0 垂足在线L的反向延长线上 /// 返回值 大于1 垂足在线L的正向延长线上 /// 返回值 (0,1) 垂足在线L上 /// </remarks> public static Double PerpendicularPosition(PointI P, LineI L) { /* 判断点与线段的关系,用途很广泛 * 本函数是根据下面的公式写的,P是点C到线段AB所在直线的垂足 * * AC dot AB * r = --------- ||AB||^2 * (Cx-Ax)(Bx-Ax) + (Cy-Ay)(By-Ay) * = ------------------------------- * L^2 * * r has the following meaning: * * r=0 P = A * r=1 P = B * r<0 P is on the backward extension of AB * r>1 P is on the forward extension of AB * 0<r<1 P is interior to AB */ return(DotMultiple(L.Starting, L.End, P) / (Distance(L.End, L.Starting) * Distance(L.End, L.Starting))); }
/// <summary> /// 获取线段L与多边形PG的交点集合 /// </summary> /// <param name="L">线段L</param> /// <param name="PG">多边形PG</param> /// <returns>返回交点集合,如果有无数个交点则返回null.</returns> public static PointD[] Intersection(LineI L, PolygonI PG) { List <PointD> result = new List <PointD>(); foreach (LineI S in PG) { PointD[] P = Intersection(L, S); if (P == null) { return(null); } if (P.Length == 0) { continue; } if (result.Contains(P[0]) == false) { result.Add((PointD)P[0]); } } return(result.ToArray()); }
/// <summary> /// 判断线段L与圆C的交点个数 /// </summary> /// <param name="L">线段L</param> /// <param name="C">圆形C</param> /// <returns>相交返回交点数目,否则返回0</returns> public static Int32?HasIntersection(LineI L, CircleI C) { Int32 count = 0; //如果和圆C有交点首先是L到圆心的距离小于或等于C的半径 if (DoubleAlgorithm.Equals(PointAlgorithm.ClosestDistance(C.Center, L), C.Radius)) { return(1); } else if (PointAlgorithm.ClosestDistance(C.Center, L) > C.Radius) { return(0); } if (PointAlgorithm.Distance(C.Center, L.Starting) >= C.Radius) { ++count; } if (PointAlgorithm.Distance(C.Center, L.End) >= C.Radius) { ++count; } return(count); }
public bool Intersects(LineI l2) { return(doIntersect(Start, End, l2.Start, l2.End)); }
/// <summary> /// 计算点P到线L的最近距离 /// </summary> /// <param name="P">点P</param> /// <param name="L">线L</param> /// <returns>返回最近距离</returns> public static Double ClosestDistance(PointI P, LineI L) { return(Distance(ClosestPoint(P, L), (PointD)P)); }
/// <summary> /// 线是否在区域内 /// </summary> /// <param name="Rect">矩形区域</param> /// <param name="L">线L</param> /// <returns> /// 返回True表示线L在区域内,返回False则不在区域内. /// </returns> public static Boolean InRectangle(RectangleI Rect, LineI L) { return(InRectangle(Rect, L.Starting) && InRectangle(Rect, L.End)); }
/// <summary> /// 线段L是否在多边形区域内 /// </summary> /// <param name="PG">多边形PG</param> /// <param name="L">线段L</param> /// <returns>如果线段L在区域内返回True,否则返回False.</returns> public static Boolean InPolygon(PolygonI PG, LineI L) { //if 线端PQ的端点不都在多边形内 // then return false; //点集pointSet初始化为空; //for 多边形的每条边s // do if 线段的某个端点在s上 // then 将该端点加入pointSet; // else if s的某个端点在线段PQ上 // then 将该端点加入pointSet; // else if s和线段PQ相交 // 这时候已经可以肯定是内交了 // then return false; //将pointSet中的点按照X-Y坐标排序; //for pointSet中每两个相邻点 pointSet[i] , pointSet[ i+1] // do if pointSet[i] , pointSet[ i+1] 的中点不在多边形中 // then return false; //return true; List <PointI> PointList = new List <PointI>(); if (InPolygon(PG, L.Starting) == false) { return(false); } foreach (LineI S in PG) { if (LineAlgorithm.OnLine(S, L.Starting) == true) { PointList.Add(L.Starting); } else if (LineAlgorithm.OnLine(S, L.End) == true) { PointList.Add(L.End); } else if (LineAlgorithm.OnLine(L, S.Starting) == true) { PointList.Add(S.Starting); } else if (LineAlgorithm.OnLine(L, S.End) == true) { PointList.Add(S.End); } else if (LineAlgorithm.HasIntersection(L, S) > 0) { return(false); } } PointI[] OrderedPointList = PointList.ToArray(); for (Int32 i = 0; i < (OrderedPointList.Length - 1); ++i) { for (Int32 j = 0; j < (OrderedPointList.Length - i - 1); j++) { MinMax <PointI> MM = new MinMax <PointI>(OrderedPointList[j], OrderedPointList[j + 1]); OrderedPointList[j] = MM.Min; OrderedPointList[j + 1] = MM.Max; } } for (Int32 i = 0; i < (OrderedPointList.Length - 1); ++i) { if (false == InPolygon(PG, PointAlgorithm.MidPoint(OrderedPointList[i], OrderedPointList[i + 1]))) { return(false); } } return(true); }
/// <summary> /// 计算线L到圆C的距离 /// </summary> /// <param name="C">圆C</param> /// <param name="L">线L</param> /// <returns>返回线到圆周的距离。</returns> /// <remarks> /// 返回值小于0 表示线在圆内或与圆周相交。 /// 返回值等于0 表示线在圆周上与圆周相切。 /// 返回值大于0 表示线在圆外与圆周没有交点。 /// </remarks> public static Double Distance(CircleI C, LineI L) { return(PointAlgorithm.Distance(C.Center, L) - C.Radius); }