@@ -130,7 +130,7 @@ static f64 iptsd_dft_interpolate_frequency(const Context &ctx, const ipts::DftWi
130
130
static void iptsd_dft_handle_position (Context &ctx, const ipts::DftWindow &dft,
131
131
ipts::StylusData &stylus)
132
132
{
133
- if (dft.rows <= 0 ) {
133
+ if (dft.rows <= 1 ) {
134
134
iptsd_dft_lift (stylus);
135
135
return ;
136
136
}
@@ -161,6 +161,47 @@ static void iptsd_dft_handle_position(Context &ctx, const ipts::DftWindow &dft,
161
161
if (ctx.config .invert_y )
162
162
y = 1 - y;
163
163
164
+ if (dft.x [1 ].magnitude > ctx.config .dft_tilt_min_mag &&
165
+ dft.y [1 ].magnitude > ctx.config .dft_tilt_min_mag ) {
166
+
167
+ // calculate tilt angle from relative position of secondary transmitter
168
+
169
+ auto [pxt, xt] = iptsd_dft_interpolate_position (ctx, dft.x [1 ]);
170
+ auto [pyt, yt] = iptsd_dft_interpolate_position (ctx, dft.y [1 ]);
171
+
172
+ if (pxt && pyt) {
173
+
174
+ xt /= dft.dim .width - 1 ;
175
+ yt /= dft.dim .height - 1 ;
176
+
177
+ if (ctx.config .invert_x )
178
+ xt = 1 - xt;
179
+
180
+ if (ctx.config .invert_y )
181
+ yt = 1 - yt;
182
+
183
+ xt -= x;
184
+ yt -= y;
185
+
186
+ if (ctx.config .dft_tip_distance ) {
187
+ // correct tip position using tilt data
188
+ auto r = ctx.config .dft_tip_distance / ctx.config .dft_tilt_distance ;
189
+ x -= xt * r;
190
+ y -= yt * r;
191
+ }
192
+
193
+ xt *= ctx.config .width / (ctx.config .dft_tilt_distance * 10 );
194
+ yt *= ctx.config .height / (ctx.config .dft_tilt_distance * 10 );
195
+
196
+ auto azm = std::max (0 ., std::fmod (std::atan2 (-yt, xt) / M_PI + 2 , 2 )) * 18000 ;
197
+ auto alt = (.5 - std::acos (std::min (1 ., std::hypot (xt, yt))) / M_PI) * 18000 ;
198
+ stylus.azimuth = gsl::narrow<u16>(std::round (azm));
199
+ stylus.altitude = gsl::narrow<u16>(std::round (alt));
200
+
201
+ }
202
+
203
+ }
204
+
164
205
x = std::round (std::clamp (x, 0.0 , 1.0 ) * IPTS_MAX_X);
165
206
y = std::round (std::clamp (y, 0.0 , 1.0 ) * IPTS_MAX_Y);
166
207
0 commit comments