How to create a 3D vector using XYZ angles - math

So i found out how to create a vector2 in 2D using only one angle but now i need a vector3 using two or three angles
The code i used to get the 2D vector:
function V2ToForce(Angle,Force)
local Force = Force or 1
local X,Y = math.cos(Angle)*Force,math.sin(Angle)*Force
return X,Y
end
Any pseudocode would help.
Edit:
I found this formula but dosent work either
function Test(X,Y,Force)
local x = math.cos(X) * math.cos(Y);
local z = math.sin(X) * math.cos(Y);
local y = math.sin(Y);
return x*Force,y*Force,z*Force
end

Ty who commented got it to work, still has some bugs but nothing that a if statement can't solve.
Thats what i ended up with for anyone with the same problem
function Test1(X,Y,Force)
local X1 = math.cos(Y)*Force
local Y1 = (math.sin(Y)*math.sin(X))*Force
local Z1 = (-math.sin(Y)*math.cos(X))*Force
return X1,Y1,Z1
end
function Test2(X,Y,Force)
local X1 = math.cos(X) * math.cos(Y)
local Z1 = -math.sin(X) * math.cos(Y)
local Y1 = math.sin(Y)
return X*Force,Y*Force,Z1*Force
end
Sry for my bad english

Related

Plotting a 3D surface in Julia, using either Plots or PyPlot

I would like to plot a two variable function(s) (e_pos and e_neg in the code). Here, t and a are constants which I have given the value of 1.
My code to plot this function is the following:
t = 1
a = 1
kx = ky = range(3.14/a, step=0.1, 3.14/a)
# Doing a meshgrid for values of k
KX, KY = kx'.*ones(size(kx)[1]), ky'.*ones(size(ky)[1])
e_pos = +t.*sqrt.((3 .+ (4).*cos.((3)*KX*a/2).*cos.(sqrt(3).*KY.*a/2) .+ (2).*cos.(sqrt(3).*KY.*a)));
e_neg = -t.*sqrt.((3 .+ (4).*cos.((3)*KX*a/2).*cos.(sqrt(3).*KY.*a/2) .+ (2).*cos.(sqrt(3).*KY.*a)));
using Plots
plot(KX,KY,e_pos, st=:surface,cmap="inferno")
If I use Plots this way, sometimes I get an empty 3D plane without the surface. What am I doing wrong? I think it may have to do with the meshgrids I did for kx and ky, but I am unsure.
Edit: I also get the following error:
I changed some few things in my code.
First, I left the variables as ranges. Second, I simply computed the functions I needed without mapping the variables onto them. Here's the code:
t = 2.8
a = 1
kx = range(-pi/a,stop = pi/a, length=100)
ky = range(-pi/a,stop = pi/a, length=100)
#e_pos = +t*np.sqrt(3 + 4*np.cos(3*KX*a/2)*np.cos(np.sqrt(3)*KY*a/2) + 2*np.cos(np.sqrt(3)*KY*a))
e_pos(kx,ky) = t*sqrt(3+4cos(3*kx*a/2)*cos(sqrt(3)*ky*a/2) + 2*cos(sqrt(3)*ky*a))
e_neg(kx,ky) = -t*sqrt(3+4cos(3*kx*a/2)*cos(sqrt(3)*ky*a/2) + 2*cos(sqrt(3)*ky*a))
# Sort of broadcasting?
e_posfunc = e_pos.(kx,ky);
e_negfunc = e_neg.(kx,ky);
For the plotting I simply used the GR backend:
using Plots
gr()
plot(kx,ky,e_pos,st=:surface)
plot!(kx,ky,e_neg,st=:surface, xlabel="kx", ylabel="ky",zlabel="E(k)")
I got what I wanted!

How to use NLopt in Julia with equality_constraint

I'm struggling to amend the Julia-specific tutorial on NLopt to meet my needs and would be grateful if someone could explain what I'm doing wrong or failing to understand.
I wish to:
Minimise the value of some objective function myfunc(x); where
x must lie in the unit hypercube (just 2 dimensions in the example below); and
the sum of the elements of x must be one.
Below I make myfunc very simple - the square of the distance from x to [2.0, 0.0] so that the obvious correct solution to the problem is x = [1.0,0.0] for which myfunc(x) = 1.0. I have also added println statements so that I can see what the solver is doing.
testNLopt = function()
origin = [2.0,0.0]
n = length(origin)
#Returns square of the distance between x and "origin", and amends grad in-place
myfunc = function(x::Vector{Float64}, grad::Vector{Float64})
if length(grad) > 0
grad = 2 .* (x .- origin)
end
xOut = sum((x .- origin).^2)
println("myfunc: x = $x; myfunc(x) = $xOut; ∂myfunc/∂x = $grad")
return(xOut)
end
#Constrain the sums of the x's to be 1...
sumconstraint =function(x::Vector{Float64}, grad::Vector{Float64})
if length(grad) > 0
grad = ones(length(x))
end
xOut = sum(x) - 1
println("sumconstraint: x = $x; constraint = $xOut; ∂constraint/∂x = $grad")
return(xOut)
end
opt = Opt(:LD_SLSQP,n)
lower_bounds!(opt, zeros(n))
upper_bounds!(opt,ones(n))
equality_constraint!(opt,sumconstraint,0)
#xtol_rel!(opt,1e-4)
xtol_abs!(opt,1e-8)
min_objective!(opt, myfunc)
maxeval!(opt,20)#to ensure code always terminates, remove this line when code working correctly?
optimize(opt,ones(n)./n)
end
I have read this similar question and documentation here and here, but still can't figure out what's wrong. Worryingly, each time I run testNLopt I see different behaviour, as in this screenshot including occasions when the solver uselessly evaluates myfunc([NaN,NaN]) many times.
You aren't actually writing to the grad parameters in-place, as you write in the comments;
grad = 2 .* (x .- origin)
just overrides the local variable, not the array contents -- and I guess that's why you see these df/dx = [NaN, NaN] everywhere. The simplest way to fix that would be with broadcasting assignment (note the dot):
grad .= 2 .* (x .- origin)
and so on. You can read about that behaviour here and here.

Find specific point between 2 points - three.js

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)
}

Function is circle within circle and correction?

I am trying to implement a mathematical procedure to ensure that a circle c1 is completely inside another circle c2.
It should work the following way:
Given c1(x, y, r) and c2(x, y, r) and c2.r>c1.r
return true if c1 is inside c2
return a vector V(x,y) being the minimum correction to apply to c1 so it is inside c2.
How does it look to you? should be easy for a mathematician or a physicist but it's quite hard for me.
I already tried an implementation in lua, but there's definitely something wrong on it.
local function newVector(P1, P2)
local w, h=(P2.x-P1.x), (P2.y-P1.y)
local M=math.sqrt(w^2 + h^2)
local alpha=math.atan(h/w)
return {m=M, alpha=alpha}
end
local function isWithin(C1, C2)
local V12=newVector(C1, C2)
local R12=C2.r-C1.r
local deltaR=R12-V12.m
if deltaR>=0 then
return true
else
local correctionM=(V12.m+deltaR) --module value to correct
local a=V12.alpha
print("correction angle: "..math.deg(a))
local correctionX=correctionM*math.cos(a)
local correctionY=correctionM*math.sin(a)
return {x=correctionX, y=correctionY}
end
end
Thanks!
Isn't it enough to check that distance(Center1, Center2) + Radius1 <= Radius2 ?
local function isWithin(C1, C2)
local distance = math.sqrt((C1.x-C2.x)^2+(C1.y-C2.y)^2)
return distance + C1.r <= C2.r + Epsilon
Epsilon is used in order to avoid numerical errors. (e.g. Epsilon = 1e-9)
Sounds easy this way.
Ok, finally I have it working fine.
The key was to use math.atan2 as lhf suggested. And I had some numerical mistake in the correction value.
Here's the final code. I have also included the circleFromBounds function that I use to create the circles from any corona display object.
local function newVector(P1, P2)
local w, h=(P2.x-P1.x), (P2.y-P1.y)
local M=math.sqrt(w^2 + h^2)
local alpha=math.atan2(h, w)
return {m=M, alpha=alpha}
end
local function isWithin(C1, C2)
local V12=newVector(C1, C2)
local epsilon = 10^(-9)
if (V12.m + C1.r <= C2.r + epsilon) then
return true
else
local correctionM=(C2.r-(C1.r+V12.m)) --module value to correct
local A=V12.alpha
local correctionX=correctionM*math.cos(A)
local correctionY=correctionM*math.sin(A)
return {x=correctionX, y=correctionY}
end
end
local function circleFromBounds(bounds, type)
local x, y, r
local width, height = (bounds.xMax-bounds.xMin), (bounds.yMax-bounds.yMin)
local ratio=width/height
x=bounds.xMin+width*.5
y=bounds.yMin+height*.5
if "inner"==type then
if ratio>1 then
r=height*.5
else
r=width*.5
end
elseif "outer"==type then
local c1, c2 = width*.5, height*.5
r = math.sqrt(c1^2 + c2^2)
end
return {x=x, y=y, r=r}
end
Thanks for your help!

trapezodial integral matlab

I want to use instead of matlab integration command, a basic self created one. Do you have any Idea how to fix the error? If I use Matlab quad command, my algorithm works good but when I try to use my self created integral function,not suprisingly for sure, it does not work:(
M-File:
function y = trapapa(low, up, ints, fun)
y = 0;
step = (up - low) / ints;
for j = low : step : up
y = y + feval(fun,j);
end
y = (y - (feval(fun, low) + feval(fun, up))/2) * step;
Mean algorithm:
clear;
x0=linspace(0,4,3);
y=linspace(0,2,3);
for i=1:length(x0)
for j=1:length(y)
x(i,j)=y(j)+x0(i);
alpha=#(rho)((5-2*x(i,j)).*exp(y(j)-rho))./2;
%int(i,j)=quad(alpha,0,y(j))
int(i,j)=trapapa(alpha,0,y(j),10)
end
end
You are not following your function definition in the script. The fun parameter (variable alpha) is supposed to be the last one.
Try int(i,j)=trapapa(0,y(j),10,alpha)

Resources