Here is a povray code that I am trying to digest:
#include "colors.inc"
camera {
location <4, 0, -10>
look_at <4, 0, 0>
}
background{White}
light_source { <10, 10, 5> color White}
light_source { <0, 20, 0> color White}
//********************** Turtle Position ****************************
// These represent the position and angle of the turtle
#declare cylinderWidth=.1;
#declare locx = 0;
#declare locy = 0;
#declare myAngle = 0;
//************************* Macros **********************************
// This is a macro that moves the turtle forward by a distance s.
#macro kmove(s)
#declare locx_new = locx + s*cos(radians(myAngle));
#declare locy_new = locy + s*sin(radians(myAngle));
cylinder { <locx, locy, 0>, <locx_new, locy_new, 0>, s*cylinderWidth}
#declare locx = locx_new;
#declare locy = locy_new;
#end
// This is a macro that is recursive for moving the turtle around.
#macro koch(s, recursion_depth)
#if (recursion_depth > 0)
union {
object { koch(s/3, recursion_depth-1) }
object {
#declare myAngle = myAngle + 60;
koch(s/3, recursion_depth-1)
}
object {
#declare myAngle = myAngle -120;
koch(s/3, recursion_depth-1)
}
object {
#declare myAngle = myAngle + 60;
koch(s/3, recursion_depth-1)
}
}
#else
kmove(s);
#end
#end
//************************* Parameters **********************************
// This sets the number of levels of recursion
#declare myDepth = 0;
// This is the distance along x that the turtle moves.
#declare mySize = 8;
//*********************** DRAW THE TURTLE!! *******************************
// This is the command for actually drawing the Turtle's path based in the
// distance and levels of recursion.
object{
koch(mySize,myDepth)
pigment { color Blue }
}
What I do not understand is the macro 'koch' that involves the if statement. How does it make cylinders, as it does not involve the function kmove(s). It appears that every iteration makes three line segments, each of which have length s/3; and then it rotates them through some angle. But how does it do this, when it does not even involve kmove(s)?
Also, why aren't there any translate commands? Wouldn't every iteration produce line segments that overlap?
EDIT: Obviously, I ran the code before making this post, and it does in fact work. However, as it is obvious from what I have said above, I would like to understand how this code works.
How does it make cylinders, as it does not involve the function kmove(s).
It does involve the macro kmove in the #else branch, which serves as recursion terminator here.
why aren't there any translate commands
The location of the cylinder is controlled directly during its creation:
cylinder { <locx, locy, 0>, <locx_new, locy_new, 0>, s*cylinderWidth}
As the locx and locy variables are used (which are updated every time kmove is invoked!), the cylinders are placed at different positions.
To understand what happens here, try doing by hand what the POV-Ray parser does, i.e. replacing the macro invokations with the body of the same macro, inserting the values of the actual parameters where the formal parameters are referenced, deleting if-then-else cases whose conditions are not met etc.; eventually this should result in koch(mySize,myDepth) being reduced to a sequence of kmove bodies, i.e. a sequence of
#declare locx_new = locx + s*cos(radians(myAngle));
#declare locy_new = locy + s*sin(radians(myAngle));
cylinder { <locx, locy, 0>, <locx_new, locy_new, 0>, s*cylinderWidth}
#declare locx = locx_new;
#declare locy = locy_new;
with actual values instead of s formal parameter references. Note that by tracing the values of the loc and angle variables over this (non-recursive) sequence you can even get rid of their references with the sequence resulting in one of
cylinder { <locx, locy, 0>, <locx_new, locy_new, 0>, s*cylinderWidth}
declarations (of course with references replaced by values again).
Related
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):
Please help me understand how the following code always returns the smallest value in the array. I tried moving position of 3 but it always manages to return it irrespective of the position of it in the array.
let myA = [12,3,8,5]
let myN = 4
function F4(A,N)
{
if(N==1){
return A[0]
}
if(F4(A,N-1) < A[N-1]){
return F4(A,N-1)
}
return A[N-1]
}
console.log(F4(myA,myN))
This is quite tricky to get an intuition for. It's also quite important that you learn the process for tackling this type of problem rather than simply be told the answer.
If we take a first view of the code with a few comments and named variables it looks like this:
let myA = [12,3,8,5];
let myN = myA.length;
function F4(A, N) {
// if (once) there is only one element in the array "A", then it must be the minimum, do not recurse
if (N === 1){
return A[0]
}
const valueFromArrayLessLastEl = F4(A,N-1); // Goes 'into' array
const valueOfLastElement = A[N-1];
console.log(valueFromArrayLessLastEl, valueOfLastElement);
// note that the recursion happens before min(a, b) is evaluated so array is evaluated from the start
if (valueFromArrayLessLastEl < valueOfLastElement) {
return valueFromArrayLessLastEl;
}
return valueOfLastElement;
}
console.log(F4(myA, myN))
and produces
12 3 // recursed all the way down
3 8 // stepping back up with result from most inner/lowest recursion
3 5
3
but in order to gain insight it is vital that you approach the problem by considering the simplest cases and expand from there. What happens if we write the code for the cases of N = 1 and N = 2:
// trivially take N=1
function F1(A) {
return A[0];
}
// take N=2
function F2(A) {
const f1Val = F1(A); // N-1 = 1
const lastVal = A[1];
// return the minimum of the first element and the 2nd or last element
if (f1Val < lastVal) {
return f1Val;
}
return lastVal;
}
Please note that the array is not being modified, I speak as though it is because the value of N is decremented on each recursion.
With myA = [12, 3, 8, 5] F1 will always return 12. F2 will compare this value 12 with 3, the nth-1 element's value, and return the minimum.
If you can build on this to work out what F3 would do then you can extrapolate from there.
Play around with this, reordering the values in myA, but crucially look at the output as you increase N from 1 to 4.
As a side note: by moving the recursive call F4(A,N-1) to a local constant I've prevented it being called twice with the same values.
I come from OOP background (C#/Java to be specific) and I really do not understand how R treat the variable from outside the function.
I made this example:
result = list();
result$total = 0;
result$count = 0;
result$something = "abc";
a = 1:10;
b = 10:20;
mapply(function(x, y) {
print(result$something);
# Does not work with either = or <--
result$total <-- result$total + x + y;
result$count <-- result$count + 1;
print(result$count);
}, x = a, y = b);
result$average = result$total / result$count;
print(result$total);
print(result$count);
print(result$average);
Here, clearly result is available to the anonymous function because the program did print "abc" 10 times.
However, the change to its component total and count does not survive. 10 times it prints 1 for the result$count, and the final 3 lines are 0, 0 and NaN.
Why is this happening? What should I do in this case, if I want the function to be able to change the variable value?
Note: in my real case, result is NOT a global variable, but is inside another function, and I will use return (result) from the function.
I'm extracting the min from a vector.
Say vector = [0, inf, inf, inf];
ExtractSmallest(vector) = 0;
and then vector = [0, 1, inf, inf];
but now, we've already seen 0. Thus,
ExtractSmallest(vector) = 1;
I represent this in my code by doing nodes.erase(nodes.begin() + smallestPosition);
But, I now realize that erasing is very bad. Is there a way to achieve this without erasing the vectors? Just skipping over the ones we've already seen?
Node* CGraph::ExtractSmallest(vector<Node*>& nodes)
{
int size = nodes.size();
if (size == 0) return NULL;
int smallestPosition = 0;
Node* smallest = nodes.at(0);
for (int i=1; i<size; ++i)
{
Node* current = nodes.at(i);
if (current->distanceFromStart <
smallest->distanceFromStart)
{
smallest = current;
smallestPosition = i;
}
}
nodes.erase(nodes.begin() + smallestPosition);
return smallest;
}
Option 1 You can have an additional vector<bool> on which you iterate in parallel. When you find the smallest element, mark that position in the bool vector as true. Whenever you iterate, skip the positions in both vectors that are marked as true.
Option 2 If order is not important, keep the number of elements removed so far. When you find the minimum, swap positions with the first non-excluded element. On a new iteration, start from the first non-excluded element.
Option 3 If order is not important, sort the array. (this takes O(n*log(n))). Removal will now take O(1) - you just exclude the first non-excluded element.
Option 4 If there are no duplicates, you can keep a std::set on the side with all excluded elements to this point. When you iterate, check whether the current element was already excluded or not.
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.