formula by https://github.com/seiji-t
https://crashlaker.github.io/d3js-static/infinity/index2-rocket.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>
<script src="https://unpkg.com/geometric@1.0.0/build/geometric.min.js"></script>
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#container {
width: 1000px;
height: 1000px;
margin: auto;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
const container = d3.select('#container')
.style('position', 'relative')
const rocket = container.append('img')
.attr('src', 'rocket.png')
.style('position', 'absolute')
.style('width', '80px')
const scaleX = d3.scaleLinear().domain([-1,1]).range([100, 700])
const scaleY = d3.scaleLinear().domain([-1,1]).range([100, 700])
let m = 10
let oldx = oldy = 0
let x, y
let i = 1
// setInterval(() => {
d3.timer(_ => {
x = Math.cos(i)
y = Math.sin(i) * Math.cos(i)
// working solution I
// let angle = geometric.lineAngle([[oldx,oldy], [x,y]])
// angle += 90
// working solution II by seiji
let num = (Math.cos(i)*Math.cos(i)) - (Math.sin(i)*Math.sin(i))
let den = -Math.sin(i)
let angle = Math.atan2(num,den) // NAN
angle *= 180/Math.PI
angle += 90
rocket.style('top', scaleX(y)+'px')
.style('left', scaleY(x)+'px')
.style('transform', `rotate(${angle}deg)`)
// console.log(scaleX(x), scaleY(y))
oldx = x
oldy = y
i+=0.04
})
// }, 30);
</script>
</body>
</html>
references
Angle Between Points
https://bl.ocks.org/HarryStevens/b212d3166a85aecb9d5fc61cf660de23