How can I write code that makes a spiral? - vba

I just started learning to programming in Excel VBA, and I have a problem.
I want to draw a spiral with a program, but a can not solve it well.
I would like to use for and do until and do while cycles only.
Here is my code:
Sub spiral()
For i = 1 To 16
xmm = xmm - 1
ymm = ymm - 1
Do Until xp = i
xp = xp + 1
Cells(5 + xp, 5) = i
Loop
Do Until yp = i
yp = yp + 1
Cells(5 + xp, 5 + yp) = i + 1
Loop
Do Until xm > xp
xm = xm + 1
Cells(5 + xp + i * xmm, 5 + yp) = i + 2
Loop
Do Until ym > yp
ym = ym + 1
Cells(5 + xp + xmm, 5 + yp + i * ymm) = i + 3
Loop
Next i
End Sub
Thanks!

I can't think of any practical reason you'd need this, but that said, I'm often wasting time messing around with odd tasks "just to see if I can." 😊
Access VBA Circles
Recently a spiral was a self-assigned challenge I played with in SQL, although it originated with a circle in Access VBA from another useless project of mine:
Access World : Making an Analog Clock on an MS Access Form
This taught me a number of concepts including how to draw a circle on a grid.
Drawing a circle is almost the identical process as drawing the hands on that clock. If, rather than drawing the whole line of the clock hand, I instead draw only the tip of it (aka, the radius), all the way around, the 360°, then I have a circle.
SQL Circle
Say that ten times fast!
Then one day I wondered how hard it would be to convert the circle code to SQL Server, exploiting the graphing feature of the Stack Exchange Data Explorer (SEDE). A graph is drawn on a grid, so it's the same concept.
Here is one of several results (again, all useless):
SEDE : Draw Random Circles on chart
Click Run Query and then when it's finished calculating click the Graph tab. (You'll also need to either login with your Stack Exchange ID, or do the captcha.) There are various constants you can play with in the user prompts (below the SQL).
SQL Spiral
Then at some point I wondered about spirals.
(...but probably should have been time for me to get a life? Naaaa, lol)
A spiral is simply a modified circle except the radius decreases (or increases) as you progress around the circumference -- and you don't stop at 360° -- instead just keep going and going, and continually changing the radius at a steady rate.
SEDE : Draw a spiral
Again, click Run Query and then when it's finished calculating click the Graph tab. (You'll also need to either login with your Stack Exchange ID, or do the captcha.) There are various constants you can play with in the user prompts (below the SQL).
Spiral in Excel
I'm not going to waste any more time on spirals today, but if I was going to draw one in Excel worksheet cells, I would resize all cells on the worksheet to a tiny square grid (maybe width=1, height=10), and then I would borrow the code from the SQL example, adapting it to Excel (which woudn't take much work).
The Access VBA example may be more confusing to adapt since there a lot of programmatic manipulation of controls going on (which can't be done at runtime).
Or, the Access example could be duplicated in Excel using controls (ie., lines) instead of the grid method you were trying so far.
More Information:
Wikipedia : Midpoint Circle Algorithm
rosettacode : Midpoint circle algorithm examples (code in 39 languages)
tutsPlus.com : Working with circles/spirals
Math Overflow : How to spiral coordinates in an outward pattern on 2D grid?

Base on some answers from this thread (Looping in a spiral), I've managed to come with this solution
Sub spiral()
x = 0
y = 0
d = 1
m = 1
i = 1
j = 1
Do While i < 6
Do While 2 * x * d < m
Cells(x + 5, y + 5).Value = j
x = x + d
j = j + 1
Loop
Do While 2 * y * d < m
Cells(x + 5, y + 5).Value = j
y = y + d
j = j + 1
Loop
d = -1 * d
m = m + 1
i = i + 1
Loop
End Sub
Not sure if it is something that you are looking for thou, as you didn't specify the exact output that you want to achieve.

Related

Are calculations involving a large matrix using arrays in VBA faster than doing the same calculation manually in Excel?

I am trying to do calculations as part of regression model in Excel.
I need to calculate ((X^T)WX)^(-1)(X^T)WY. Where X, W, Y are matrices and ^T and ^-1 are denoting the matrix transpose and inverting operation.
Now when X, W, Y are of small dimensions I simply run my macro which calculates these values very very fast.
However sometimes I am dealing with the case when say, the dimensions of X, W, Y are 5000 X 5, 5000 X 1 and 5000 X 1 respectively, then the macro can take a lot longer to run.
I have two questions:
Would, instead of using my macro which generates the matrices on Excel sheets and then uses Excel formulas like MMULT and MINVERSE etc. to calculate the output, it be faster for larger dimension matrices if I used arrays in VBA to do all the calculations? (I am not too sure how arrays work in VBA so I don't actually know if it would do anything to excel, and hence if it would be any quicker/less computationally intensive.)
If the answer to the above question is no it would be no quicker. Then does anybody have an idea how to speed such calculations up? Or do I need to simply put up with it and wait.
Thanks for your time.
Considering that the algorithm of the code is the same, the speed ranking is the following:
Dll custom library with C#, C++, C, Java or anything similar
VBA
Excel
I have compared a VBA vs C++ function here, in the long term the result is really bad for VBA.
So, the following Fibonacci with recursion in C++:
int __stdcall FibWithRecursion(int & x)
{
int k = 0;
int p = 0;
if (x == 0)
return 0;
if (x == 1)
return 1;
k = x - 1;
p = x - 2;
return FibWithRecursion(k) + FibWithRecursion(p);
}
is exponentially better, when called in Excel, than the same complexity function in VBA:
Public Function FibWithRecursionVBA(ByRef x As Long) As Long
Dim k As Long: k = 0
Dim p As Long: p = 0
If (x = 0) Then FibWithRecursionVBA = 0: Exit Function
If (x = 1) Then FibWithRecursionVBA = 1: Exit Function
k = x - 1
p = x - 2
FibWithRecursionVBA = FibWithRecursionVBA(k) + FibWithRecursionVBA(p)
End Function
Better late than never:
I use matrices that are bigger, 3 or 4 dimensions, sized like 16k x 26 x 5.
I run through them to find data, apply one or two formulas or make combos with other matrices.
Number one, after starting the macro, open another application like notepad, you might have a nice speed increase ☺ !
Then, I guess you switched of screen updating etc, and turned of automatic calculation
As last: don't put the data in cells, not in arrays.
Just something like:
Dim Matrix1 as String ===>'put it in declarations if you want to use it in other macros as well. Remember you can not do "blabla=activecell.value2" etc anymore!!
In the "Sub()" code, use ReDim Matrix1(1 to a_value, 1 to 2nd_value, ... , 1 to last_value)
Matrix1(45,32,63)="what you want to put there"
After running, just drop the
Matrix1(1 to a_value, 1 to 2nd_value,1) at 1st sheet,
Matrix1(1 to a_value, 1 to 2nd_value,2) at 2nd sheet, etc
Switch on screen updating again, etc
In this way my calculation went from 45 minutes to just one, by avoiding the intermediary screen update
Success, I hope it is useful for somebody

What is faster to calculate: Large looped calculations or Vlookup on multiple large data grids?

This is a conceptual question that will help me before I start coding my next project. Which approach do you think will be faster?
Loop Calculations: An example of how it would be set up:
for i = 0 to 67
While x < 350
y = 0
While y < 600
Call solved() 'solves and returns "concentration"
If c(y, x) <> Empty = True Then
c(y, x) = c(row, x) + concentration
Else
c(y, x) = concentration
End If
y = y + 1
Wend
x = x + 1
Wend
Next i
Vlookup:
Using Matlab I can generate millions of solved data points and store them into a matrix. This can be stored in a database.
Restrictions: Only Access available as a database. and with the amount of data needed to be stored it will hit memory limit. Excel is not a good idea to store this much data as well.
Taking the restriction into account, I have thought of using multiple text files to store data and use Excel to search and pull values.
Theoretically, a search should be faster. But with different files to open up and a large matrix to look through, the speed will be affected. What do you guys think, and please input if there is a better approach. Thanks!

Calculating Collision Times Between Two Circles - Physics

I keep stumbling into game/simulation solutions for finding distance while time is running, and it's not what I'm looking for.
I'm looking for an O(1) formula to calculate the (0 or 1 or 2) clock time(s) in which two circles are exactly r1+r2 distance from each other. Negative time is possible. It's possible two circles don't collide, and they may not have an intersection (as in 2 cars "clipping" each other while driving too close to the middle of the road in opposite directions), which is messing up all my mx+b solutions.
Technically, a single point collision should be possible.
I'm about 100 lines of code deep, and I feel sure there must be a better way, and I'm not even sure whether my test cases are correct or not. My initial setup was:
dist( x1+dx1*t, y1+dy1*t, x2+dx2*t, y2+dy2*t ) == r1+r2
By assuming the distance at any time t could be calculated with Pythagoras, I would like to know the two points in time in which the distance from the centers is precisely the sum of the radii. I solved for a, b, and c and applied the quadratic formula, and I believe that if I'm assuming they were phantom objects, this would give me the first moment of collision and the final moment of collision, and I could assume at every moment between, they are overlapping.
I'm working under the precondition that it's impossible for 2 objects to be overlapping at t0, which means infinite collision of "stuck inside each other" is not possible. I'm also filtering out and using special handling for when the slope is 0 or infinite, which is working.
I tried calculating the distance when, at the moment object 1 is at the intersection point, it's distance from object 2, and likewise when o2 is at the intersection point, but this did not work as it's possible to have collision when they are not at their intersection.
I'm having problems for when the slopes are equal, but different magnitude.
Is there a simple physics/math formula for this already?
Programming language doesn't matter, pseudcode would be great, or any math formula that doesn't have complex symbols (I'm not a math/physics person)... but nothing higher order (I assume python probably has a collide(p1, p2) method already)
There is a simple(-ish) solution. You already mentioned using the quadratic formula which is a good start.
First define your problem where the quadratic formula can be useful, in this case, distance between to centers, over time.
Let's define our time as t
Because we are using two dimensions we can call our dimensions x & y
First let's define the two center points at t = 0 of our circles as a & b
Let's also define our velocity at t = 0 of a & b as u & v respectively.
Finally, assuming a constant acceleration of a & b as o & p respectively.
The equation for a position along any one dimension (which we'll call i) with respect to time t is as follows: i(t) = 1 / 2 * a * t^2 + v * t + i0; with a being constant acceleration, v being initial velocity, and i0 being initial position along dimension i.
We know the distance between two 2D points at any time t is the square root of ((a.x(t) - b.x(t))^2 + (a.y(t) - b.y(t))^2)
Using the formula of position along a dimensions we can substitute everything in the distance equation in terms of just t and the constants we defined earlier. For shorthand we will call the function d(t);
Finally using that equation, we will know that the t values where d(t) = a.radius + b.radius are where collision starts or ends.
To put this in terms of quadratic formula we move the radius to the left so we get d(t) - (a.radius + b.radius) = 0
We can then expand and simplify the resulting equation so everything is in terms of t and the constant values that we were given. Using that solve for both positive & negative values with the quadratic formula.
This will handle errors as well because if you get two objects that will never collide, you will get an undefined or imaginary number.
You should be able to translate the rest into code fairly easily. I'm running out of time atm and will write out a simple solution when I can.
Following up on #TinFoilPancakes answer and heavily using using WolframAlpha to simplify the formulae, I've come up with the following pseudocode, well C# code actually that I've commented somewhat:
The Ball class has the following properties:
public double X;
public double Y;
public double Xvel;
public double Yvel;
public double Radius;
The algorithm:
public double TimeToCollision(Ball other)
{
double distance = (Radius + other.Radius) * (Radius + other.Radius);
double a = (Xvel - other.Xvel) * (Xvel - other.Xvel) + (Yvel - other.Yvel) * (Yvel - other.Yvel);
double b = 2 * ((X - other.X) * (Xvel - other.Xvel) + (Y - other.Y) * (Yvel - other.Yvel));
double c = (X - other.X) * (X - other.X) + (Y - other.Y) * (Y - other.Y) - distance;
double d = b * b - 4 * a * c;
// Ignore glancing collisions that may not cause a response due to limited precision and lead to an infinite loop
if (b > -1e-6 || d <= 0)
return double.NaN;
double e = Math.Sqrt(d);
double t1 = (-b - e) / (2 * a); // Collison time, +ve or -ve
double t2 = (-b + e) / (2 * a); // Exit time, +ve or -ve
// b < 0 => Getting closer
// If we are overlapping and moving closer, collide now
if (t1 < 0 && t2 > 0 && b <= -1e-6)
return 0;
return t1;
}
The method will return the time that the Balls collide, which can be +ve, -ve or NaN, NaN means they won't or didn't collide.
Further points to note are, we can check the discriminant against <zero to bail out early which will be most of the time, and avoid the Sqrt. Also since I'm using this in a continuous collision detection system, I'm ignoring collisions (glancing) that will have little or no impact since it's possible the response to the collision won't change the velocities and lead to the same situation being checked infinitely, freezing the simulation.
The 'b' variable can used for this check since luckily it's similar to the dot product. If b is >-1e-6 ie. they're not moving closer fast enough we return NaN, ie. they don't collide. You can tweak this value to avoid freezes, smaller will allow closer glancing collisions but increase the chance of a freeze when they happen like when a bunch of circles are packed tightly together. Likewise to avoid Balls moving through each other we signal an immediate collison if they're already overlapping and moving closer.

I need some help on designing a program that will perform a minimization using VBA Excel

How do I use Excel VBA to find the minimum value of an equation?
For example, if I have the equation y = 2x^2 + 14, and I want to make a loop that will slowly increase/decrease the value of x until it can find the smallest value possible for y, and then let me know what the corresponding value of x is, how would I go about doing that?
Is there a method that would work for much more complicated equations?
Thank you for your help!
Edit: more details
I'm trying to design a program that will find a certain constant needed to graph a nuclear decay. This constant is a part of an equation that gets me a calculated decay. I'm comparing this calculated decay against a measured decay. However, the constant changes very slightly as the decay happens, which means I have to use something called a residual-square to find the best constant to use that will fit the entire decay best to make my calculated decay as accurate as possible.
It works by doing (Measured Decay - Calculated Decay) ^2
You do that for the decay at several times, and add them all up. What I need my program to do is to slowly increase and decrease this constant until I can find a minimum value for the value I get when I add up the residual-squared results for all the times using this decay. The residual-squared that has the smallest value has the value of the constant that I want.
I already drafted a program that does all the calculations and such. I'm just not sure how to find this minimum value. I'm sure if a method works for something like y = x^2 + 1, I can adapt it to work for my needs.
Test the output while looping to look for the smallest output result.
Here's an Example:
Sub FormulaLoop()
Dim x As Double
Dim y As Double
Dim yBest As Double
x = 1
y = (x ^ 2) + 14
yBest = y
For x = 2 To 100
y = (x ^ 2) + 14
If y < yBest Then
yBest = y
End If
Next x
MsgBox "The smallest output of y was: " & yBest
End Sub
If you want to loop through all the possibilities of two variables that make up x then I'd recommend looping in this format:
Sub FormulaLoop_v2()
Dim MeasuredDecay As Double
Dim CalculatedDecay As Double
Dim y As Double
Dim yBest As Double
MeasuredDecay = 1
CalculatedDecay = 1
y = ((MeasuredDecay - CalculatedDecay) ^ 2) + 14
yBest = y
For MeasuredDecay = 2 To 100
For CalculatedDecay = 2 To 100
y = ((MeasuredDecay - CalculatedDecay) ^ 2) + 14
If y < yBest Then
yBest = y
End If
Next CalculatedDecay
Next MeasuredDecay
MsgBox "The smallest output of y was: " & yBest
End Sub

angle for particular co-ordinate in projectile path?

I have xy co-ordinate like (200,200). I know the angle calculation from the origin the ball throws. How can I find the initial velocity to reach that particular xy co-ordinate when ball is thrown in 2d Environment?
Iam using
x = v0cosq0t;
y = v0sinq0t - (1/2)gt2.
but time is needed. Without time can I do it? any help please?
I'm assuming that you want the ball to hit that specific point (200,200) at the apex of its path. Well, my physics is a bit rusty, but this is what I've thrown together:
v_y = square_root(2*g*y),
where g is a positive number reflecting the acceleration due to gravity, and y being how high you want to go (200 in this case).
v_x = (x*g) / v_y,
where x is how far in the x direction you want to go (200 in this case), g is as before, and Vy is the answer we got in the previous equation.
These equations remove the need for an angle. However, if you'd rather have the velocity + angle, that's simple:
v0 = square_root(v_x^2 + v_y^2)
and
angle = arctan(v_y / v_x).
Here is the derivation, if you're interested:
(1/2)at^2 + v_yt + 0 = y
(1/2)at^2 + v_yt - y = 0
by quadratic formula,
t = (-v_y +/- square_root(v_y^2 - 2ay)) / a
we also have another equation, because at the apex the vertical velocity is 0:
0 = v_y + at
substitute:
0 = v_y + (-v_y +/- square_root(v_y^2 - 2ay))
0 = square_root(v_y^2 - 2ay)
0 = v_y^2 - 2ay
v_y = square_root(-2ay), or
v_y = square_root(2gy)
For v_x:
v_x*t = x
from before, t = v_y / a, so
v_x = (x*g)/v_y
I hope that made enough sense.
Im sure you can assume the velocity change is instantaneous. Games physics always has some 'dodgy' parts in it because it is too computationally expensive or not important enough to get right down the low granularity information.
You can start the velocity ass instantaneous, and then using a timer class to measure then time between each frame (very rough way of doing it), or you can have a timer class set up in an update loop that will update the physics every x seconds.