Find specific point between 2 points - three.js - vector

How can I find a point ( C (x,y,z) ) between 2 points ( A(x,y,z) , B(x,y,z) ) in a thgree.js scene?
I know that with this: mid point I can find the middle point between them, but I don't want the middle point, I want to find the point which is between them and also has distance a from the A point?
in this picture you can see what I mean :
Thank you.

Basically you need to get the direction vector between the two points (D), normalize it, and you'll use it for getting the new point in the way: NewPoint = PointA + D*Length.
You could use length normalized (0..1) or as an absolute value from 0 to length of the direction vector.
Here you can see some examples using both methods:
Using absolute value:
function getPointInBetweenByLen(pointA, pointB, length) {
var dir = pointB.clone().sub(pointA).normalize().multiplyScalar(length);
return pointA.clone().add(dir);
}
And to use with percentage (0..1)
function getPointInBetweenByPerc(pointA, pointB, percentage) {
var dir = pointB.clone().sub(pointA);
var len = dir.length();
dir = dir.normalize().multiplyScalar(len*percentage);
return pointA.clone().add(dir);
}
See it in action: http://jsfiddle.net/8mnqjsge/
Hope it helps.

I know the question is for THREE.JS and I end up looking for something similar in Babylon JS.
Just in case if you are using Babylon JS Vector3 then the formula would translate to:
function getPointInBetweenByPerc(pointA, pointB, percentage) {
var dir = pointB.clone().subtract(pointA);
var length = dir.length();
dir = dir.normalize().scale(length *percentage);
return pointA.clone().add(dir);
}
Hope it help somebody.

This is known as lerp between two points
e.g. in Three:
C = new Three.Vector3()
C.lerpVectors(A, B, a)
also in generic this is just a single lerp (linear interpolation) math (basically (a * t) + b * (1 - t)) on each axis. Lerp can be described as follows:
function lerp (a, b, t) {
return a + t * (b - a)
}
in your case (see above) :
A = {
x: lerp(A.x, B.x, a),
y: lerp(A.y, B.y, a),
z: lerp(A.z, B.z, a)
}

Related

How would you normalize and calculate speed for a 2D vector if it was clamped by different speeds in all four directions? (-x, +x, -y, +y)

My goal here is to improve the user experience so that the cursor goes where the user would intuitively expect it to when moving the joystick diagonally, whatever that means.
Consider a joystick that has a different configured speed for each direction.
e.g. Maybe the joystick has a defect where some directions are too sensitive and some aren't sensitive enough, so you're trying to correct for that. Or maybe you're playing an FPS where you rarely need to look up or down, so you lower the Y-sensitivity.
Here are our max speeds for each direction:
var map = {
x: 100,
y: 200,
}
The joystick input gives us a unit vector from 0 to 1.
Right now the joystick is tilted to the right 25% of the way and tilted up 50% of the way.
joystick = (dx: 0.25, dy: -0.50)
Sheepishly, I'm not sure where to go from here.
Edit: I will try #Caderyn's solution:
var speeds = {
x: 100, // max speed of -100 to 100 on x-axis
y: 300, // max speed of -300 to 300 on y-axis
}
var joystick = { dx: 2, dy: -3 }
console.log('joystick normalized:', normalize(joystick))
var scalar = Math.sqrt(joystick.dx*joystick.dx / speeds.x*speeds.x + joystick.dy*joystick.dy / speeds.y*speeds.y)
var scalar2 = Math.sqrt(joystick.dx*joystick.dx + joystick.dy*joystick.dy)
console.log('scalar1' , scalar) // length formula that uses max speeds
console.log('scalar2', scalar2) // regular length formula
// normalize using maxspeeds
var normalize1 = { dx: joystick.dx/scalar, dy: joystick.dy/scalar }
console.log('normalize1', normalize1, length(normalize1))
// regular normalize (no maxpseed lookup)
var normalize2 = { dx: joystick.dx/scalar2, dy: joystick.dy/scalar2 }
console.log('normalize2', normalize2, length(normalize2))
function length({dx, dy}) {
return Math.sqrt(dx*dx + dy*dy)
}
function normalize(vector) {
var {dx,dy} = vector
var len = length(vector)
return {dx: dx/len, dy: dy/len}
}
Am I missing something massive or does this give the same results as regular vector.len() and vector.normalize() that don't try to integrate the maxspeed data at all?
three solutions :
You can simply multiply each component of the input vector by it's respective speed
you can divide the vector itself by sqrt(dx^2/hSpeed^2+dy^2/vSpeed^2)
you can multiply the vector itself by sqrt((dx^2+dy^2)/(dx^2/hSpeed^2+dy^2/vSpeed^2)) or 0 if the input is (0, 0)
the second solution will preserve the vector's direction when the first will tend to pull it in the direction with the greatest max speed. But if the domain of those function is the unit disc, their image will be an ellipse whose radii are the two max speeds
EDIT : the third method does what the second intended to do: if the imput is A, it will return B such that a/b=c/d (the second method was returning C):

How to put background image to the plot in Rust plotters lib

I'm trying to draw car trips on a plane. I'm using Plotters library.
Here is some code example of trips' drawing procedure:
pub fn save_trips_as_a_pic<'a>(trips: &CarTrips, resolution: (u32, u32))
{
// Some initializing stuff
/// <...>
let root_area =
BitMapBackend::new("result.png", (resolution.0, resolution.1)).into_drawing_area();
root_area.fill(&WHITE).unwrap();
let root_area =
root_area.margin(10,10,10,10).titled("TITLE",
("sans-serif", 20).into_font()).unwrap();
let drawing_areas =
root_area.split_evenly((cells.1 as usize, cells.0 as usize));
for (index, trip) in trips.get_trips().iter().enumerate(){
let mut chart =
ChartBuilder::on(drawing_areas.get(index).unwrap())
.margin(5)
.set_all_label_area_size(50)
.build_ranged(50.0f32..54.0f32, 50.0f32..54.0f32).unwrap();
chart.configure_mesh().x_labels(20).y_labels(10)
.disable_mesh()
.x_label_formatter(&|v| format!("{:.1}", v))
.y_label_formatter(&|v| format!("{:.1}", v))
.draw().unwrap();
let coors = trip.get_points();
{
let draw_result =
chart.draw_series(series_from_coors(&coors, &BLACK)).unwrap();
draw_result.label(format!("TRIP {}",index + 1)).legend(
move |(x, y)|
PathElement::new(vec![(x, y), (x + 20, y)], &random_color));
}
{
// Here I put red dots to see exact nodes
chart.draw_series(points_series_from_trip(&coors, &RED));
}
chart.configure_series_labels().border_style(&BLACK).draw().unwrap();
}
}
What I got now on Rust Plotters:
So, after drawing it in the 'result.png' image file, I struggle to understand these "lines", because I don't see the map itself. I suppose, there is some way in this library to put a map "map.png" in the background of the plot. If I would use Python, this problem will be solved like this:
# here we got a map image;
img: Image.Image = Image.open("map-image.jpg")
img.putalpha(64)
imgplot = plt.imshow(img)
# let's pretend that we got our map size in pixels and coordinates
# just in right relation to each other.
scale = 1000
x_shift = 48.0
y_shift = 50.0
coor_a = Coordinate(49.1, 50.4)
coor_b = Coordinate(48.9, 51.0)
x_axis = [coor_a.x, coor_b.x]
x_axis = [(element-x_shift) * scale for element in x_axis]
y_axis = [coor_a.y, coor_b.y]
y_axis = [(element-y_shift) * scale for element in y_axis]
plt.plot(x_axis, y_axis, marker='o')
plt.show()
Desired result on Python
Well, that's easy on Python, but I got no idea, how to do similar thing on Rust.

Algorithm to make a route from Source Node to End Node using every node exactly once

I'm trying to create a route, given a start node and end node, that will travel to every single node in the graph, and minimize the cost of doing so.
The graph is undirected, and every node is connected to each other directly. The weight of every edge is positive. I think because every node connects to eachother, that there are many "loops" in my graph, but I don't want to generate a route with a loop in it.
So, for a graph with N nodes, I have (N*N-1) directed edges. A graph with nodes A,B,C,D would have edges:
A to B / B to A
A to C / C to A
A to D / D to A
B to C / C to B
C to D / D to C
B to D / D to B
When I implement the Floyd Warshall algorithm from Wikipedia, I only ever get an array of 2 nodes. There's a function in the article that gives you the shortest path from node U to node V, and that's the function that only returns [U,V] (array containing U and V)
I MUST be misunderstanding what it is exactly that Floyd Warshall is meant to solve. I'll attach my code to show how I've implemented it in javascript.
function colorsToEdgeMatrix(colors){
var dist = [];
for(var i = 0; i < colors.length;i++){
dist[i] = [];
var c1 = colors[i];
for(var j = 0; j < colors.length;j++){
if(i == j){continue;}
var c2 = colors[j];
dist[i][j] = colorDistance(c1,c2);
}
}
return dist;
}
function colorsToNextMatrix(colors){
var next = [];
for(var i = 0; i < colors.length;i++){
next[i] = [];
for(var j = 0; j < colors.length;j++){
if(i == j){continue;}
next[i][j] = j;
}
}
return next;
}
//lab colors
function FloydWarshallWithPathReconstruction (colors){
var next = [];
var dist = colorsToEdgeMatrix(colors);
var next = colorsToNextMatrix(colors);
var N = colors.length;
for(var k = 0; k < N; k++){ // standard Floyd-Warshall implementation
for(var i = 0; i < N; i++){
for(var j = 0; j < N; j++){
if(dist[i][k] + dist[k][j] < dist[i][j]){
dist[i][j] = dist[i][k] + dist[k][j]
next[i][j] = next[i][k]
}
}
}
}
return next;
}
function Path(next,u, v) {
var path = [];
if(next[u][v] == null){
return []
}
path = [u]
while(u != v){
u = next[u][v]
path.push(u)
}
return path;
}
var lab = randomLABArray(100); //make an array of LAB color space colors. a LAB element has an array structure [L,a,b]
lab = sortLuminosityLAB(lab); //sorts the LAB colors from light to dark
var next = FloydWarshallWithPathReconstruction(lab); //gets all paths using floyd warshall
var path = Path(next, 0, lab.length-1); //gets the path calculated from lightest to darkest
console.log( path );
Does this algorithm not necessarily return a path that goes through every node? I guess what it does is just spits out the best path for every start and end node, and doesn't guarantee any path goes through every node...
I used the Nearest Neighbor algorithm with decent result, and Brute Force is impossible after 10 elements. I was hoping the Floyd Warshall would give even better results
Huh...so this might actually be a Hamiltonian Path problem and isn't as simple as I thought...
This can be reduced to the Traveling Salesman problem as follows. Pick a large number M which is greater than the sum of all weights in the graph. Add this number to the weights on all edges in the graph except the edge connecting the start node and the end node. That edge should have its cost set to zero. Solve the resulting Traveling Salesman Problem. It is easy to see that the optimal solution of the TSP will include the edge connecting the start and end node. Throw that edge away from the optimal solution and adjust the weights back to their original value -- and you have found the optimal solution to your problem.
Conversely, the regular TSP can be reduced to your problem in an even easier way. Pick a node at random and duplicate it. Let one of these newly duplicated nodes be the start node and the other be the end node. Solve your optimal path problem for this instance. Then -- remerge these two nodes into the original node, which will splice the ends together to form a circuit, which is easily seen to be optimal. This confirms your intuition that the problem is at least as hard as the Hamiltonian circuit problem.

I'm trying to get the pixel colour for a C4 image, how do I access the image colour matrix? c4framework

In the discussion of the colour colorMatrix:bias it reads :
This filter performs a matrix multiplication, as follows, to transform the color vector:
s.r = dot(s, redVector) s.g = dot(s, greenVector) s.b = dot(s, blueVector) s.a = dot(s, alphaVector) s = s + bias
Is there any way to gain access to the data values for the various colour vectors?
The discussion you're referring to, in the C4 documentation, refers to the process that a filter uses for calculating a matrix multiplication. This is actually just a description of what the filter does to the colors in the image when it gets applied.
In fact, what's happening under the hood is that the colorMatrix: method sets up a CIFilter called CIColorMatrix and applies this to a C4Image. Unfortunately the source code for the CIColorMatrix filter isn't provided by Apple.
So, a longwinded answer to your question is:
You can't access color components for pixels in a C4Image through the CIColorMatrix filter. But, the C4Image class has a property called CGImage (e.g. yourC4Image.CGImage) which you can use to get pixel data.
A good, simple technique can be found HERE
EDIT:
I got obsessed last night with this question, and added these two methods to the C4Image class:
Method for loading pixel data:
-(void)loadPixelData {
NSUInteger width = CGImageGetWidth(self.CGImage);
NSUInteger height = CGImageGetHeight(self.CGImage);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
bytesPerPixel = 4;
bytesPerRow = bytesPerPixel * width;
rawData = malloc(height * bytesPerRow);
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), self.CGImage);
CGContextRelease(context);
}
And a method for accessing pixel color:
-(UIColor *)colorAt:(CGPoint)point {
if(rawData == nil) {
[self loadPixelData];
}
NSUInteger byteIndex = bytesPerPixel * point.x + bytesPerRow * point.y;
CGFloat r, g, b, a;
r = rawData[byteIndex];
g = rawData[byteIndex + 1];
b = rawData[byteIndex + 2];
a = rawData[byteIndex + 3];
return [UIColor colorWithRed:RGBToFloat(r) green:RGBToFloat(g) blue:RGBToFloat(b) alpha:RGBToFloat(a)];
}
That's how I would apply the techniques from the other post I mentioned.

iterative version of easy recursive algorithm

I have a quite simple question, I think.
I've got this problem, which can be solved very easily with a recursive function, but which I wasn't able to solve iteratively.
Suppose you have any boolean matrix, like:
M:
111011111110
110111111100
001111111101
100111111101
110011111001
111111110011
111111100111
111110001111
I know this is not an ordinary boolean matrix, but it is useful for my example.
You can note there is sort of zero-paths in there...
I want to make a function that receives this matrix and a point where a zero is stored and that transforms every zero in the same area into a 2 (suppose the matrix can store any integer even it is initially boolean)
(just like when you paint a zone in Paint or any image editor)
suppose I call the function with this matrix M and the coordinate of the upper right corner zero, the result would be:
111011111112
110111111122
001111111121
100111111121
110011111221
111111112211
111111122111
111112221111
well, my question is how to do this iteratively...
hope I didn't mess it up too much
Thanks in advance!
Manuel
ps: I'd appreciate if you could show the function in C, S, python, or pseudo-code, please :D
There is a standard technique for converting particular types of recursive algorithms into iterative ones. It is called tail-recursion.
The recursive version of this code would look like (pseudo code - without bounds checking):
paint(cells, i, j) {
if(cells[i][j] == 0) {
cells[i][j] = 2;
paint(cells, i+1, j);
paint(cells, i-1, j);
paint(cells, i, j+1);
paint(cells, i, j-1);
}
}
This is not simple tail recursive (more than one recursive call) so you have to add some sort of stack structure to handle the intermediate memory. One version would look like this (pseudo code, java-esque, again, no bounds checking):
paint(cells, i, j) {
Stack todo = new Stack();
todo.push((i,j))
while(!todo.isEmpty()) {
(r, c) = todo.pop();
if(cells[r][c] == 0) {
cells[r][c] = 2;
todo.push((r+1, c));
todo.push((r-1, c));
todo.push((r, c+1));
todo.push((r, c-1));
}
}
}
Pseudo-code:
Input: Startpoint (x,y), Array[w][h], Fillcolor f
Array[x][y] = f
bool hasChanged = false;
repeat
for every Array[x][y] with value f:
check if the surrounding pixels are 0, if so:
Change them from 0 to f
hasChanged = true
until (not hasChanged)
For this I would use a Stack ou Queue object. This is my pseudo-code (python-like):
stack.push(p0)
while stack.size() > 0:
p = stack.pop()
matrix[p] = 2
for each point in Arround(p):
if matrix[point]==0:
stack.push(point)
The easiest way to convert a recursive function into an iterative function is to utilize the stack data structure to store the data instead of storing it on the call stack by calling recursively.
Pseudo code:
var s = new Stack();
s.Push( /*upper right point*/ );
while not s.Empty:
var p = s.Pop()
m[ p.x ][ p.y ] = 2
s.Push ( /*all surrounding 0 pixels*/ )
Not all recursive algorithms can be translated to an iterative algorithm. Normally only linear algorithms with a single branch can. This means that tree algorithm which have two or more branches and 2d algorithms with more paths are extremely hard to transfer into recursive without using a stack (which is basically cheating).
Example:
Recursive:
listsum: N* -> N
listsum(n) ==
if n=[] then 0
else hd n + listsum(tl n)
Iteration:
listsum: N* -> N
listsum(n) ==
res = 0;
forall i in n do
res = res + i
return res
Recursion:
treesum: Tree -> N
treesum(t) ==
if t=nil then 0
else let (left, node, right) = t in
treesum(left) + node + treesum(right)
Partial iteration (try):
treesum: Tree -> N
treesum(t) ==
res = 0
while t<>nil
let (left, node, right) = t in
res = res + node + treesum(right)
t = left
return res
As you see, there are two paths (left and right). It is possible to turn one of these paths into iteration, but to translate the other into iteration you need to preserve the state which can be done using a stack:
Iteration (with stack):
treesum: Tree -> N
treesum(t) ==
res = 0
stack.push(t)
while not stack.isempty()
t = stack.pop()
while t<>nil
let (left, node, right) = t in
stack.pop(right)
res = res + node + treesum(right)
t = left
return res
This works, but a recursive algorithm is much easier to understand.
If doing it iteratively is more important than performance, I would use the following algorithm:
Set the initial 2
Scan the matrix for finding a 0 near a 2
If such a 0 is found, change it to 2 and restart the scan in step 2.
This is easy to understand and needs no stack, but is very time consuming.
A simple way to do this iteratively is using a queue.
insert starting point into queue
get first element from queue
set to 2
put all neighbors that are still 0 into queue
if queue is not empty jump to 2.

Resources