Given that you have thousands of 3D vectors with their time of insertion, and you want to find the instantaneous velocity at the current time? Also, the primary criterion is accuracy, with the secondary criterion being performance.
Sample data:
t is in milliseconds (low resolution)
:> t: 19624, x: -221.68, y: 394.46, z: 127.66
:> t: 19656, x: -222.07, y: 394.26, z: 127.54
:> t: 19671, x: -222.47, y: 394.06, z: 127.43
:> t: 19687, x: -222.53, y: 394.03, z: 127.36
:> t: 19718, x: -222.95, y: 393.81, z: 127.23
:> t: 19734, x: -222.95, y: 393.81, z: 127.23
:> t: 19749, x: -223.42, y: 393.58, z: 127.05
:> t: 19765, x: -223.42, y: 393.58, z: 127.05
:> t: 19796, x: -223.86, y: 393.36, z: 126.91
:> t: 19812, x: -224.30, y: 393.13, z: 126.77
:> t: 19827, x: -224.36, y: 393.11, z: 126.71
:> t: 19843, x: -224.36, y: 393.11, z: 126.71
:> t: 19858, x: -224.82, y: 392.87, z: 126.55
:> t: 19874, x: -225.27, y: 392.65, z: 126.48
:> t: 19890, x: -225.32, y: 392.63, z: 126.49 [current time]
velocity with respect to OX, OY and OZ axes is the second derivative of x(t), y(t) and z(t).
The first defivative (suppose t=1) if easy to find
x'(1) = x(1) - x(0)
and
x''(2) = x'(2) - x'(1)
it will be fast enough but it wount be accurate. So I recoment you to approximate the series of x(t) with continious function (polynom), and calculate the second derivative of that polynom. Try to read about interpolation polynomes here.
Related
I have N numbers of geographical points and coordinates of the points are being updated frequently. And the number N is very big.
I need to find points within a rectangle.
I have tried searching by all points, by using 2d Array grid and R tree.
I had to remove and then insert again which is costly operation.
Indexing spatial data is a complex topic. If you just have points you can index them using a sparse grid (better memory utilization than just 2d array):
class SpatialGrid:
def __init__(self, cell_size):
self._cells: DefaultDict[Tuple, Set] = defaultdict(set)
self._cell_size = cell_size
def __len__(self):
return len(self._cells)
def _key(self, x: float, y: float) -> Tuple:
return int(x / self._cell_size), int(y / self._cell_size)
def add(self, x: float, y: float, obj: object) -> None:
i_x, i_y = self._key(x, y)
for i in (-1, 0, 1):
for j in (-1, 0, 1):
self._cells[(i_x + i, i_y + j)].add(obj)
def get(self, x: float, y: float) -> Set:
return self._cells[self._key(x, y)]
def contains(self, x: float, y: float) -> bool:
return self._key(x, y) in self._cells
if you need to find by rectangle then you can just iterate over grid cells that are in that rectangle
But of course you will need to remove and insert points whenever the coordinates change. Indexing is costly.
Given a list of points
[
%{ x: 3, y: 8 },
...,
%{ x: 1, y: 4 }
]
What is the best way to calculate the coordinates of a box that will contain all points - i.e. the bounds: %{ x1: 1, y1: 4, x2: 3, y2: 8 }
I have a hunch I can use Enum.flat_map_reduce/3 but the syntax is baffling me at the moment.
I actually ran into this as part of Advent of Code 2018 day 10 last year. This was my method. It sets the bounding box to the initial point, and then expands it as it finds points further out. No need for nil. :-)
Here it is adapted for your data:
# Start with the first point, then compare all the others to find the extremities
def bounding_box([%{x: x, y: y} | points]) do
Enum.reduce(points, %{x1: x, y1: y, x2: x, y2: y}, fn point, box ->
%{
x1: min(point.x, box.x1),
y1: min(point.y, box.y1),
x2: max(point.x, box.x2),
y2: max(point.y, box.y2)
}
end)
end
Enum.reduce/3 would be enough.
input = [%{x: 3, y: 8}, %{x: 1, y: 4}]
Enum.reduce(input, %{x1: nil, x2: nil, y1: nil, y2: nil}, fn
%{x: x, y: y}, %{x1: x1, x2: x2, y1: y1, y2: y2} ->
%{
x1: if(x < x1, do: x, else: x1),
x2: if(is_nil(x2) or x > x2, do: x, else: x2),
y1: if(y < y1, do: y, else: y1),
y2: if(is_nil(y2) or y > y2, do: y, else: y2),
}
end)
A number in Erlang (and hence Elixir) is less than any other type, hence nils for x1 and y1 are simply fine. For x2 and y2 we require an additional condition.
I would propose this, as more readable than an Enum.reduce:
input = [%{x: 3, y: 8}, %{x: 1, y: 4}]
%{
x1: input |> Enum.map(& &1.x) |> Enum.min(),
x2: input |> Enum.map(& &1.x) |> Enum.max(),
y1: input |> Enum.map(& &1.y) |> Enum.min(),
y2: input |> Enum.map(& &1.y) |> Enum.max()
}
Of course there is the downside of iterating over the list multiple times. Depending on your exact requirements, that might be a problem.
I think Enum.reduce/3 is the right way to go, but Kernel.min/2 and Kernel.max/2 can handle the decision logic pretty well (we just have to augment max to reject nil)
defmodule BoundingBox do
#moduledoc """
Creates a bounding box around coordinates.
"""
#initial %{x1: nil, y1: nil, x2: nil, y2: nil}
def new(enumerable) do
Enum.reduce(enumerable, #initial, &get_bounds/2)
end
defp get_bounds(%{x: x, y: y}, %{x1: left, y1: bottom, x2: right, y2: top}) do
%{x1: min(left, x), y1: min(bottom, y), x2: max_num(right, x), y2: max_num(top, right)}
end
defp max_num(nil, b), do: b
defp max_num(a, b), do: max(a, b)
end
I'd like to find out the height of an element, of a specific width and height, after a rotationX transform has been applied to it.
Would be ideal to be able find out the angle of an element's rotationX transform given the desired height.
rotateX() preserves the x-coordinate. The y-coordinate scales with the cosine of the rotation angle:
new_height = old_height * cos(angle)
The other way around is:
angle = arc cos(new_height / old_height)
Found 2 ways on finding dimensions of a DOM element after css 3D transforms have been applied to it.
1.By using element.getBoundingClientRect() which will return a ClientRect object with the correct dimensions of an elements after the transforms has been applied to it
{
bottom: 90.07061767578125
height: 90.07061767578125
left: 0
right: 891
top: 0
width: 891
}
A module called domvertices will return the xyz positions of 4 corner vertices for a DOM element, accounting for any transformatons:
{
a: {x: , y: , z: },
b: {x: , y: , z: },
c: {x: , y: , z: },
d: {x: , y: , z: }
}
I need to animate a similar animation in quickdraw and I'm told to use recursion. I'm having a hard time with the orbits and this is the code I have for orbiting circle but I have no idea how to use recursion to create the above image.
import math
print("circle",400,300,50)
print("flush false")
centreX=400
centreY=300
radius=100
angle=math.pi/2
while True:
print("color 0 0 0")
print("clear")
print("color 255 0 255")
print("circle",centreX,centreY,radius)
childX=math.sin(angle)*radius*1.5+centreX
childY=math.cos(angle)*radius*1.5+centreY
print("circle",childX,childY,radius/2)
print("refresh")
angle+=0.01
the data file looks like this:
RootObject: Sun
Object: Sun
Satellites: Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune,Ceres,Pluto,Haumea,Makemake,Eris
Radius: 20890260
Orbital Radius: 0
Object: Miranda
Orbital Radius: 5822550
Radius: 23500
Period: 1.413
Object: Ariel
Orbital Radius: 8595000
Radius: 60000
Period: 2.520379
Object: Umbriel
Orbital Radius: 11983500
Radius: 60000
Period: 4.144177
Object: Titania
Orbital Radius: 19575000
Radius: 75000
Period: 8.7058
Object: Oberon
Orbital Radius: 26235000
Radius: 75000
Period: 13.463
Object: Uranus
Orbital Radius: 453572956
Radius: 2555900
Period: 30799
Satellites: Puck,Miranda,Ariel,Umbriel,Titania,Oberon
Object: Neptune
Orbital Radius: 550000000
Radius: 2476400
Period: 60190
Satellites: Triton
Object: Triton
Orbital Radius: 40000000
Radius: 135300
Period: -5.8
Object: Mercury
Orbital Radius: 38001200
Period: 87.9691
Radius: 243900.7
Object: Venus
Orbital Radius: 57477000
Period: 224.698
Radius: 605100.8
Object: Earth
Orbital Radius: 77098290
Period: 365.256363004
Radius: 637100.0
Satellites: Moon
Object: Moon
Orbital Radius: 18128500
Radius: 173700.10
Period: 27.321582
Object: Mars
Orbital Radius: 106669000
Period: 686.971
Radius: 339600.2
Satellites: Phobos,Deimos
Object: Phobos
Orbital Radius: 3623500.6
Radius: 200000
Period: 0.31891023
Object: Deimos
Orbital Radius: 8346000
Period: 1.26244
Radius: 200000.2
Object: Jupiter
Orbital Radius: 210573600
Period: 4332.59
Radius: 7149200
Satellites: Io,Europa,Ganymede,Callisto
Object: Ceres
Orbital Radius: 130995855
Period: 1679.67
Radius: 48700
Object: Io
Orbital Radius: 22000000
Period: 1.7691377186
Radius: 182100.3
Object: Europa
Orbital Radius: 36486200
Period: 3.551181
Radius: 156000.8
Object: Ganymede
Orbital Radius: 47160000
Period: 7.15455296
Radius: 263400
Object: Callisto
Orbital Radius: 69700000
Period: 16.6890184
Radius: 241000
Object: Saturn
Orbital Radius: 353572956
Period: 10759.22
Radius: 6026800
Satellites: Mimas,Enceladus,Tethys,Dione,Rhea,Titan,Iapetus
Object: Mimas
Orbital Radius: 8433396
Radius: 20600
Period: 0.9
Object: Enceladus
Orbital Radius: 10706000
Radius: 25000
Period: 1.4
Object: Tethys
Orbital Radius: 13706000
Radius: 50000
Period: 1.9
Object: Dione
Orbital Radius: 17106000
Radius: 56000
Period: 2.7
Object: Rhea
Orbital Radius: 24000000
Radius: 75000
Period: 4.5
Object: Titan
Orbital Radius: 50706000
Radius: 257600
Period: 15.945
Object: Iapetus
Radius: 75000
Orbital Radius: 72285891
Period: 79
I'm supposed to import the data into a recursive function to create the orbits and the animation but I have no idea how. I've tried almost everything, Its very frustrating.
Would this code work?
print("flush false")
scale=250/max([dict[x]["Orbital Radius"] for x in dict if "Orbital Radius" in dict[x]])
t=0
x=400
y=300
while True:
print("refresh")
print("colour 0 0 0")
print("clear")
print("colour 255 255 255")
print("fillcircle",x,y,dict['Sun']['Radius']*scale)
print("text ", "\"Sun\"",x+dict['Sun']['Radius']*scale,y)
r_earth=dict['Earth']['Orbital Radius']*scale;
print("circle",x,y,r_earth)
r_X=x+math.sin(t*2*math.pi/dict['Earth']['Period'])*r_earth
r_Y=y+math.cos(t*2*math.pi/dict['Earth']['Period'])*r_earth
print("fillcircle",r_X,r_Y,dict['Earth']['Radius']*scale)
print("text ", "\"Earth\"",r_X+dict['Earth']['Radius']*scale,r_Y)
t+=0.02
I have coordinates (Idrisi) x: 550000, 580000 y: 4840000, 4810000, but I need latitude and longitude... how can I convert it? :(
Thanx