Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1441 chris 1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Threading.Tasks;
6
 
7
namespace BauzoidNET.math
8
{
9
    /** Line segment class. */
10
    public class Line2
11
    {
12
 
13
            // Constants========================================================================================
14
 
15
            // Embedded Types===================================================================================
16
 
17
            // Fields===========================================================================================
18
 
19
            public Vector2 a = new Vector2();
20
            public Vector2 b = new Vector2();
21
 
22
            // parametric form
23
            private float A = 0.0f;
24
            private float B = 0.0f;
25
            private float C = 0.0f;
26
 
27
            private Vector2 mTemp = new Vector2();
28
            private Vector2 mTemp2 = new Vector2();
29
 
30
            // Methods==========================================================================================
31
 
32
            public Line2()
33
            {
34
                    calcParametric();
35
            }
36
 
37
            public Line2(float ax, float ay, float bx, float by)
38
            {
39
                    set(ax, ay, bx, by);
40
            }
41
 
42
            public Line2(Vector2 a, Vector2 b)
43
            {
44
                    set(a, b);
45
            }
46
 
47
            public void set(float _ax, float _ay, float _bx, float _by)
48
            {
49
                    a.x = _ax; a.y = _ay;
50
                    b.x = _bx; b.y = _by;
51
                    calcParametric();
52
            }
53
 
54
            public void set(Vector2 _a, Vector2 _b)
55
            {
56
                    a.x = _a.x; a.y = _a.y;
57
                    b.x = _b.x; b.y = _b.y;
58
                    calcParametric();          
59
            }
60
 
61
            public void setPointA(float _ax, float _ay)
62
            {
63
                    a.x = _ax; a.y = _ay;
64
                    calcParametric();          
65
            }
66
 
67
            public void setPointB(float _bx, float _by)
68
            {
69
                    b.x = _bx; b.y = _by;
70
                    calcParametric();          
71
            }
72
 
73
            public Line2 copy()
74
            {
75
                    return new Line2(a, b);
76
            }
77
 
78
            public Vector2 getMidPoint()
79
            {
80
                    return new Vector2(a.x + (b.x - a.x) / 2, a.y + (b.y - a.y) /2);
81
            }
82
 
83
            public Vector2 getLineVector()
84
            {
85
                    return new Vector2(b.x - a.x, b.y - a.y);
86
            }
87
 
88
            public void getLineVector(Vector2 result)
89
            {
90
                    result.set(b.x - a.x, b.y - a.y);
91
            }
92
 
93
            public void calcParametric()
94
            {
95
                    A = getA();
96
                    B = getB();
97
                    C = getC();
98
            }
99
 
100
            public float getLengthSqr()
101
            {
102
                    float diffX = a.x - b.x;
103
                    float diffY = a.y - b.y;
104
                    return (diffX*diffX + diffY*diffY);
105
            }
106
 
107
            public float getLength()
108
            {
109
                    float length = getLengthSqr();
110
                    return (float)(Math.Sqrt(length));
111
            }
112
 
113
            /** Check if x, y (which must be collinear to the line segment) lies within the line segment. */
114
            public bool isCollinearPointOnSegment(float x, float y)
115
            {
116
                    //Gdx.app.log("BLA", "p: " + x + ", " + y + " [" + ax + ", " + ay + " - " + bx + ", " + by);
117
 
118
                    float EPSILON = 0.0001f;
119
 
120
                    if ((x <= (Math.Max(a.x, b.x) + EPSILON)) && (x >= (Math.Min(a.x, b.x) - EPSILON)) &&
121
                            (y <= (Math.Max(a.y, b.y) + EPSILON)) && (y >= (Math.Min(a.y, b.y) - EPSILON)))
122
                    {
123
                            return true;
124
                    }
125
 
126
                    return false;
127
            }
128
 
129
            /** Get the A coefficient in the Ax + By = C form. */
130
            public float getA()
131
            {
132
                    return b.y - a.y;
133
            }
134
 
135
            /** Get the B coefficient in the Ax + By = C form. */
136
            public float getB()
137
            {
138
                    return a.x - b.x;
139
            }
140
 
141
            /** Get the C coefficient in the Ax + By = C form. */
142
            public float getC()
143
            {
144
                    return getA() * a.x + getB() * a.y;
145
            }
146
 
147
 
148
            /** Get intersection point. */
149
            public Vector2 getLineIntersection(Line2 other)
150
            {
151
                    Vector2 result = new Vector2();
152
                    if (getLineIntersection(other, result))
153
                            return result;
154
 
155
                    return null;
156
            }
157
 
158
            /** Get intersection point (no allocation version). */
159
            public bool getLineIntersection(Line2 other, Vector2 result)
160
            {
161
                    // get Ax + By = C form coefficients                
162
                    float A1 = A;
163
                    float B1 = B;
164
                    float C1 = C;
165
 
166
                    float A2 = other.A;
167
                    float B2 = other.B;
168
                    float C2 = other.C;
169
 
170
                    float delta = A1*B2 - A2*B1;
171
                    if (delta == 0)
172
                            return false;
173
 
174
                    float x = (B2*C1 - B1*C2)/delta;
175
                    float y = (A1*C2 - A2*C1)/delta;
176
 
177
                    result.set(x, y);
178
 
179
                    return true;
180
            }
181
 
182
 
183
            /** Get line segment intersection point. */
184
            public Vector2 getSegmentIntersection(Line2 other)
185
            {
186
                    Vector2 result = new Vector2();
187
 
188
                    if (getSegmentIntersection(other, result))
189
                            return result;
190
 
191
                    return null;
192
            }
193
 
194
            /** Get line segment intersection point (no allocation version). */
195
            public bool getSegmentIntersection(Line2 other, Vector2 result)
196
            {
197
                    if (!getLineIntersection(other, result))
198
                            return false;
199
 
200
                    if (this.isCollinearPointOnSegment(result.x, result.y) && other.isCollinearPointOnSegment(result.x, result.y))
201
                            return true;
202
 
203
                    return false;
204
            }
205
 
206
 
207
            /** Check if a segment intersects another. */
208
        public bool intersectsSegment(Line2 other)
209
            {
210
                    return getSegmentIntersection(other, mTemp);
211
            }
212
 
213
 
214
            /** Get the smallest perpendicular vector from point to the line. */
215
            public Vector2 getMinimalVectorFrom(Vector2 point)
216
            {
217
                    /*Vector2 closestPoint = getClosestPointFrom(point);
218
 
219
                    return new Vector2(closestPoint.x - point.x, closestPoint.y - point.y);*/
220
                    Vector2 result = new Vector2();
221
                    getMinimalVectorFrom(point, result);
222
                    return result;
223
            }
224
 
225
 
226
            /** Get the smallest perpendicular vector from point to the line (no allocation version). */
227
            public void getMinimalVectorFrom(Vector2 point, Vector2 result)
228
            {
229
                    //Vector2 closestPoint = getClosestPointFrom(point);
230
                    getClosestPointFrom(point, mTemp);
231
                    result.set(mTemp.x - point.x, mTemp.y - point.y);
232
 
233
                    //return new Vector2(closestPoint.x - point.x, closestPoint.y - point.y);
234
            }
235
 
236
            /** Get the smallest perpendicular vector from point to the line. */
237
            public Vector2 getMinimalVectorFrom(float px, float py)
238
            {
239
                    return getMinimalVectorFrom(new Vector2(px, py));
240
            }
241
 
242
 
243
            /** Get the closest point on line from a given point. */
244
            public Vector2 getClosestPointFrom(Vector2 point)
245
            {
246
                    return getClosestPointFrom(point.x, point.y);
247
            }
248
 
249
            /** Get the closest point on line from a given point (no allocation version). */
250
            public void getClosestPointFrom(Vector2 point, Vector2 result)
251
            {
252
                    getClosestPointFrom(point.x, point.y, result);
253
            }
254
 
255
            /** Get the closest point on line from a given point. */
256
            public Vector2 getClosestPointFrom(float px, float py)
257
            {
258
                    Vector2 result = new Vector2();
259
                    getClosestPointFrom(px, py, result);
260
                    return result;
261
            }
262
 
263
            /** Get the closest point on line from a given point (no allocation version). */
264
            public void getClosestPointFrom(float px, float py, Vector2 result)
265
            {
266
                    getLineVector(mTemp);
267
 
268
                    mTemp2.set(px - a.x, py - a.y);
269
 
270
                    float t = Vector2.dotProduct(mTemp, mTemp2) / mTemp.squaredLength();
271
 
272
                    t = MathUtil.clamp(t, 0, 1);
273
                    result.set(a.x + t * mTemp.x, a.y + t * mTemp.y);
274
            }
275
 
276
 
277
            /** Get the closest distance from a given point. */
278
            public float getClosestDistanceFrom(Vector2 point)
279
            {
280
                    return getClosestDistanceFrom(point.x, point.y);
281
            }
282
 
283
            /** Get the closest distance from a given point. */
284
            public float getClosestDistanceFrom(float px, float py)
285
            {
286
                    return (float)Math.Sqrt(getClosestSquaredDistanceFrom(px, py));
287
            }
288
 
289
            /** Get the closest distance from a given point. */
290
            public float getClosestSquaredDistanceFrom(float px, float py)
291
            {
292
                    getClosestPointFrom(px, py, mTemp);
293
 
294
                    float dx = mTemp.x - px;
295
                    float dy = mTemp.y - py;
296
 
297
                    return (dx*dx + dy*dy);
298
            }
299
    }
300
}