Subversion Repositories AndroidProjects

Rev

Rev 907 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
907 chris 1
package com.gebauz.bauzoid.math;
2
 
3
/** Line segment class. */
4
public class Line2
5
{
6
        // Constants========================================================================================
7
 
8
        // Embedded Types===================================================================================
9
 
10
        // Fields===========================================================================================
11
 
12
        private float ax = 0;
13
        private float ay = 0;
14
 
15
        private float bx = 0;
16
        private float by = 0;
17
 
18
        // parametric form
19
        private float A = 0.0f;
20
        private float B = 0.0f;
21
        private float C = 0.0f;
22
 
23
        // Methods==========================================================================================
24
 
25
        public Line2()
26
        {
27
                calcParametric();
28
        }
29
 
30
        public Line2(float _ax, float _ay, float _bx, float _by)
31
        {
32
                ax = _ax; ay = _ay;
33
                bx = _bx; by = _by;
34
                calcParametric();
35
        }
36
 
37
        public Line2(Vector2 a, Vector2 b)
38
        {
39
                ax = a.x; ay = a.y;
40
                bx = b.x; by = b.y;
41
                calcParametric();
42
        }
43
 
1001 chris 44
        public Vector2 getLineVector()
45
        {
46
                return new Vector2(bx - ax, by - ay);
47
        }
48
 
907 chris 49
        public void calcParametric()
50
        {
51
                A = getA();
52
                B = getB();
53
                C = getC();
54
        }
55
 
56
        public float getLengthSqr()
57
        {
58
                float diffX = ax - bx;
59
                float diffY = ay - by;
60
                return (diffX*diffX + diffY*diffY);
61
        }
62
 
63
        public float getLength()
64
        {
65
                float length = getLengthSqr();
66
                return (float)(Math.sqrt(length));
67
        }
68
 
69
        /** Check if x, y (which must be collinear to the line segment) lies within the line segment. */
70
        public boolean isCollinearPointOnSegment(float x, float y)
71
        {
72
                if ((x <= Math.max(ax, bx)) && (x >= Math.min(ax, bx)) &&
73
                        (y <= Math.max(ay, by)) && (y >= Math.min(ay, by)))
74
                {
75
                        return true;
76
                }
77
 
78
                return false;
79
        }
80
 
81
        /** Get the A coefficient in the Ax + By = C form. */
82
        public final float getA()
83
        {
84
                return by - ay;
85
        }
86
 
87
        /** Get the B coefficient in the Ax + By = C form. */
88
        public final float getB()
89
        {
90
                return ax - bx;
91
        }
92
 
93
        /** Get the C coefficient in the Ax + By = C form. */
94
        public final float getC()
95
        {
96
                return getA() * ax + getB() * ay;
97
        }
98
 
99
        public Vector2 getLineIntersection(Line2 other)
100
        {
101
                // get Ax + By = C form coefficients            
102
                float A1 = A;
103
                float B1 = B;
104
                float C1 = C;
105
 
106
                float A2 = other.A;
107
                float B2 = other.B;
108
                float C2 = other.C;
109
 
110
                float delta = A1*B2 - A2*B1;
111
                if (delta == 0)
112
                        return null;
113
 
114
                float x = (B2*C1 - B1*C2)/delta;
115
                float y = (A1*C2 - A2*C1)/delta;
116
 
117
                return new Vector2(x, y);
118
        }
119
 
120
        public Vector2 getSegmentIntersection(Line2 other)
121
        {
122
                Vector2 p = getLineIntersection(other);
123
 
124
                if (p == null)
125
                        return null;
126
 
127
                if (this.isCollinearPointOnSegment(p.x, p.y) && other.isCollinearPointOnSegment(p.x, p.y))
128
                        return p;
129
 
130
                return null;
131
        }
132
 
133
        public boolean intersectsSegment(Line2 other)
134
        {
135
                Vector2 p = getSegmentIntersection(other);
136
 
137
                if (p == null)
138
                        return false;
139
 
140
                return true;
141
        }
1001 chris 142
 
143
        /** Get the smallest perpendicular vector from point to the line. */
144
        public Vector2 getMinimalVectorFrom(Vector2 point)
145
        {
146
                Vector2 closestPoint = getClosestPointFrom(point);
147
 
148
                return new Vector2(closestPoint.x - point.x, closestPoint.y - point.y);
149
        }
150
 
151
        /** Get the smallest perpendicular vector from point to the line. */
152
        public Vector2 getMinimalVectorFrom(float px, float py)
153
        {
154
                return getMinimalVectorFrom(new Vector2(px, py));
155
        }
156
 
157
        /** Get the closest point on line from a given point. */
158
        public Vector2 getClosestPointFrom(Vector2 point)
159
        {
160
                Vector2 ab = getLineVector();
161
 
162
                Vector2 ap = new Vector2(point.x - ax, point.y - ay);
163
 
164
                float t = Vector2.dotProduct(ap, ab) / ab.squaredLength();
165
 
166
                t = MathUtil.clamp(t, 0, 1);
167
 
168
                return new Vector2(ax + t * ab.x, ay + t * ab.y);
169
        }
170
 
171
        public Vector2 getClosestPointFrom(float px, float py)
172
        {
173
                return getClosestPointFrom(new Vector2(px, py));
174
        }
175
 
176
 
177
        /*     
178
        (P-A).D == |X-A|
907 chris 179
 
1001 chris 180
                        X == A + ((P-A).D)D
181
                        Desired perpendicular: X-P
182
 
183
 
184
                          Returns the closest point x on segment ab to point p
185
   (x-p).(b-a) = 0, x = a + t(b-a)
186
   => (a + t(b-a) - p).(b-a) = 0
187
   => t(b-a).(b-a) = (p-a).(b-a)
188
   => t = (p-a).(b-a) / |b-a|^2
189
 
190
   Ogre::Vector3 closestPointOnLineSegment(const Ogre::Vector3 &p,const Ogre::Vector3 &a,const Ogre::Vector3 b)
191
   {
192
      Ogre::Vector3 ab = b-a;
193
      float t = (p-a).dotProduct(ab) / (ab).squaredLength();
194
      t = Ogre::Math::Clamp(t,0.f,1.f);
195
      return a + t*ab;
196
   }
197
 
198
                        *
199
                        *
200
                        *
201
                        */
202
 
907 chris 203
        // Getters/Setters==================================================================================
204
 
205
}
206
 
207
 
208