1 /**
2 * libdmtx - Data Matrix Encoding/Decoding Library
3 * Copyright 2008, 2009 Mike Laughton. All rights reserved.
4 * Copyright 2012-2016 Vadim A. Misbakh-Soloviov. All rights reserved.
5 *
6 * See LICENSE file in the main project directory for full
7 * terms of use and distribution.
8 *
9 * Contact:
10 * Vadim A. Misbakh-Soloviov <dmtx@mva.name>
11 * Mike Laughton <mike@dragonflylogic.com>
12 *
13 * \file dmtxvector2.c
14 * \brief 2D Vector math
15 */
16
17 /**
18 *
19 *
20 */
21 extern DmtxVector2 *
dmtxVector2AddTo(DmtxVector2 * v1,const DmtxVector2 * v2)22 dmtxVector2AddTo(DmtxVector2 *v1, const DmtxVector2 *v2)
23 {
24 v1->X += v2->X;
25 v1->Y += v2->Y;
26
27 return v1;
28 }
29
30 /**
31 *
32 *
33 */
34 extern DmtxVector2 *
dmtxVector2Add(DmtxVector2 * vOut,const DmtxVector2 * v1,const DmtxVector2 * v2)35 dmtxVector2Add(DmtxVector2 *vOut, const DmtxVector2 *v1, const DmtxVector2 *v2)
36 {
37 *vOut = *v1;
38
39 return dmtxVector2AddTo(vOut, v2);
40 }
41
42 /**
43 *
44 *
45 */
46 extern DmtxVector2 *
dmtxVector2SubFrom(DmtxVector2 * v1,const DmtxVector2 * v2)47 dmtxVector2SubFrom(DmtxVector2 *v1, const DmtxVector2 *v2)
48 {
49 v1->X -= v2->X;
50 v1->Y -= v2->Y;
51
52 return v1;
53 }
54
55 /**
56 *
57 *
58 */
59 extern DmtxVector2 *
dmtxVector2Sub(DmtxVector2 * vOut,const DmtxVector2 * v1,const DmtxVector2 * v2)60 dmtxVector2Sub(DmtxVector2 *vOut, const DmtxVector2 *v1, const DmtxVector2 *v2)
61 {
62 *vOut = *v1;
63
64 return dmtxVector2SubFrom(vOut, v2);
65 }
66
67 /**
68 *
69 *
70 */
71 extern DmtxVector2 *
dmtxVector2ScaleBy(DmtxVector2 * v,double s)72 dmtxVector2ScaleBy(DmtxVector2 *v, double s)
73 {
74 v->X *= s;
75 v->Y *= s;
76
77 return v;
78 }
79
80 /**
81 *
82 *
83 */
84 extern DmtxVector2 *
dmtxVector2Scale(DmtxVector2 * vOut,const DmtxVector2 * v,double s)85 dmtxVector2Scale(DmtxVector2 *vOut, const DmtxVector2 *v, double s)
86 {
87 *vOut = *v;
88
89 return dmtxVector2ScaleBy(vOut, s);
90 }
91
92 /**
93 *
94 *
95 */
96 extern double
dmtxVector2Cross(const DmtxVector2 * v1,const DmtxVector2 * v2)97 dmtxVector2Cross(const DmtxVector2 *v1, const DmtxVector2 *v2)
98 {
99 return (v1->X * v2->Y) - (v1->Y * v2->X);
100 }
101
102 /**
103 *
104 *
105 */
106 extern double
dmtxVector2Norm(DmtxVector2 * v)107 dmtxVector2Norm(DmtxVector2 *v)
108 {
109 double mag;
110
111 mag = dmtxVector2Mag(v);
112
113 if(mag <= DmtxAlmostZero)
114 return -1.0; /* XXX this doesn't look clean */
115
116 dmtxVector2ScaleBy(v, 1/mag);
117
118 return mag;
119 }
120
121 /**
122 *
123 *
124 */
125 extern double
dmtxVector2Dot(const DmtxVector2 * v1,const DmtxVector2 * v2)126 dmtxVector2Dot(const DmtxVector2 *v1, const DmtxVector2 *v2)
127 {
128 return (v1->X * v2->X) + (v1->Y * v2->Y);
129 }
130
131 /**
132 *
133 *
134 */
135 extern double
dmtxVector2Mag(const DmtxVector2 * v)136 dmtxVector2Mag(const DmtxVector2 *v)
137 {
138 return sqrt(v->X * v->X + v->Y * v->Y);
139 }
140
141 /**
142 *
143 *
144 */
145 extern double
dmtxDistanceFromRay2(const DmtxRay2 * r,const DmtxVector2 * q)146 dmtxDistanceFromRay2(const DmtxRay2 *r, const DmtxVector2 *q)
147 {
148 DmtxVector2 vSubTmp;
149
150 /* Assumes that v is a unit vector */
151 assert(fabs(1.0 - dmtxVector2Mag(&(r->v))) <= DmtxAlmostZero);
152
153 return dmtxVector2Cross(&(r->v), dmtxVector2Sub(&vSubTmp, q, &(r->p)));
154 }
155
156 /**
157 *
158 *
159 */
160 extern double
dmtxDistanceAlongRay2(const DmtxRay2 * r,const DmtxVector2 * q)161 dmtxDistanceAlongRay2(const DmtxRay2 *r, const DmtxVector2 *q)
162 {
163 DmtxVector2 vSubTmp;
164
165 #ifdef DEBUG
166 /* Assumes that v is a unit vector */
167 if(fabs(1.0 - dmtxVector2Mag(&(r->v))) > DmtxAlmostZero) {
168 ; /* XXX big error goes here */
169 }
170 #endif
171
172 return dmtxVector2Dot(dmtxVector2Sub(&vSubTmp, q, &(r->p)), &(r->v));
173 }
174
175 /**
176 *
177 *
178 */
179 extern DmtxPassFail
dmtxRay2Intersect(DmtxVector2 * point,const DmtxRay2 * p0,const DmtxRay2 * p1)180 dmtxRay2Intersect(DmtxVector2 *point, const DmtxRay2 *p0, const DmtxRay2 *p1)
181 {
182 double numer, denom;
183 DmtxVector2 w;
184
185 denom = dmtxVector2Cross(&(p1->v), &(p0->v));
186 if(fabs(denom) <= DmtxAlmostZero)
187 return DmtxFail;
188
189 dmtxVector2Sub(&w, &(p1->p), &(p0->p));
190 numer = dmtxVector2Cross(&(p1->v), &w);
191
192 return dmtxPointAlongRay2(point, p0, numer/denom);
193 }
194
195 /**
196 *
197 *
198 */
199 extern DmtxPassFail
dmtxPointAlongRay2(DmtxVector2 * point,const DmtxRay2 * r,double t)200 dmtxPointAlongRay2(DmtxVector2 *point, const DmtxRay2 *r, double t)
201 {
202 DmtxVector2 vTmp;
203
204 /* Ray should always have unit length of 1 */
205 assert(fabs(1.0 - dmtxVector2Mag(&(r->v))) <= DmtxAlmostZero);
206
207 dmtxVector2Scale(&vTmp, &(r->v), t);
208 dmtxVector2Add(point, &(r->p), &vTmp);
209
210 return DmtxPass;
211 }
212