Jypeli  9
The simple game programming library
LineSegment.cs
Siirry tämän tiedoston dokumentaatioon.
1 #region MIT License
2 /*
3  * Copyright (c) 2005-2008 Jonathan Mark Porter. http://physics2d.googlepages.com/
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17  * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  */
22 #endregion
23 
24 
25 
26 
27 #if UseDouble
28 using Scalar = System.Double;
29 #else
30 using Scalar = System.Single;
31 #endif
32 using System;
33 using System.Runtime.InteropServices;
34 using AdvanceMath.Design;
35 namespace AdvanceMath.Geometry2D
36 {
37  [StructLayout(LayoutKind.Sequential, Size = LineSegment.Size)]
38  [AdvBrowsableOrder("Vertex1,Vertex2")]
39 #if !CompactFramework && !WindowsCE && !PocketPC && !XBOX360 && !SILVERLIGHT && !WINDOWS_PHONE && !NETFX_CORE
40  [Serializable]
41  [System.ComponentModel.TypeConverter(typeof(AdvTypeConverter<LineSegment>))]
42 #endif
43  public struct LineSegment : IEquatable<LineSegment>
44  {
45  public const int Size = Vector2D.Size * 2;
46 
47  public static void Intersects(ref Vector2D v1, ref Vector2D v2, ref Vector2D v3, ref Vector2D v4, out bool result)
48  {
49  Scalar div, ua, ub;
50  div = 1 / ((v4.Y - v3.Y) * (v2.X - v1.X) - (v4.X - v3.X) * (v2.Y - v1.Y));
51  ua = ((v4.X - v3.X) * (v1.Y - v3.Y) - (v4.Y - v3.Y) * (v1.X - v3.X)) * div;
52  ub = ((v2.X - v1.X) * (v1.Y - v3.Y) - (v2.Y - v1.Y) * (v1.X - v3.X)) * div;
53  result = ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1;
54  }
55  public static bool Intersects(ref Vector2D v1, ref Vector2D v2, ref Vector2D v3, ref Vector2D v4, out Vector2D result)
56  {
57  Scalar div, ua, ub;
58  div = 1 / ((v4.Y - v3.Y) * (v2.X - v1.X) - (v4.X - v3.X) * (v2.Y - v1.Y));
59  ua = ((v4.X - v3.X) * (v1.Y - v3.Y) - (v4.Y - v3.Y) * (v1.X - v3.X)) * div;
60  ub = ((v2.X - v1.X) * (v1.Y - v3.Y) - (v2.Y - v1.Y) * (v1.X - v3.X)) * div;
61  if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1)
62  {
63  Vector2D.Lerp(ref v1, ref v2, ref ua, out result);
64  return true;
65  }
66  else
67  {
68  result = Vector2D.Zero;
69  return false;
70  }
71  }
72 
73 
74  public static void Intersects(ref Vector2D vertex1, ref Vector2D vertex2, ref Ray ray, out Scalar result)
75  {
76  Vector2D tanget, normal;
77  Scalar edgeMagnitude;
78  Vector2D.Subtract(ref vertex1, ref vertex2, out tanget);
79  Vector2D.Normalize(ref tanget, out edgeMagnitude, out tanget);
80  Vector2D.GetRightHandNormal(ref tanget, out normal);
81 
82  Scalar dir;
83  Vector2D.Dot(ref normal, ref ray.Direction, out dir);
84  if (Math.Abs(dir) >= MathHelper.Tolerance)
85  {
86  Vector2D originDiff;
87  Vector2D.Subtract(ref ray.Origin, ref vertex2, out originDiff);
88  Scalar actualDistance;
89  Vector2D.Dot(ref normal, ref originDiff, out actualDistance);
90  Scalar DistanceFromOrigin = -(actualDistance / dir);
91  if (DistanceFromOrigin >= 0)
92  {
93  Vector2D intersectPos;
94  Vector2D.Multiply(ref ray.Direction, ref DistanceFromOrigin, out intersectPos);
95  Vector2D.Add(ref intersectPos, ref originDiff, out intersectPos);
96 
97  Scalar distanceFromSecond;
98  Vector2D.Dot(ref intersectPos, ref tanget, out distanceFromSecond);
99 
100  if (distanceFromSecond >= 0 && distanceFromSecond <= edgeMagnitude)
101  {
102  result = DistanceFromOrigin;
103  return;
104  }
105  }
106  }
107  result = -1;
108  }
109 
110  public static void GetDistance(ref Vector2D vertex1, ref Vector2D vertex2, ref Vector2D point, out Scalar result)
111  {
112  Scalar edgeLength;
113  Vector2D edge, local;
114 
115  Vector2D.Subtract(ref point, ref vertex2, out local);
116  Vector2D.Subtract(ref vertex1, ref vertex2, out edge);
117  Vector2D.Normalize(ref edge, out edgeLength, out edge);
118 
119  Scalar nProj = local.Y * edge.X - local.X * edge.Y;
120  Scalar tProj = local.X * edge.X + local.Y * edge.Y;
121  if (tProj < 0)
122  {
123  result = MathHelper.Sqrt(tProj * tProj + nProj * nProj);
124  }
125  else if (tProj > edgeLength)
126  {
127  tProj -= edgeLength;
128  result = MathHelper.Sqrt(tProj * tProj + nProj * nProj);
129  }
130  else
131  {
132  result = Math.Abs(nProj);
133  }
134  }
135  public static void GetDistanceSq(ref Vector2D vertex1, ref Vector2D vertex2, ref Vector2D point, out Scalar result)
136  {
137  Scalar edgeLength;
138  Vector2D edge, local;
139 
140  Vector2D.Subtract(ref point, ref vertex2, out local);
141  Vector2D.Subtract(ref vertex1, ref vertex2, out edge);
142  Vector2D.Normalize(ref edge, out edgeLength, out edge);
143 
144  Scalar nProj = local.Y * edge.X - local.X * edge.Y;
145  Scalar tProj = local.X * edge.X + local.Y * edge.Y;
146  if (tProj < 0)
147  {
148  result = tProj * tProj + nProj * nProj;
149  }
150  else if (tProj > edgeLength)
151  {
152  tProj -= edgeLength;
153  result = tProj * tProj + nProj * nProj;
154  }
155  else
156  {
157  result = nProj * nProj;
158  }
159  }
160 
161  [AdvBrowsable]
163  [AdvBrowsable]
165 
166  [InstanceConstructor("Vertex1,Vertex2")]
167  public LineSegment(Vector2D vertex1, Vector2D vertex2)
168  {
169  this.Vertex1 = vertex1;
170  this.Vertex2 = vertex2;
171  }
172 
174  {
175  Scalar result;
176  GetDistance(ref point, out result);
177  return result;
178  }
179  public void GetDistance(ref Vector2D point, out Scalar result)
180  {
181  GetDistance(ref Vertex1, ref Vertex2, ref point, out result);
182  }
183 
184  public Scalar Intersects(Ray ray)
185  {
186  Scalar result;
187  Intersects(ref ray, out result);
188  return result;
189  }
190  public void Intersects(ref Ray ray, out Scalar result)
191  {
192  Intersects(ref Vertex1, ref Vertex2, ref ray, out result);
193  }
194 
195 
196 
197  public override string ToString()
198  {
199  return string.Format("V1: {0} V2: {1}", Vertex1, Vertex2);
200  }
201  public override int GetHashCode()
202  {
203  return Vertex1.GetHashCode() ^ Vertex2.GetHashCode();
204  }
205  public override bool Equals(object obj)
206  {
207  return obj is LineSegment && Equals((LineSegment)obj);
208  }
209  public bool Equals(LineSegment other)
210  {
211  return Equals(ref this, ref other);
212  }
213  public static bool Equals(LineSegment line1, LineSegment line2)
214  {
215  return Equals(ref line1, ref line2);
216  }
217  public static bool Equals(ref LineSegment line1, ref LineSegment line2)
218  {
219  return Vector2D.Equals(ref line1.Vertex1, ref line2.Vertex1) && Vector2D.Equals(ref line1.Vertex2, ref line2.Vertex2);
220  }
221 
222  public static bool operator ==(LineSegment line1, LineSegment line2)
223  {
224  return Equals(ref line1, ref line2);
225  }
226  public static bool operator !=(LineSegment line1, LineSegment line2)
227  {
228  return !Equals(ref line1, ref line2);
229  }
230  }
231 }
AdvanceMath.Geometry2D.LineSegment.operator!=
static bool operator!=(LineSegment line1, LineSegment line2)
Definition: LineSegment.cs:226
AdvanceMath.MathHelper.Sqrt
static Scalar Sqrt(Scalar d)
Definition: MathHelper.cs:314
AdvanceMath.Geometry2D.LineSegment.Intersects
static void Intersects(ref Vector2D vertex1, ref Vector2D vertex2, ref Ray ray, out Scalar result)
Definition: LineSegment.cs:74
AdvanceMath.Design.AdvTypeConverter
Definition: AdvTypeConverter'.cs:39
AdvanceMath.Geometry2D.LineSegment.GetDistance
Scalar GetDistance(Vector2D point)
Definition: LineSegment.cs:173
AdvanceMath.Geometry2D.LineSegment.Equals
static bool Equals(LineSegment line1, LineSegment line2)
Definition: LineSegment.cs:213
AdvanceMath.MathHelper.Tolerance
const Scalar Tolerance
Definition: MathHelper.cs:48
AdvanceMath.Vector2D.Subtract
static Vector2D Subtract(Vector2D left, Vector2D right)
Subtracts 2 Vector2Ds.
Definition: Vector2D.cs:306
AdvanceMath.Geometry2D.LineSegment.Size
const int Size
Definition: LineSegment.cs:45
AdvanceMath.Geometry2D.LineSegment.Intersects
void Intersects(ref Ray ray, out Scalar result)
Definition: LineSegment.cs:190
AdvanceMath.MathHelper
Definition: MathHelper.cs:38
AdvanceMath.Vector2D.Add
static Vector2D Add(Vector2D left, Vector2D right)
Adds 2 Vectors2Ds.
Definition: Vector2D.cs:287
AdvanceMath.Geometry2D.LineSegment.operator==
static bool operator==(LineSegment line1, LineSegment line2)
Definition: LineSegment.cs:222
AdvanceMath.Geometry2D.LineSegment.Intersects
static bool Intersects(ref Vector2D v1, ref Vector2D v2, ref Vector2D v3, ref Vector2D v4, out Vector2D result)
Definition: LineSegment.cs:55
AdvanceMath.Vector2D.Normalize
static Vector2D Normalize(Vector2D source)
This returns the Normalized Vector2D that is passed. This is also known as a Unit Vector.
Definition: Vector2D.cs:615
AdvanceMath.Geometry2D.LineSegment.Equals
bool Equals(LineSegment other)
Definition: LineSegment.cs:209
AdvanceMath.Vector2D.GetHashCode
override int GetHashCode()
Provides a unique hash code based on the member variables of this class. This should be done because ...
Definition: Vector2D.cs:1249
AdvanceMath.Geometry2D.LineSegment.Equals
static bool Equals(ref LineSegment line1, ref LineSegment line2)
Definition: LineSegment.cs:217
AdvanceMath.Vector2D.Zero
static readonly Vector2D Zero
Vector2D(0,0)
Definition: Vector2D.cs:69
AdvanceMath.Geometry2D
Definition: BoundingCircle.cs:36
AdvanceMath.Geometry2D.LineSegment.Equals
override bool Equals(object obj)
Definition: LineSegment.cs:205
AdvanceMath.Geometry2D.LineSegment.GetHashCode
override int GetHashCode()
Definition: LineSegment.cs:201
AdvanceMath.Geometry2D.LineSegment
Definition: LineSegment.cs:44
AdvanceMath.Vector2D.Multiply
static Vector2D Multiply(Vector2D source, Scalar scalar)
Does Scaler Multiplication on a Vector2D.
Definition: Vector2D.cs:413
AdvanceMath.Geometry2D.LineSegment.GetDistance
void GetDistance(ref Vector2D point, out Scalar result)
Definition: LineSegment.cs:179
AdvanceMath.Geometry2D.LineSegment.ToString
override string ToString()
Definition: LineSegment.cs:197
AdvanceMath.Geometry2D.LineSegment.Intersects
static void Intersects(ref Vector2D v1, ref Vector2D v2, ref Vector2D v3, ref Vector2D v4, out bool result)
Definition: LineSegment.cs:47
AdvanceMath.Vector2D.Dot
static Scalar Dot(Vector2D left, Vector2D right)
Does a Dot Operation Also know as an Inner Product.
Definition: Vector2D.cs:445
Scalar
System.Single Scalar
Definition: Clamped.cs:29
AdvanceMath.Geometry2D.LineSegment.Vertex1
Vector2D Vertex1
Definition: LineSegment.cs:162
AdvanceMath.Vector2D.Equals
override bool Equals(object obj)
Compares this Vector to another object. This should be done because the equality operators (==,...
Definition: Vector2D.cs:1259
AdvanceMath.Vector2D.GetRightHandNormal
static Vector2D GetRightHandNormal(Vector2D source)
Gets a Vector2D that is perpendicular(orthogonal) to the passed Vector2D while staying on the XY Plan...
Definition: Vector2D.cs:693
AdvanceMath.Geometry2D.Ray
Definition: Ray.cs:45
AdvanceMath.Geometry2D.LineSegment.GetDistanceSq
static void GetDistanceSq(ref Vector2D vertex1, ref Vector2D vertex2, ref Vector2D point, out Scalar result)
Definition: LineSegment.cs:135
AdvanceMath.Geometry2D.LineSegment.Vertex2
Vector2D Vertex2
Definition: LineSegment.cs:164
System
Definition: CFFauxAttributes.cs:29
AdvanceMath.Geometry2D.LineSegment.LineSegment
LineSegment(Vector2D vertex1, Vector2D vertex2)
Definition: LineSegment.cs:167
AdvanceMath.Geometry2D.LineSegment.GetDistance
static void GetDistance(ref Vector2D vertex1, ref Vector2D vertex2, ref Vector2D point, out Scalar result)
Definition: LineSegment.cs:110
AdvanceMath.Design
Definition: AdvBrowsableAttribute.cs:29
AdvanceMath.Vector2D.Size
const int Size
The Size of the class in bytes;
Definition: Vector2D.cs:59
AdvanceMath.Vector2D
This is the Vector Class.
Definition: Vector2D.cs:50
AdvanceMath.Geometry2D.LineSegment.Intersects
Scalar Intersects(Ray ray)
Definition: LineSegment.cs:184
AdvanceMath.Vector2D.Y
Scalar Y
This is the Y value. (Usually represents a vertical position or direction.)
Definition: Vector2D.cs:805
AdvanceMath
Definition: Clamped.cs:36
AdvanceMath.Vector2D.Lerp
static Vector2D Lerp(Vector2D left, Vector2D right, Scalar amount)
Definition: Vector2D.cs:141