Show plots inside module in Mathematica - wolfram-mathematica

I want to show plots inside a module (maybe recursive):
m = Module[{i, j}, i = 3; Plot[Sin[t], {t, 0, 1}]; j = 4]
Even
m = Module[{i, j}, i = 3; Show[Plot[Sin[t], {t, 0, 1}]]; j = 4]
not work. Why is this, and how to plot correctly?

The only reason a plot is normally displayed in Mathematica is that the Plot function returns the graphics object representing the plot, and Mathematica displays the return value of whatever you run in a notebook. However, when you follow the statement with a semicolon, you prevent it from returning a value.
What you can do if you need to display something from within the middle of a module is Print[Plot[...]];. The Print function displays the value of its argument directly.

Related

cv2 pose estimation using homography matrix

I am trying to calculate the pose of image Y, given image X. Image Y is the same as image X rotated 90ยบ degrees.
1 -So, for starters i find the matches between both images.
2 -Then i store all the good matches.
3 -The homography between the the matches from both images is calculated using cv2.RANSAC.
4 -Then for the X image, i transform the 2d matching points into 3d, adding 0 as the Z axis.
5 -Object points contain all points from matches of original image, while image points contain matches from the training image. Both array of points are filtered using the mask returned by homography.
6 -After that, i use cv2.calibrateCamera with these object points and image points.
7 -Finnaly i use cv2.projectPoints to get the projections of the axis
I know with that until step 5, the results are correct because i use cv2.drawMatches to see the matches. However this may not be the way to get what i want to achieve.
matches = flann.knnMatch(query_image.descriptors, descriptors, k=2)
good = []
for m, n in matches:
if m.distance < 0.70 * n.distance:
good.append(m)
current_good = good
src_pts = np.float32([selected_image.keypoints[m.queryIdx].pt for m in current_good]).reshape(-1, 1, 2)
dst_pts = np.float32([keypoints[m.trainIdx].pt for m in current_good]).reshape(-1, 1, 2)
homography, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
test = np.zeros(((mask.ravel() > 0).sum(), 3),np.float32) #obj points
test1 = np.zeros(((mask.ravel() > 0).sum(), 2), np.float32) #img points
i=0
counter=0
for m in current_good:
if mask.ravel()[i] == 1:
test[counter][0] = selected_image.keypoints[m.queryIdx].pt[0]
test[counter][1] = selected_image.keypoints[m.queryIdx].pt[1]
test1[counter][0] = selected_image.keypoints[m.trainIdx].pt[0]
test1[counter][1] = selected_image.keypoints[m.trainIdx].pt[1]
counter+=1
i+=1
gray = cv2.cvtColor(self.train_image, cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)
#here start my doubts about what i want to do and if it is possible to do it this way
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera([test], [test1], gray.shape[::-1], None, None)
axis = np.float32([[3, 0, 0], [0, 3, 0], [0, 0, -3]]).reshape(-1, 3)
rvecs = np.array(rvecs, np.float32)
tvecs = np.array(tvecs, np.float32)
imgpts, jac = cv2.projectPoints(axis, rvecs, tvecs, mtx, dist)
However after all this, imgpts returned by cv2.projectPoints give results that don't make much sense to me, like :
[[[857.3185 109.317406]]
[[857.2196 108.360954]]
[[857.2846 107.579605]]]
I would like to have a normal to my image like it is shown here https://docs.opencv.org/trunk/d7/d53/tutorial_py_pose.html and i successfully got it to work using the chessboard image. But trying to adapt to a general image is giving me strange results.

Can't solve Coulomb Force differential equation in Mathematica

I'm trying to solve a problem: I have to find the trajectory of an electron in a graphene lattice using Mathematica. I've tried to solve the Coulomb Force equation with NDSolve and to plot the result for each direction, but i obtain a white plot. Could someone help me please? Thank you in advance. Here's the code for the x direction:
coordx = {0.6327, 1.88058, 3.03927, 4.28716, 5.44584, 6.69373,
7.85241, 9.10029, 1.9728, 3.22069, 4.37937, 5.62726, 6.78594,
8.03382, 9.19251, 10.4404, 3.3129, 4.56079, 5.71947, 6.96736,
8.12604, 9.37393, 10.53261, 11.7805, 4.653, 5.90089, 7.05956,
8.30746, 9.46614, 10.71403, 11.87271, 13.1206};
me = 9.01*10^-31;
pi = 3.14159;
epsilon0 = 8.854*10^-12;
q = -1.6*10^-19;
Q = 1.6*10^-19;
step = 0.01;
Forzax[p_, r_] :=
Sum[(Q*q)/(4 pi*epsilon0*Norm[r - p[[i]]]^2), {i, Length[p]}]
Forzax[coordx, {x[t]}];
NDSolve[{x''[t] == Forzax[coordx, {x[t]}]/me , x[0] == 0,
x'[0] == 0}, {x[t]}, {t, 0, 1500}]
Show[ParametricPlot[Evaluate[{x[t]} /. %], {t, 0, 1500},
PlotRange -> All]]
I don't know what you're trying to plot, but these few modifications seem to plot your function.
sol = NDSolve[{x''[t] == Forzax[coordx, {x[t]}]/me,
x[0] == 0, x'[0] == 0}, {x}, {t, 0, 1500}];
f = sol[[1, 1, 2]];
Plot[f[t], {t, 0, 1500}, PlotRange -> All]
From what I can tell, your code is running fine but the plot is empty because you're calling ParametricPlot with just one function. From the documentation, this is how you call ParametricPlot:
ParametricPlot[{fx[t], fy[t]}, {t, tmin, tmax}]
Since you're still solving the 1D problem and only have x[t], ParametricPlot cannot draw anything; it's missing the y coordinate of the trajectory. Once you do a 2D calculation, ParamatricPlot should be able to give you to figure you want. If you want to do a 3D calculation, you should use ParamatricPlot3D.
A question though: how do you intend to to a 3D calculation of an electron in graphene? The motion of the electron in the 3rd dimension will not follow Newtonian mechanics at all because it is confined so much in that direction. In fact, I'd be kind of cautious about using Newton's 2nd law in graphene no matter what, since electrons in graphene behave like massless particles. I leave the interpretation of the results up to you, but the physicist in me cannot resist adding this word of caution.

Area under a curve in Mathematica

Problem:
I have a two separated list of values, X={x1,x2....x2059} and Y={Y1,Y2....Y2059}. Using the Mathematica function "Transpose" i can obtain a new list Z = {{x1,y1},{x2,y2},...{x2059,y2059}}. Using ListLinePlot[Z] i made the plot.
Now, the problem is: How i can calculate the area under the plotted curve. I can't use NIntegrate, or Integrate. Can I use the interpolation function? how?
Even using the Trapezoidal Rule (implemente by me) i didn't obtain a good resul.
The data comes from an Load-deformation plot. This means that for the first half part of the data, the curve growth. From the second part of data the curve come back to zero (close to zero). In particular, X = deformation and Y=Load.
(*create a simulation for your points*)
npts = 2058;
x = Sort#RandomReal[100, npts];
y = Join[Sort#RandomReal[100, npts/2], Reverse#Sort#RandomReal[100, npts/2]];
f = Interpolation[Transpose#{x, y}, InterpolationOrder -> 1];
(*Plot and Integrate*)
Plot[f[t], {t, Min#x, Max#x}, Filling -> Axis]
NIntegrate[f[t], {t, Min#x, Max#x}, Method -> "LocalAdaptive"]
answer:
(* 5006.01 *)

Parametrizing 3D geometry for shape optimization

I am trying to parametrize a 3D geometry for shape optimization. The structure looks like the following. Another real example is here.
Currently I am using BSplines to create the lower part and using symmetry to create the whole down part of the foil. Here is what I get.
Now I have many control points to take care in order to run a shape optimization. I also don't know how to join the upper part with the bottom hydrofoil part in a sensible way. I don't know how to design a good middle part of the foil (fat nose part of the foil) where the upper part is linked to. I also need to accompany a flap with in the geometry.
Please offer some suggestion for parametrization of such a surface so that we can manipulate the geometry from MMA. The less control points are there better the situation is for optimization. May be combination of some analytic function in 3D. But I doubt if that is possible.
BR
I think you have two choices: 1) create the second part of the geometry and then write a face-face intersection algorithm to merge them. 2) create the second part of the geometry and write two functions that return -1 if a query point is inside the geometry and +1 if it is out side (other values will do). Then use RegionPlot3D[ f1[x,y,z]<0 || f2[x,y,z]<0,....]. The idea is the to extract the GraphicsComplex and use that. The question is going to be how well you can approximate the corners with that. Here is an illustration of what I mean.
if1[x_, y_, z_] := If[x^2 + y^2 + z^2 <= 1, -1, 1]
if2[x_, y_, z_] := If[(x - 1)^2 + y^2 <= 1 && -1.5 <= z <= 1.5, -1, 1]
res = RegionPlot3D[
if1[x, y, z] < 0 || if2[x, y, z] < 0, {x, -2, 2}, {y, -2,
2}, {z, -2, 2}, PlotPoints -> 100, Boxed -> False, Axes -> False]
Then extract the coords and the polygons.
coords = res[[1, 1]];
poly = Cases[res[[1]], _Polygon, Infinity];
Graphics3D[GraphicsComplex[coords, poly], Boxed -> False]
Hope this helps.

Opacity in EPS figures

When saving graphics in Mathematica, is it possible to save figures with opacity in EPS format? For example,
Plot[Evaluate[Table[BesselJ[n, x], {n, 4}]], {x, 0, 10},
Filling -> Axis]
gives the following figure which saves neatly in any format other than EPS.
If I try saving to EPS (in Mathematica 7), the result looks like
In Mathematica 8 it looks like
Does anyone know how to get opacity in EPS plots (or if that is even possible)? The 'use rasterization for transparency' option doesn't look as impressive as a true EPS on zooming.
I usually Rasterize my graphics in this situation. Try
Rasterize[Plot[Evaluate[Table[BesselJ[n, x], {n, 4}]],
{x, 0, 10}, Filling -> Axis], RasterSize -> 600, ImageSize -> 400]
Of course, the result will not be scalable and can take up more memory. You can partially solve the scalability problem by setting the RasterSize larger than the ImageSize, as I have done here.
OK, so EPS can not support true transparency/opacity - but that doesn't mean that Mathematica 7 is excused for doing such a bad job. As evidenced my Mathematica 8, it is possible to make it look better.
The problem with Mathematica 7's output is that it uses the same color for the fill as for the curves, when you really want a lighter color. EPS is a plain text format, so it's quite easy to write a quick hack. Here's a quick tute on PS graphics.
In PS graphics, you define a path then you say whether you want it stroked (lines) or filled (areas) - or other things we don't need to worry about. Colors are set and stay there until they are reset. So I simply import the EPS produced by Mma7 and find all filled paths. For each filled path you find the previous color and reset the color just above the fill command to be something lighter.
So here's an example (I haven't bothered packaging it up into a single script/module).
All output is from Mathematica 7.0.1
p = Plot[Evaluate[Table[BesselJ[n, x], {n, 4}]], {x, 0, 10}, Filling -> Axis]
Export to an EPS file using Export["BesselJs7.eps", p]. This produces a horrible graphic like
OK, now the "fix"
pList = Import["BesselJs7.eps", "List"]; (* Import image as a list of strings *)
FList = Flatten#Position[pList, "F"]; (* find all fill commands *)
Note that the EPS file has the line /F { fill} bind def that defines the shortcut F.
Also, you can check that pList[[FList - 1]] yields a list of "closepath"s.
FColorList = {}; (* get list of colors associated with fills *)
Catch[Do[
i = 0; rgb = True; newpath = True;
While[rgb || newpath,
(*Print[{f,i,f-i,rgb,newpath,pList[[f-i]]}];*)
If[rgb && StringMatchQ[pList[[f - i]], __ ~~ "r"], rgb = False;
AppendTo[FColorList, pList[[f - i]]]];
If[newpath && StringMatchQ[pList[[f - i]], "newpath" ~~ __],
newpath = False; np[f] = f - i];
If[f - i == 1, Throw[{f, rgb, newpath}]];
i++],
{f, FList}]]
Now a hack to create the new colors - all I do is add .5 to each rgb value. This can definitely be made better:
FColorListNew = Table[Most#ToExpression#StringSplit[f] + .5,
{f, FColorList}] /. _?(# > 1 &) -> 1.;
FColorListNew = Table[StringJoin[{Riffle[ToString /# f, " "], " r"}],
{f, FColorListNew}];
Finally, insert the new colors and write it back out:
Do[pList = Insert[pList, FColorListNew[[i]], np[FList[[i]]] + i],
{i, Length[FList]}]
Export["BesselJsFixed.eps", pList, "List"]
Some things, like finding the newpath locations, are unnecessary and the whole thing can probably be tidied up. But I've spent enough time on it for now!
Building on Mark's answer, to export a PNG with transparency, use:
Export[
"testfile.png",
Plot[Evaluate[Table[BesselJ[n, x], {n, 4}]], {x, 0, 10}, Filling -> Axis],
ImageSize -> 600,
Background -> None
]

Resources