I am wondering if anyone could tell me the coding in mathematica. I have the Maple coding as follow:
with(Optimization):
objectiveFunction := 0.30x1 + 0.15x2
N: = 0.04x1 + 0.08x2 >= 25.4
P: = 0.08x1 + 0.04x2 >= 26.4
Solve(N,x2)
Solve(P,x2)
Plot([-0.5x1 + 320, -2x1 + 960], x1 = 200..1500, x2 = -200...1500)
You can set up the objective function and constraints almost as an in Maple, except that your symbols shouldn't start with capital letters, as those are reserved for Mathematica keywords, line N:
objectiveFunction = 0.30 x1 + 0.15 x2;
n = 0.04 x1 + 0.08 x2 >= 25.4;
p = 0.08 x1 + 0.04 x2 >= 26.4;
Then you can simply pass those to FindMinimum
{objectiveValue, solution} = FindMinimum[{objectiveFunction, n, p}, {x1, x2}]
Out[...] = {99., {x1 -> 228.333, x2 -> 203.333}}
(you can also use NMinimize; FindMinimum uses local, gradient based optimization methods like Newton's, NMinimize attempts global optimization. In this case, both functions should figure out that it's a linear programming problem.)
I'm not sure what your plot is doing, but I can try to visualize the result:
Show[
ContourPlot[objectiveFunction, {x1, 200, 1500}, {x2, -200, 1500}],
RegionPlot[n && p, {x1, 200, 1500}, {x2, -200, 1500},
PlotStyle -> Directive[White, Opacity[0.2]],
BoundaryStyle -> Directive[Red, Dashed]],
Graphics[{Red, PointSize[Large], Point[{x1, x2} /. solution]}]]
Related
I am coding a game in Unity that number of your soldiers are increasing/decreasing by some triggers. I want to position my soldier objects like a full circle, so they will always be near each other(like same distances) even if their number is increasing or decreasing. How can I manage this?
You can start with some simple relatively ordered distribution of positions and by applying a dynamical system approach/gradient decent type iteration, you can let the positions converge to a much more structured pattern. I wrote such implementation in python, it is in vectorized form, but I also added an equivalent function with for loops, to illustrate the structure of the function. The final ordered pattern is inspired by the stable equilibrium position that a bunch of discs of same radius r would form if they are hold by springs, one for every two of them. To ease up the computations, I squared the spring tensions, thus avoiding square roots, so not exactly like the typical physics model, but close to it.
import numpy as np
import matplotlib.pyplot as plt
def Grad(pos, r):
Dq = - pos[:, :, np.newaxis] + pos[:, np.newaxis, :]
D = Dq[0,:,:]*Dq[0,:,:] + Dq[1,:,:]*Dq[1,:,:] + np.identity(Dq.shape[1])
Dq = (1 - r**2 / D) * Dq
return - Dq.sum(axis=2)
def Grad_flow(q_, r, step):
Q = q_
n_iter = 0
while True:
n_iter = n_iter + 1 # you can count the number of iterations needed to reach the equilibrium
Q_prev = Q
Q = Q - step * Grad(Q, r)
if np.sum(np.abs((Q.T).dot(Q) - (Q_prev.T).dot(Q_prev))) < 1e-5:
return Q
'''
Test:
'''
p = np.array([[-3, 3], [-1, 3], [1,3], [3,3],
[-3, 1], [-1, 1], [1,1], [3,1],
[-3,-1], [-1,-1], [1,-1], [3,-1],
[-3,-3], [-1, -3], [1, -3], [3,-3],
[-2, 1], [-1,2],[2,-2], [-2,-2],
[2,2], [2,0]]).T
r = 0.5
step = 0.01
q = Grad_flow(p, r, step)
'''
Plot:
'''
fig, axs = plt.subplots(1,1)
axs.set_aspect('equal')
axs.plot(q[0,:], q[1,:], 'ro')
axs.plot(p[0,:], p[1,:], 'bo')
plt.grid()
plt.show()
You start from the blue positions and you make them converge to the red positions:
Here is the loop version of the Grad function:
def Grad(pos, r):
grad = np.zeros(pos.shape, dtype=float)
for i in range(pos.shape[1]):
for j in range(pos.shape[1]):
if not i==j:
d_pos_0 = pos[0, i] - pos[0, j]
d_pos_1 = pos[1, i] - pos[1, j]
m = d_pos_0*d_pos_0 + d_pos_1*d_pos_1
m = 1 - r*r / m
grad[0, i] = grad[0, i] + m * d_pos_0
grad[1, i] = grad[1, i] + m * d_pos_1
return grad
Of course, all of this is a bit heuristic and I cannot promise full generality, so you have to play and select the parameters r which is half-distance between positions, iteration step-size step, the initial position p and so on.
Supposing you are working in the horizontal plane, you can define you much rotation for each of your soldiers, and the find that point in the plane converting cartesian coordinates (x, y) into polar ones (R, fi), add theta to fi and then convert back to cartesian:
// Rotate B around A by angle theta
private (float x, float y) Rotate(
(float x, float y) A,
(float x, float y) B,
float theta) {
float fi = Math.Atan2(B.y - A.y, B.x - A.x) + theta;
float R = Math.Sqrt((A.y - B.y) * (A.y - B.y) + (A.x - B.x) * (A.x - B.x));
return (A.x + R * Math.Cos(fi), A.y + R * Math.Sin(fi));
}
Another option that does exactly the same thing, but not using polar coords:
// Rotate B around A by angle theta clockwise
private (float x, float y) Rotate(
(float x, float y) A,
(float x, float y) B,
float theta)
{
float s = Math.Sin(theta);
float c = Math.Cos(theta);
// translate point back to origin:
B.x -= A.x;
B.y -= A.y;
// rotate point clockwise
float xnew = B.x * c - B.y * s;
float ynew = B.x * s + B.y * c;
// translate point back:
B.x = xnew + A.x;
B.y = ynew + A.y;
return B;
}
If you want your soldiers equally distributed in a circle you would need to calcualte the rotation angle of each just with float angle = 360 / numSoldiers;.
If your game is in 3d and you are working in the floor plane (XZ) you can change the .ys by .zs in the code.
You can also check how the algorithms work in a simple unity project cubes or in a console c# app to understand them and to check how they just perform the rotation of a vector's end point around its origin to return the rotated point. I think that is what you would need to find the points of interest for the position of your soldiers.
I am going to have a n-dimensional function and I would like to able plot 2D planes for the rest of the variables fixed to a number. For example:
u = w^2 y^3 + x^5 z^4 + I z^6 + I z^2 Sin[y + x - 1]+k*Sin[w*pi]
I have 5 variables in here and lets assume I want to fix z w plane and plot with sliding y,z, and k. I have many issues to fix to get what I want to do,
1- As it is the code is not working. I need to figure out to update the limsL and limsR for the sliders. If I remove the doloop and the limits at least I dont get the RED error bar. I need to update those values maybe using a button to get all the data and second button to plot.
2- But even with default limits for sliders [0,1] I do not get a plot. The values are updated at the interface. Under varying variables but does not effect the u function. And actually I prefer variables stay as z,y,x etc and not to get numerical values.
Manipulate[DynamicModule[{u =
z Sin[\[Pi] x] + Cos[\[Pi] y] + y^6 Cos[2 \[Pi] y], vars = {x, y, z}, varlims = {{1, 2}, {3, 4}, {5, 6}}, poi = {x, y},
svars = {z, r}, data = Table[RandomReal[], {20}]}, Column[{Style["Ploter", "Function"],
Row[{"Function ", InputField[u]}, Spacer[20]],
Row[{"Variables ", InputField[Dynamic[vars]]}],
Row[{"Variable limits ", InputField[Dynamic[varlims]]}],
Row[{"Plane of interest", InputField[Dynamic[poi]]}],
Row[{"Varying variables", InputField[Dynamic[svars]]}],
Plotslices[u, vars, varlims, poi, svars, size],
Dynamic[
countersvar = Dimensions[svars][[1]];
limsL = ConstantArray[0, countersvar];
limsR = ConstantArray[0, countersvar];
Do[
v = svars[[i]];
posv = Position[vars, v][[1]];
lv = varlims[[posv, 1]][[1]];
rv = varlims[[posv, 2]][[1]];
limsL[[i]] = lv;
limsR[[i]] = rv;
, {i, countersvar}];
Grid[
Table[With[{i = i}, {svars[[i]],
Slider[Dynamic[svars[[i]], {limsL[[1]], limsR[[i]]}]],
Dynamic[svars[[i]]]}], {i, Dimensions[svars][[1]]}]]]
}]], {size, {Small, Medium, Full}}, ControlPlacement -> Bottom,ContinuousAction -> False, Initialization :> (
Plotslices[u_, vars_, varlims_, poi_, svars_, size_] :=
Module[{v1, v2, lv1, lv2, rv1, rv2, posv1, posv2},
v1 = poi[[1]];
v2 = poi[[2]];
posv1 = Position[vars, v1][[1]];
posv2 = Position[vars, v2][[1]];
lv1 = varlims[[posv1, 1]][[1]];
lv2 = varlims[[posv2, 1]][[1]];
rv1 = varlims[[posv1, 2]][[1]];
rv2 = varlims[[posv2, 2]][[1]];
psl =
Plot3D[u, {v1, lv1, rv1}, {v2, lv2, rv2},
PerformanceGoal -> "Quality", Mesh -> None,
ColorFunction -> Function[{v1, v2, z}, Hue[z]],
ImageSize -> size];
Return[psl];];
)
]
I am sorry for the formatting . I tried to put it together crtl+K but it did not work.
I am trying to draw the line formed by the intersections of two planes in 3D, but I am having trouble understanding the math, which has been explained here and here.
I tried to figure it out myself, but the closest that I got to a solution was a vector pointing along the same direction as the intersection line, by using the cross product of the normals of the planes. I have no idea how to find a point on the intersection line, any point would do. I think that this method is a dead end. Here is a screenshot of this attempt:
I tried to use the solution mentioned in this question, but it has a dead link to the original explanation, and the equation didn't work for me (it has unbalanced parentheses, which I tried to correct below).
var planeA = new THREE.Plane((new THREE.Vector3(0, 0, 1)).normalize(), 100);
var planeB = new THREE.Plane((new THREE.Vector3(1, 1, 1)).normalize(), -100);
var x1 = planeA.normal.x,
y1 = planeA.normal.y,
z1 = planeA.normal.z,
d1 = planeA.constant;
var x2 = planeB.normal.x,
y2 = planeB.normal.y,
z2 = planeB.normal.z,
d2 = planeB.constant;
var point1 = new THREE.Vector3();
point1.x = 0;
point1.z = (y2 / y1) * (d1 - d2) / (z2 - z1 * y2 / y1);
point1.y = (-z1 * point1.z - d1) / y1;
var point2 = new THREE.Vector3();
point2.x = 1;
point2.z = (y2 / y1) * (x1 * point2.x + d1) - (x2 * point2.x - d2) / (z2 - z1 * y2 / y1);
point2.y = (-z1 * point2.z - x1 * point2.x - d1) / y1;
console.log(point1, point2);
output:
THREE.Vector3 {x: -1, y: NaN, z: NaN, …}
THREE.Vector3 {x: 1, y: Infinity, z: -Infinity, …}
expected output:
A point along the intersection where x = 0, and
Another point on the same line where x = 1
If someone could point me to a good explanation of how this is supposed to work, or an example of a plane-plane intersection algorithm, I would be grateful.
Here is an implementation of a solution for plane-plane intersections described at http://geomalgorithms.com/a05-_intersect-1.html . Essentially, you first use the cross product of the normals of the planes to find the direction of a line in both planes. Secondly, you use some algebra on the implicit equation of the planes (P . n + d = 0 where P is some point on the plane, n is the normal and d is the plane constant) to solve for a point which is on the intersection of the planes and also on one of the x=0, y=0 or z=0 planes. The solution is then the line described by a point and a vector. I was using three.js version 79
/*
Algorithm taken from http://geomalgorithms.com/a05-_intersect-1.html. See the
section 'Intersection of 2 Planes' and specifically the subsection
(A) Direct Linear Equation
*/
function intersectPlanes(p1, p2) {
// the cross product gives us the direction of the line at the intersection
// of the two planes, and gives us an easy way to check if the two planes
// are parallel - the cross product will have zero magnitude
var direction = new THREE.Vector3().crossVectors(p1.normal, p2.normal)
var magnitude = direction.distanceTo(new THREE.Vector3(0, 0, 0))
if (magnitude === 0) {
return null
}
// now find a point on the intersection. We use the 'Direct Linear Equation'
// method described in the linked page, and we choose which coordinate
// to set as zero by seeing which has the largest absolute value in the
// directional vector
var X = Math.abs(direction.x)
var Y = Math.abs(direction.y)
var Z = Math.abs(direction.z)
var point
if (Z >= X && Z >= Y) {
point = solveIntersectingPoint('z', 'x', 'y', p1, p2)
} else if (Y >= Z && Y >= X){
point = solveIntersectingPoint('y', 'z', 'x', p1, p2)
} else {
point = solveIntersectingPoint('x', 'y', 'z', p1, p2)
}
return [point, direction]
}
/*
This method helps finding a point on the intersection between two planes.
Depending on the orientation of the planes, the problem could solve for the
zero point on either the x, y or z axis
*/
function solveIntersectingPoint(zeroCoord, A, B, p1, p2){
var a1 = p1.normal[A]
var b1 = p1.normal[B]
var d1 = p1.constant
var a2 = p2.normal[A]
var b2 = p2.normal[B]
var d2 = p2.constant
var A0 = ((b2 * d1) - (b1 * d2)) / ((a1 * b2 - a2 * b1))
var B0 = ((a1 * d2) - (a2 * d1)) / ((a1 * b2 - a2 * b1))
var point = new THREE.Vector3()
point[zeroCoord] = 0
point[A] = A0
point[B] = B0
return point
}
var planeA = new THREE.Plane((new THREE.Vector3(0, 0, 1)).normalize(), 100)
var planeB = new THREE.Plane((new THREE.Vector3(1, 1, 1)).normalize(), -100)
var [point, direction] = intersectPlanes(planeA, planeB)
When I have problems like this, I usually let a symbolic algebra package (Mathematica in this case) deal with it. After typing
In[1]:= n1={x1,y1,z1};n2={x2,y2,z2};p={x,y,z};
In[2]:= Solve[n1.p==d1&&n2.p==d2,p]
and simplifying and substituting x=0 and x=1, I get
d2 z1 - d1 z2 d2 y1 - d1 y2
Out[5]= {{{y -> -------------, z -> ----------------}},
y2 z1 - y1 z2 -(y2 z1) + y1 z2
d2 z1 - x2 z1 - d1 z2 + x1 z2
> {{y -> -----------------------------,
y2 z1 - y1 z2
d2 y1 - x2 y1 + (-d1 + x1) y2
> z -> -----------------------------}}}
-(y2 z1) + y1 z2
It is easy to let three.js solve this for you.
If you were to express your problem in matrix notation
m * x = v
Then the solution for x is
x = inverse( m ) * v
We'll use a 4x4 matrix for m, because three.js has an inverse() method for the Matrix4 class.
var x1 = 0,
y1 = 0,
z1 = 1,
d1 = 100;
var x2 = 1,
y2 = 1,
z2 = 1,
d2 = -100;
var c = 0; // the desired value for the x-coordinate
var v = new THREE.Vector4( d1, d2, c, 1 );
var m = new THREE.Matrix4( x1, y1, z1, 0,
x2, y2, z2, 0,
1, 0, 0, 0,
0, 0, 0, 1
);
var minv = new THREE.Matrix4().getInverse( m );
v.applyMatrix4( minv );
console.log( v );
The x-component of v will be equal to c, as desired, and the y- and z-components will contain the values you are looking for. The w-component is irrelevalent.
Now, repeat for the next value of c, c = 1.
three.js r.58
Prerequisites
Recall that to represent a line we need a vector describing its direction and a point through which this line goes. This is called parameterized form:
line_point(t) = t * (point_2 - point_1) + point_1
where point_1 and point_2 are arbitrary points through which the line goes, and t is a scalar which parameterizes our line. Now we can find any point line_point(t) on the line if we put arbitrary t into the equation above.
NOTE: The term (point_2 - point_1) is nothing, but a vector describing the direction of our line, and the term point_1 is nothing, but a point through which our line goes (of course point_2) would also be fine to use too.
The Algorithm
Find the direction direction of the intersection line by taking
cross product of plane normals, i.e. direction = cross(normal_1,
normal_2).
Take any plane, for example the first one, and find any 2 distinct points
on this plane: point_1 and point_2. If we assume that the plane equation
is of the form a1 * x + b1 * y + c1 * z + d1 = 0, then to find 2
distinct points we could do the following:
y1 = 1
z1 = 0
x1 = -(b1 + d1) / a1
y2 = 0
z2 = 1
x2 = -(c1 + d1) / a1
where point_1 = (x1, y1, z1) and point_2 = (x2, y2, z2).
Now that we have 2 points, we can construct the parameterized
representation of the line lying on this first plane:
line_point(t) = t * (point_2 - point_1) + point_1, where line_point(t)
describes any point on this line, and t is just an input scalar
(frequently called parameter).
Find the intersection point intersection_point of the line
line_point(t) and the second plane a2 * x + b2 * y + c2 * z + d2 = 0 by using
the standard line-plane intersection algorithm (pay attention to the
Algebraic form section as this is all you need to implement line-plane
intersection, if you haven't done so already).
Our intersection line is now found and can be constructed in
parameterized form as usual: intersection_line_point(s) = s *
direction + intersection_point, where intersection_line_point(s)
describes any point on this intersection line, and s is parameter.
NOTE: I didn't read this algorithm anywhere, I've just devised it from the top of my head based on my knowledge of linear algebra. That doesn't mean that it doesn't work, but it might be possible that this algorithm can be optimized further.
Conditioning
When 2 normal vectors normal_1 and normal_2 are almost collinear this problem gets extremely ill-conditioned. Geometrically it means that the 2 planes are almost parallel to each other and determining the intersection line with acceptable precision becomes impossible in finite-precision arithmetic which is floating-point arithmetic in this case.
I am trying to add this parametric plot only in the z-axis (right now when I add it expands in the x,y, and z), the effect of this summation would be addition of amplitudes of the sine waves. Here is what I have now. http://imgur.com/j9hN7VR
Here is the code I am using to implement it:
frequency = 1000;
speed = 13397.2441;
wavelength = speed/frequency;
s = (r - 2);
t = (r - 4);
u = (r - 6);
v = (r - 8);
ParametricPlot3D[{{r*Cos[q] - 4, r*Sin[q], Sin[(2*Pi)/wavelength*(r)]},
{s*Cos[q] - 2, s*Sin[q], Sin[(2*Pi)/wavelength*(s + wavelength/4 - 1)]},
{t*Cos[q], t*Sin[q], Sin[(2*Pi)/wavelength*(t + wavelength/4 + 0.5)]},
{u*Cos[q] + 2, u*Sin[q], Sin[(2*Pi)/wavelength*(u + wavelength/4 + 1.65)]},
{v*Cos[q] + 4, v*Sin[q], Sin[(2*Pi)/wavelength*(v + wavelength/4 + 3.5)]}},
{r, 0, 25}, {q, 0, Pi}, PlotPoints -> 30, Mesh -> 20, PlotRange -> {{-25, 25}, {0, 35}, {-6, 6}}]
Any suggestions would be greatly appreciated!
Unfortunately I could not find an answer for this, so I ended up just simulating in MATLAB instead by generating all values over the field (in a matrix) and then summing as I was trying to do here.
It's apparently very simple but I can't find my mistake. The Plot gives me no points at all.
tmax = 1.;
nmax = 10;
deltat = tmax/nmax;
h[t_, s_] := t^2 + s^2;
T = Table[{{n*deltat}, {n*deltat}, h[n*deltat, n*deltat]}, {n, 0, nmax}]
inth = ListInterpolation[T]
Plot3D[inth[s, t], {s, 0, 1}, {t, 0, 1}]
Any help would be mostly welcome!
Marco
I think your "T" is supposed to be a list of 3D points, in which case you should generate it with:
tmax = 1.;
nmax = 10;
deltat = tmax/nmax;
h[t_, s_] := t^2 + s^2;
T = Table[{n*deltat, n*deltat, h[n*deltat, n*deltat]}, {n, 0, nmax}]
inth = ListInterpolation[T]
Plot3D[inth[s, t], {s, 0, 1}, {t, 0, 1}]
Now T[[1]] = {0., 0., 0.} and not {{0.}, {0.}, 0.} as before.