0
# Coordinate Transformations
1
2
Coordinate system conversions between canvas, cartesian, and polar coordinate systems for advanced geometric calculations and animations.
3
4
## Capabilities
5
6
### Coordinate System Types
7
8
```typescript { .api }
9
/**
10
* Polar coordinate representation
11
*/
12
interface PolarPoint {
13
/** Angle in radians */
14
theta: number;
15
/** Distance from origin */
16
radius: number;
17
}
18
```
19
20
### Canvas ↔ Cartesian Conversions
21
22
Convert between canvas coordinates (origin top-left, Y increases downward) and mathematical cartesian coordinates (origin at center, Y increases upward).
23
24
```typescript { .api }
25
/**
26
* Convert canvas coordinates to cartesian coordinates
27
* @param v - Canvas coordinate point
28
* @param center - Center point for coordinate system
29
* @returns Cartesian coordinate point
30
*/
31
function canvas2Cartesian(v: Vector, center: Vector): Vector;
32
33
/**
34
* Convert cartesian coordinates to canvas coordinates
35
* @param v - Cartesian coordinate point
36
* @param center - Center point for coordinate system
37
* @returns Canvas coordinate point
38
*/
39
function cartesian2Canvas(v: Vector, center: Vector): Vector;
40
```
41
42
**Usage Example:**
43
44
```typescript
45
import { canvas2Cartesian, cartesian2Canvas, vec2 } from "react-native-redash";
46
47
// Canvas setup
48
const screenWidth = 300;
49
const screenHeight = 400;
50
const center = vec2(screenWidth / 2, screenHeight / 2); // (150, 200)
51
52
// Convert touch position to mathematical coordinates
53
const touchPosition = vec2(100, 100); // Top-left area of screen
54
const mathCoords = canvas2Cartesian(touchPosition, center);
55
// Result: { x: -50, y: 100 } (left and up from center)
56
57
// Convert back to canvas for drawing
58
const canvasCoords = cartesian2Canvas(mathCoords, center);
59
// Result: { x: 100, y: 100 } (original position)
60
```
61
62
### Cartesian ↔ Polar Conversions
63
64
Convert between cartesian (x, y) and polar (angle, radius) coordinate systems.
65
66
```typescript { .api }
67
/**
68
* Convert cartesian coordinates to polar coordinates
69
* @param v - Cartesian coordinate point
70
* @returns Polar coordinate point
71
*/
72
function cartesian2Polar(v: Vector): PolarPoint;
73
74
/**
75
* Convert polar coordinates to cartesian coordinates
76
* @param p - Polar coordinate point
77
* @returns Cartesian coordinate point
78
*/
79
function polar2Cartesian(p: PolarPoint): Vector;
80
```
81
82
**Usage Example:**
83
84
```typescript
85
import { cartesian2Polar, polar2Cartesian, vec2 } from "react-native-redash";
86
87
// Convert point to polar coordinates
88
const point = vec2(100, 100);
89
const polar = cartesian2Polar(point);
90
// Result: { theta: 0.785..., radius: 141.42... } (45° at distance √2*100)
91
92
// Convert back to cartesian
93
const cartesian = polar2Cartesian(polar);
94
// Result: { x: 100, y: 100 } (original point)
95
96
// Useful for rotational animations
97
const rotatedPolar = { ...polar, theta: polar.theta + Math.PI / 4 };
98
const rotatedPoint = polar2Cartesian(rotatedPolar);
99
```
100
101
### Direct Conversions
102
103
Convenience functions that combine multiple coordinate system conversions.
104
105
```typescript { .api }
106
/**
107
* Convert polar coordinates directly to canvas coordinates
108
* @param p - Polar coordinate point
109
* @param center - Canvas center point
110
* @returns Canvas coordinate point
111
*/
112
function polar2Canvas(p: PolarPoint, center: Vector): Vector;
113
114
/**
115
* Convert canvas coordinates directly to polar coordinates
116
* @param v - Canvas coordinate point
117
* @param center - Canvas center point
118
* @returns Polar coordinate point
119
*/
120
function canvas2Polar(v: Vector, center: Vector): PolarPoint;
121
```
122
123
**Complete Animation Example:**
124
125
```typescript
126
import React, { useEffect } from "react";
127
import { View, StyleSheet } from "react-native";
128
import {
129
canvas2Polar,
130
polar2Canvas,
131
canvas2Cartesian,
132
vec2,
133
useVector
134
} from "react-native-redash";
135
import Animated, {
136
useSharedValue,
137
useAnimatedStyle,
138
useAnimatedGestureHandler,
139
withSpring,
140
useDerivedValue,
141
withRepeat,
142
withTiming
143
} from "react-native-reanimated";
144
import { PanGestureHandler } from "react-native-gesture-handler";
145
146
export const PolarAnimationDemo = () => {
147
const center = vec2(150, 200);
148
const position = useVector(150, 200);
149
const angle = useSharedValue(0);
150
const radius = useSharedValue(80);
151
152
// Animate in circular motion
153
useEffect(() => {
154
angle.value = withRepeat(
155
withTiming(Math.PI * 2, { duration: 3000 }),
156
-1,
157
false
158
);
159
}, []);
160
161
// Convert polar to canvas coordinates for circular animation
162
const circularStyle = useAnimatedStyle(() => {
163
const canvasPos = polar2Canvas(
164
{ theta: angle.value, radius: radius.value },
165
center
166
);
167
168
return {
169
transform: [
170
{ translateX: canvasPos.x - 25 }, // Offset for element size
171
{ translateY: canvasPos.y - 25 }
172
]
173
};
174
});
175
176
// Gesture handler for interactive element
177
const gestureHandler = useAnimatedGestureHandler({
178
onActive: (event) => {
179
const touchPos = vec2(event.absoluteX, event.absoluteY);
180
const polar = canvas2Polar(touchPos, center);
181
182
// Update position based on polar coordinates
183
position.x.value = touchPos.x;
184
position.y.value = touchPos.y;
185
186
// Could use polar data for other effects
187
radius.value = withSpring(Math.min(polar.radius, 120));
188
}
189
});
190
191
const interactiveStyle = useAnimatedStyle(() => ({
192
transform: [
193
{ translateX: position.x.value - 25 },
194
{ translateY: position.y.value - 25 }
195
]
196
}));
197
198
// Polar coordinate display
199
const polarDisplay = useDerivedValue(() => {
200
const touchPos = vec2(position.x.value, position.y.value);
201
const polar = canvas2Polar(touchPos, center);
202
return `θ: ${(polar.theta * 180 / Math.PI).toFixed(1)}° r: ${polar.radius.toFixed(1)}`;
203
});
204
205
return (
206
<View style={styles.container}>
207
{/* Center point */}
208
<View style={[styles.center, {
209
left: center.x - 5,
210
top: center.y - 5
211
}]} />
212
213
{/* Circular animation */}
214
<Animated.View style={[styles.circle, circularStyle]} />
215
216
{/* Interactive element */}
217
<PanGestureHandler onGestureEvent={gestureHandler}>
218
<Animated.View style={[styles.interactive, interactiveStyle]} />
219
</PanGestureHandler>
220
221
{/* Coordinate display would go here in real app */}
222
</View>
223
);
224
};
225
226
const styles = StyleSheet.create({
227
container: {
228
flex: 1,
229
backgroundColor: "#f0f0f0"
230
},
231
center: {
232
position: "absolute",
233
width: 10,
234
height: 10,
235
borderRadius: 5,
236
backgroundColor: "red"
237
},
238
circle: {
239
position: "absolute",
240
width: 50,
241
height: 50,
242
borderRadius: 25,
243
backgroundColor: "blue"
244
},
245
interactive: {
246
position: "absolute",
247
width: 50,
248
height: 50,
249
borderRadius: 25,
250
backgroundColor: "green"
251
}
252
});
253
```
254
255
**Practical Use Cases:**
256
257
```typescript
258
import {
259
canvas2Polar,
260
polar2Canvas,
261
cartesian2Polar,
262
polar2Cartesian,
263
vec2
264
} from "react-native-redash";
265
266
// 1. Radial menu positioning
267
const menuItems = 6;
268
const menuRadius = 100;
269
const center = vec2(150, 150);
270
271
const menuPositions = Array.from({ length: menuItems }, (_, i) => {
272
const angle = (i * 2 * Math.PI) / menuItems;
273
return polar2Canvas({ theta: angle, radius: menuRadius }, center);
274
});
275
276
// 2. Orbital animation
277
const orbitRadius = useSharedValue(80);
278
const orbitSpeed = useSharedValue(1);
279
280
const orbitStyle = useAnimatedStyle(() => {
281
const time = Date.now() / 1000;
282
const angle = time * orbitSpeed.value;
283
284
const position = polar2Canvas(
285
{ theta: angle, radius: orbitRadius.value },
286
center
287
);
288
289
return {
290
transform: [
291
{ translateX: position.x },
292
{ translateY: position.y }
293
]
294
};
295
});
296
297
// 3. Compass or gauge interfaces
298
const compassNeedle = useAnimatedStyle(() => {
299
const heading = heading.value; // Some heading value
300
const needleEnd = polar2Canvas(
301
{ theta: heading, radius: 80 },
302
center
303
);
304
305
// Calculate rotation for needle pointing to the coordinate
306
return {
307
transform: [
308
{ rotate: `${heading}rad` }
309
]
310
};
311
});
312
```