General
Follow



David
David
Last activity on 15 Jul 2024

Hello and a warm welcome to all! We're thrilled to have you visit our community. MATLAB Central is a place for learning, sharing, and connecting with others who share your passion for MATLAB and Simulink. To ensure you have the best experience, here are some tips to get you started:
  1. Read the Community Guidelines: Understanding our community standards is crucial. Please take a moment to familiarize yourself with them. Keep in mind that posts not adhering to these guidelines may be flagged by moderators or other community members.
  2. Ask Technical Questions at MATLAB Answers: If you have questions related to MathWorks products, head over to MATLAB Answers (new question form - Ask the community). It's the go-to spot for technical inquiries, with responses often provided within an hour, depending on the complexity of the question and volunteer availability. To increase your chances of a speedy reply, check out our tips on how to craft a good question (link to post on asking good questions).
  3. Choosing the Right Channel: We offer a variety of discussion channels tailored to different contexts. Select the one that best fits your post. If you're unsure, the General channel is always a safe bet. If you feel there's a need for a new channel, we encourage you to suggest it in the Ideas channel.
  4. Reporting Issues: If you encounter posts that violate our guidelines, please use the 🚩Flag/Report feature (found in the 3-dot menu) to bring them to our attention.
  5. Quality Control: We strive to maintain a high standard of discussion. Accounts that post spam or too much nonsense may be subject to moderation, which can include temporary suspensions or permanent bans.
  6. Share Your Ideas: Your feedback is invaluable. If you have suggestions on how we can improve the community or MathWorks products, the Ideas channel is the perfect place to voice your thoughts.
Enjoy yourself and have fun! We're committed to fostering a supportive and educational environment. Dive into discussions, share your expertise, and grow your knowledge. We're excited to see what you'll contribute to the community!
Mike Croucher
Mike Croucher
Last activity about 17 hours ago

I've always used MATLAB with other languages. In the early days, C and C++ via mex files were the most common ways I spliced two languages together. Other than that I've also used MATLAB with Java, Excel and even Fortran.
In more recent years, Python is the language I tend to use most alongside MATLAB and support for this combination is steadily improving. In my latest blog post, I show how easy it has become to use Python's Numpy with MATLAB.
Have you used this functionality much? If so, what for? How well did it work for you?
David Ding
David Ding
Last activity on 5 Dec 2024 at 3:07

I am inspired by the latest video from YouTube science content creator Veritasium on his distinct yet thorough explanation on how rainbows work. In his video, he set up a glass sphere experiment representing how light rays would travel inside a raindrop that ultimately forms the rainbow. I highly recommend checking it out.
In the meantime, I created an interactive MATLAB App in MATLAB Online using App Designer to visualize the light paths going through a spherical raindrop with numerical calculations along the way. While I've seen many diagrams out there showing the light paths, I haven't found any doing calculations in each step. Hence I created an app in MATLAB to show the calculations along with the visualizations as one varies the position of the incoming light ray.
Demo video:
For more information about the app and how to open it and play around with it in MATLAB Online, please check out my blog article:
Toshiaki Takeuchi
Toshiaki Takeuchi
Last activity on 3 Dec 2024 at 22:30

Our MathWorks Usability Team is working on an accessibility project and they want to interview people who use MATLAB and also have experience with screen readers.
If you fit the criteria and are interested, sign up here https://www.mathworks.com/products/usability.html?tfa_30=A11Y
Walter Roberson
Walter Roberson
Last activity on 3 Dec 2024 at 15:49

At the present time, the following problems are known in MATLAB Answers itself:
  • @doc is presenting messed up text until something is selected
  • Symbolic output is not displaying. The work-around is to disp(char(EXPRESSION))
  • Near the top of each Question is displayed a link of the most recent activity on the question. The link is normally clickable and takes you directly to the relevant contribution. But at the moment the link does not take you anywhere
Hans Scharler
Hans Scharler
Last activity on 3 Dec 2024 at 15:09

Let's say you have a chance to ask the MATLAB leadership team any question. What would you ask them?
Steve Eddins
Steve Eddins
Last activity on 3 Dec 2024 at 2:20

I wish I knew more about the intended evolution of the capabilities of the function arguments block. I love implementing function syntaxes using this relatively new form, but it doesn't yet handle some function syntax design patterns that I think are valuable and worth keeping.
For example, some functions take an input quantity that can something numeric, or it can be an option string that descriptively names a particular value of that quantity. One example is dateshift(t,"dayofweek",dow), where dow can be an integer from 1 to 7, or it can be one of the option strings "weekday" or "weekend".
Another example is Image Processing Toolbox that take a connectivity specifier as input. The function bwconncomp is one particular case. Connectivity can be specified using certain scalars, certain arrays, or the option string "maximal".
I think this is a worthwhile function design pattern, but I don't think the arguments block validation functionality supports it well (unless you use a lot of extra code that duplicates standard MATLAB behavior, which undermines the value of the arguments block).
I posted about this today over on my blog. See "Function Syntax Design Conundrum."
MathWorkers - believe me, I know that it is not in your DNA to discuss future features. But would anyone care to offer a hint about directions for the arguments block functionality?
Just shared an amazing YouTube video that demonstrates a real-time PID position control system using MATLAB and Arduino.
All files, including code and setup details, are available on GitHub. Check it out!
I don't like the change
16%
I really don't like the change
29%
I'm okay with the change
24%
I love the change
11%
I'm indifferent
11%
I want both the web & help browser
11%
38 votes
Nicolas Douillet
Nicolas Douillet
Last activity on 21 Nov 2024 at 11:52

T < 2 years
38%
2 years < T < 5 years
26%
5 years < T < 10 years
18%
10 years < T < 20 years
11%
T > 20 years
8%
10172 votes
Teodo
Teodo
Last activity on 17 Nov 2024 at 16:29

Inspired by the suggestion of Mr. Chen Lin (MathWorks), I am writing this post with a humble and friendly intent to share some fascinating insights and knowledge about the Schwarzschild radius. My entry, which is related to this post, is named: 'Into the Abyss - Schwarzschild Radius (a time lapse)'.
MATLAB Shorts Mini Hack: Schwarzschild Radius
The Schwarzschild radius (or gravitational radius) defines the radius of the event horizon of a black hole, which is the boundary beyond which nothing, not even light, can escape the gravitational pull of the black hole. This concept comes from the Schwarzschild solution to Einstein’s field equations in general relativity. Black holes are regions of spacetime where gravitational collapse has caused matter to be concentrated within such a small volume that the escape velocity exceeds the speed of light.
This is a rudimentary scientific post, as the matter of Schwarzschild radius - it's true meaning and function, is a much, much, much-more complex "thing" (not known to us entierly, by the third degre of epistemological explanation(s)).
And, very important is to mention: I am NOT an expert - by any means, on this topic, just a very curious guy, in almost anything, that has to do with science.
Schwarzschild Radius (Gravitational Radius)
The Schwarzschild radius (Rₛ) is the critical radius at which an object of mass must be compressed to form a black hole, specifically, a non-rotating, uncharged black hole, known as a Schwarzschild black hole. The Schwarzschild radius is given by the formula: .
Where: .
Key Characteristics are, that for any mass, if that mass is compressed within a sphere with radius equal to , the gravitational field is so strong that not even light can escape, thus forming a black hole. The Schwarzschild radius is proportional to the mass. Larger masses have larger Schwarzschild radii.
Example:
For the Sun : .
So, if the Sun were compressed into a sphere with a radius of ~3 km, it would become a black hole!
Stellar-mass Black Holes form from the collapse of massive stars (roughly ). Their Schwarzschild radius ranges from a few kilometers to tens of kilometers.
Supermassive Black Holes found at the centers of galaxies, such as Sagittarius A in the Milky Way (), their Schwarzschild radii span from a few million to billions of kilometers!
Primordial or Micro Black Holes, are the hypothetical small black holes with masses much smaller than stellar masses, where the Schwarzschild radius could be extremely tiny.
A black hole, in general, is a solution to Einstein’s general theory of relativity where spacetime is curved to such an extent that nothing within a certain region, called the event horizon, can escape.
MATLAB Shorts Mini Hack: Schwarzschild Radius
Types of Black Holes:
1. Schwarzschild (Non-rotating, Uncharged):
- This is the simplest type of black hole, described by the Schwarzschild solution.
- Its key feature is the singularity at the center, where the curvature of spacetime becomes infinite.
- No charge, no angular momentum (spin), and spherical symmetry.
2. Kerr (Rotating):
- Describes rotating black holes.
- Involves an additional parameter called angular momentum.
- Has an event horizon and an inner boundary, known as the ergosphere, where spacetime is dragged around by the black hole's rotation.
3. Reissner–Nordström (Charged, Non-rotating):
- A black hole with electric charge.
- A charged black hole has two event horizons (inner and outer) and a central singularity.
4. Kerr–Newman (Rotating and Charged):
- The most general solution, describing a black hole that has both charge and angular momentum.
Relationship Between Schwarzschild Radius and Black Holes
Formation of Black Holes: When a massive star exhausts its nuclear fuel, gravitational collapse can compress the core beyond the Schwarzschild radius, creating a black hole.
Event Horizon: The Schwarzschild radius marks the event horizon for a non-rotating black hole. This is the boundary beyond which no information or matter can escape the black hole.
Curvature of Spacetime: At distances closer than the Schwarzschild radius, spacetime curvature becomes so extreme that all paths, even those of light, are bent towards the black hole’s singularity.
BTW, the term singularity, scientificaly 😊, means that: we do not have a clue what is really happening right there...
Detailed Properties of Black Holes:
a. Singularity:
At the center of a black hole, within the Schwarzschild radius, lies the singularity, a point (or ring in the case of rotating black holes) where gravitational forces compress matter to infinite density and spacetime curvature becomes infinite. General relativity breaks down at the singularity, and a quantum theory of gravity is required for a complete understanding.
b. Event Horizon:
The event horizon is not a physical surface but a boundary where the escape velocity equals the speed of light. For an outside observer, objects falling into a black hole appear to slow down and fade away near the event horizon due to gravitational time dilation, a prediction of general relativity. From the perspective of the infalling object, however, it crosses the event horizon in finite time without noticing anything special at the moment of crossing.
c. Hawking Radiation: (In the post, I told that there is no radiation - to make it simple, although, there is a relatively newly-found (theoretically) radiation. Truth to be said, some physicists are still chalenging this notion, in some of it's parts...)
Quantum mechanical effects near the event horizon predict that black holes can emit radiation (Hawking radiation), a process through which black holes can lose mass and, over very long timescales, potentially evaporate completely. This process has a temperature inversely proportional to the black hole's mass, making large black holes emit extremely weak radiation. (Very trivialy speaking: the concept supposes that an anti-particle is drawn from the vakum and is anihilated with the black's hole matter (particle), and in the process, the black hole looses mass gradually and proportionally to the released energy - very slowly(!)).
This radiation is significant only for small black holes.
Gravitational Time Dilation (here, as well, things become 'super-weird'...)
Near the Schwarzschild radius, the intense gravitational field leads to time dilation. For an external observer far from the black hole, time appears to slow down for an object moving toward the event horizon. As it approaches the Schwarzschild radius, time dilation becomes so extreme that the object appears frozen in time at the horizon.
The time dilation factor is given by:
Eg. Approaching the Schwarzschild radius and theoretically remaining just outside of it for a few hours would correspond to the passage of approximately several decades on Earth due to relativistic time dilation.
Using relativistic equations, it's estimated that near the event horizon 2 hours (120 minutes) near the black hole Sagittarius A* (as already mentioned ~ 4 million ) - in the center of our galaxy Milky Way, could correspond to 83 years passing on Earth! However, this varies based on the precise distance from the event horizon (give or take, a decade 😬).
Information Paradox (definte answer on this question, 'hold's the keys of the universe' 😊, maybe...)
The black hole information paradox arises from the seeming contradiction between general relativity and quantum mechanics.
According to quantum mechanics, information cannot be destroyed, yet anything falling into a black hole seems to be lost beyond the event horizon. Hawking radiation, which allows a black hole to evaporate, does not appear to carry information about the matter that fell into the black hole, leading to ongoing debates and research into how information is preserved in the context of black holes, or not...!
Schwarzschild Radius is the key parameter defining the size of the event horizon of a non-rotating black hole. Black Holes are regions where the Schwarzschild radius constrains all physical phenomena due to extreme gravitational forces, forming event horizons and singularities. The interaction between general relativity and quantum mechanics in the context of black holes (e.g., Hawking radiation and the information paradox) remains one of the most intriguing areas in modern theoretical physics.
I hope you will find this post, and information provided, interesting.
Tim
Tim
Last activity on 12 Nov 2024 at 18:11

You can make a lot of interesting objects with matlab primitive shapes (e.g. "cylinder," "sphere," "ellipsoid") by beginning with some of the built-in Matlab primitives and simply applying deformations. The gif above demonstrates how the Manta animation was created using a cylinder as the primitive and successively applying deformations: (https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16252);
Similarly, last year a sphere was deformed to create a face in two of my submissions, for example, the profile in "waking":
You can piece-wise assemble images, but one of the advantages of creating objects with deformations is that you have a parametric representation of the surface. Creating a higher or lower polygon rendering of the surface is as simple as declaring the number of faces in the orignal primitive. For example here is the scene in "snowfall" using sphere with different numbers of input faces:
sphere(100)
sphere(500)
High poly models aren't always better. Low-polygon shapes can sometimes add a little distance from that low point in the uncanny valley.
Go to this page, scroll down to the middle of the long page where you see "Coding Photo editing STEM Business ...." and select "STEM". Voilà!
Mike Croucher
Mike Croucher
Last activity on 8 Nov 2024 at 17:15

Next week is MATLAB EXPO week and it will be the first one that I'm presenting at! I'll be giving two presentations, both of which are related to the intersection of MATLAB and open source software.
  • Open Source Software and MATLAB: Principles, Practices, and Python Along with MathWorks' Heather Gorr. We we discuss three different types of open source software with repsect to their relationship to MATLAB
  • The CLASSIX Story: Developing the Same Algorithm in MATLAB and Python Simultaneously A collaboration with Prof. Stefan Guettel from University of Manchester. Developing his clustering algorithm, CLASSIX, in both Python and MATLAB simulatenously helped provide insights that made the final code better than if just one language was used.
There are a ton of other great talks too. Come join us! (It's free!) MATLAB EXPO 2024
John D'Errico
John D'Errico
Last activity on 8 Nov 2024 at 14:47

syms u v
atan2alt(v,u)
ans = 
function Z = atan2alt(V,U)
% extension of atan2(V,U) into the complex plane
Z = -1i*log((U+1i*V)./sqrt(U.^2+V.^2));
% check for purely real input. if so, zero out the imaginary part.
realInputs = (imag(U) == 0) & (imag(V) == 0);
Z(realInputs) = real(Z(realInputs));
end
As I am editing this post, I see the expected symbolic display in the nice form as have grown to love. However, when I save the post, it does not display. (In fact, it shows up here in the discussions post.) This seems to be a new problem, as I have not seen that failure mode in the past.
You can see the problem in this Answer forum response of mine, where it did fail.
Teodo
Teodo
Last activity on 7 Nov 2024 at 14:47

At the onset of each week, I release a post that analyzes code with the intent of making it accessible for beginners, while also providing insights that can benefit more experienced users seeking to learn new techniques or approaches.
This week, my inspiration comes from the fractal art produced in MATLAB, as presented in my entry Whispers of the Ocean's Breeze:
MATLAB Shorts Mini Hack entry: Whispers of the Ocean's Breeze
Below, I offer a pretty detailed walkthrough of the code break-down, with the goal of creating both an educational and stimulating experience for those eager to learn or find some inspiration. Taking into account that this post is somewhat lengthy, it provides a breakdown and summary of various techniques. It is my hope that it will assist someone and allow readers to focus on the sections that are of most interest to them.
While the code contains comments, this post offers additional explanations and details.
1. Function Definition and Metadata
function drawframe(f)
Line 1: Defines the main function drawframe, which takes a single parameter f. This parameter controls various aspects of the animation, such as movement or speed.
% Audio source: Klapa Šibenik (comp. Arsen Dedić) -
% - Zaludu me svitovala mati
% (Hrvatska 🇭🇷, (Dalmacija))
% Enhanced aesthetics and added dynamic movement,
% offering a creative Remix of my earlier concept.
% (This version brings richer visual appeal,smoother transitions,
% and a more engaging animation flow)
Lines 2-4: Commented-out lines providing metadata or notes about the code. These comments describe the aesthetic goals and improvements in this version, highlighting that it's a remix of one of my earlier entry's, with added dynamic movement and smoother visuals. (These notes are not executed by MATLAB.)
A general tip for using comments: include comments in your code as frequently as needed. They serve as helpful reminders of what each part of the code does, especially when you revisit it after some time, and make it easier for others who may read or use your code.
2. Function Call to seaweed
seaweed(4) % The value in brackets can be adjusted for significantly
% enhanced visualization,
% but it exceeds the 235-second limit in the contest script.
% Feel free to experiment at Desktop workstation - with higher
% values in the loop,
% for more complex and beautiful results.
Line 5: Calls the seaweed function with an argument of 4. The number 4 controls the recursion depth, affecting how detailed or complex the 'seaweed' pattern will be.
Lines 6-9: Comment explaining that increasing the value in seaweed(4) enhances visualization but may exceed time limits in contest environment(s). This suggests adjusting this parameter on a desktop to explore more intricate patterns...
3. Definition of seaweed Function
function seaweed(k)
% Set up the figure window with a specific position and background color
figure('Position', [60+2*f, 60-2*f, 600, 600], 'Color', [0.15, 0.15, 0.5]);
Line 10: Defines the seaweed function, which takes a parameter k (depth of recursion). This function initializes the graphical figure window.
Line 12: Sets up the figure window with a position influenced by f, making the figure’s position change dynamically with f. The background color [0.15, 0.15, 0.5] creates a dark blue background, enhancing the underwater aesthetic.
4. Recursive Drawing with crta Function
crta([0, 0], 90, k, k);
% Make the axes equal and turn them off for a clean figure
axis equal
axis off
Line 14: Calls the recursive function crta, starting the drawing process at [0, 0](origin point) with a 90-degree angle. Both k values set the initial recursion depth and maximum recursion level.
Lines 16-17: Sets the axis scale to equal, ensuring no distortion, and turns off the axes for a cleaner display.
5. Definition of crtaFunction and Initialization of Parameters
function crta(tck, ugao, prstiter, r)
% Define thickness of line segment proportional to current depth
sir = 5 * (prstiter / r);
% Define length of the line segment
duz1 = 5 * prstiter;
Line 18: Defines crta, a nested function within seaweed, taking parameters tck (current coordinates), ugao (angle), prstiter (current recursion depth), and r (maximum recursion depth).
Lines 20-21: Defines sir (line thickness) to be proportional to the current recursion depth, prstiter, creating thinner branches as depth increases. While, duz1 defines the line segment length, which shortens with each recursion, creating perspective.
6. Angle Calculations for Branching
% Define four branching angles with slight variations
ug1 = ugao + 15 + (f / 15);
ug2 = ugao + 7 - f / 15;
ug3 = ugao - 7 + f / 15;
ug4 = ugao - 15 - f / 15;
Lines 23-27: Sets branching angles ug1, ug2, ug3, and ug4 relative to the initial angle ugao, adding and subtracting small amounts. These angles, influenced by f, introduce subtle variations, enhancing the natural appearance.
7. Calculations for Branch Endpoints
% Calculate endpoints of each line segment for the four angles
a1 = duz1 * sind(ug1) + tck(2);
b1 = duz1 * cosd(ug1) + tck(1);
c2 = duz1 * sind(ug2) + tck(2);
a2 = duz1 * cosd(ug2) + tck(1);
b3 = duz1 * sind(ug3) + tck(2);
c3 = duz1 * cosd(ug3) + tck(1);
d4 = duz1 * sind(ug4) + tck(2);
e4 = duz1 * cosd(ug4) + tck(1);
Lines 29-36: Calculates x and y endpoints for each of the four branches using sind and cosd functions, which convert angles into coordinates. Each branch starts at tck(current In this section, the code calculates the endpoints of four line segments, each corresponding to a distinct angle (ug1, ug2,ug3, and ug4). These endpoints are computed based on the length of the line segment duz1, which scales with recursion depth to make each segment shorter as the recursive function progresses. The trigonometric functions sind and cosd are used here to calculate the horizontal and vertical displacements of each segment relative to the current position, tck. While, sind and cosd functions compute the sine and cosine of each angle in degrees, returning the y and x displacements, respectively. For each angle, multiplying by duz1scales these displacements to achieve the intended length for each line segment. Each endpoint coordinate is calculated by adding these displacements to the initial position, tck, to determine the final position for each branch segment:
  • a1 and b1 represent the y and x endpoints for the segment at angle ug1
  • c2 and a2 represent the y and x endpoints for the segment at angle ug2
  • b3 and c3 represent the y and x endpoints for the segment at angle ug3
  • d4 and e4 represent the y and x endpoints for the segment at angle ug4
These coordinates form the four main branches radiating out from the current position in different directions. By varying the angle slightly for each branch and scaling the length proportionally, the function generates a visually rich, organic branching structure that resembles seaweed or other natural patterns.
8. Midpoint Calculations for Additional Complexity
% Calculate midpoints for additional "leaves" to
% simulate complexity
uga1 = ug2 - 5 + f / 5;
ugb2 = ug3 + 5 - f / 5;
uga2 = duz1 / 2 * sind(uga1) + c2 + f / 20;
ugb3 = duz1 / 2 * cosd(uga1) + a2 - f / 20;
ugc2 = duz1 / 2 * sind(ugb2) + b3 + f / 20;
ugda1 = duz1 / 2 * cosd(ugb2) + c3 - f / 20;
Lines 38-44: Calculates midpoint angles and positions for extra leaf” structures. This further enhances the fractal appearance by adding more detail, as these points fall between main branches!
Additional midpoints are calculated to add further detail and complexity to the fractal pattern. These midpoints represent extra branches or leaves that emerge from within the main branch segments, enhancing the natural, organic appearance of the fractal structure. Consequently, uga1 and ugb2 are new angles derived by slightly modifying the main branch angles ug2and ug3. The adjustments are made by adding and subtracting small values, including a component based on f. These subtle variations create slight deviations in the angles of the additional branches, making them appear more random and organic, like leaves growing off main stems in varied directions. Once the new angles uga1 and ugb2 are defined, they are used to calculate intermediate coordinates along the main branch lines. These midpoints are positioned halfway along each branch segment, representing the location from which the extra “leaf” branches will emerge.
To find these midpoints:
  • uga2 and ugb3 use sind(uga1) and cosd(uga1)to calculate the y and x coordinates halfway along the segment for angle ug2.
  • ugc2 and ugda1 similarly use sind(ugb2) and cosd(ugb2) to get the coordinates for angle ug3.
Each midpoint calculation also includes a slight additional offset based on f (like f / 20), adding variation in their positions and contributing to the irregular, natural look of the structure.
By adding these secondary branches, the fractal pattern gains more intricacy. These “leaves” give a more complex and dense appearance, resembling the growth patterns of plants or seaweed where smaller branches diverge from main stems. The addition of midpoints also contributes to the overall depth and richness of the fractal design, ensuring that each recursive call doesn’t simply repeat but also grows in visual detail, making the resulting fractal more visually appealing and realistic. The midpoint calculations thus play a crucial role in enhancing the visual complexity of the fractal by introducing smaller, secondary branches that break up the regularity of the main branches, making the structure more detailed and lifelike.
9. Color Definition Based on Depth
% Define color based on depth, simulating a gradient effect
% as recursion deepens
boja = [1 - (prstiter / r), 1 - 0.5 * (prstiter / r), 0];
Line 46: Defines the color boja as a gradient that shifts from yellow to dark orange based on recursion depth. This gradient effect enhances the visual depth of the pattern.
This code sets up a color gradient for each branch segment based on its recursion depth. This approach not only adds aesthetic appeal but also visually separates different levels of recursion, making it easier to perceive depth within the fractal. The variable boja is an RGB color array, where each element represents the intensity of red, green, and blue respectively, on a scale from 0 (no intensity) to 1(full intensity).
The first element, 1 - (prstiter / r), controls the red component. The second element, 1 - 0.5 * (prstiter / r), controls the green component. The third element is set to 0, meaning there is no blue in the color, resulting in a gradient that shifts from yellow (where both red and green are high) to darker orange and then brownish tones as recursion deepens. The color gradually shifts from a bright yellowish tone at shallow recursion levels to a darker, warmer orange as recursion depth increases. This is achieved by gradually decreasing the red and green components of the color as prstiter (current recursion depth) approaches r (maximum recursion depth). At the top levels of recursion (where prstiter is closer to r), the color becomes darker and more subdued, giving the branches a gradient that makes the structure look natural and complex. This effect is reminiscent of how colors in nature tend to fade or darken with distance or depth, such as in underwater scenes where light penetration decreases with depth.
The gradient serves as a visual cue that helps distinguish between different recursion levels. Since each level is progressively darker, viewers can intuitively sense the depth of each branch, which adds to the three-dimensional effect of the fractal. The use of warm colors (yellow to orange) for each branch segment helps the fractal pattern stand out vividly against the cool blue background set in the seaweed function. This color contrast enhances the underwater, organic look of the structure, making it appear as though the "seaweed" is reaching out toward a light source above. This coloring strategy also contributes to the fractal’s aesthetic complexity. By associating color depth with recursion depth, the fractal appears to have layers, creating a visually satisfying and realistic effect.
10. Plotting Branch Segments
% Plot main branches from the starting point (tck) to the calculated
% endpoints with color and transparency
p1 = plot([tck(1), b1], [tck(2), a1], 'LineWidth', sir, 'Color', boja);
hold on
s2 = plot([tck(1), a2], [tck(2), c2], 'LineWidth', sir, 'Color', boja);
s3 = plot([tck(1), c3], [tck(2), b3], 'LineWidth', sir, 'Color', boja);
s4 = plot([tck(1), e4], [tck(2), d4], 'LineWidth', sir, 'Color', boja);
% Plot secondary branches connecting midpoints for added detail
s5 = plot([a2, ugb3], [c2, uga2], 'LineWidth', sir, 'Color', boja);
s6 = plot([c3, ugda1], [b3, ugc2], 'LineWidth', sir, 'Color', boja);
Lines 48-56: Plots the main branches and secondary branches for added detail. Each plot command connects points with a specified thickness and color, creating the branching effect.
Here presented code, plots the main branches and additional leaf segments, giving form to the fractal pattern. Each plot command specifies a line segment by connecting two points, with attributes like line width (sir) and color (boja) enhancing the realism and aesthetic detail. Lines from p1to s4 represent a branch extending outward from the current point tck to its calculated endpoint. The branch segments p1, s2, s3, and s4 form the primary structure of the fractal by branching off at angles ug1, ug2, ug3, and ug4 respectively, calculated in earlier presented and explained steps. The plot command takes a pair of [x, y] coordinates that define the line’s start and end points. For instance, p1 = plot([tck(1), b1], [tck(2), a1], 'LineWidth', sir, 'Color', boja); draws a line from tck(the current position) to (b1, a1), one of the endpoints.
The arguments 'LineWidth', sir and 'Color', boja ensure that each line segment has a thickness and color appropriate to its recursion level, making higher-level branches thicker and more prominent while creating a natural gradient. The command hold on is crucial here, it allows MATLAB to draw multiple line segments within the same figure window without erasing the previous segments. This is necessary for the recursive nature of the fractal, as each call to crtaadds branches to the existing structure, layering them to form a complex, interconnected pattern. Lines s5 and s6 represent additional leafsegments, plotted between midpoints calculated in Section 8. These smaller branches diverge from the main branches, adding further intricacy and detail to the fractal. By connecting midpoints (such as a2 to ugb3 and c3 to ugda1), the code generates extra leafy offshoots that break up the regularity of the main branches.
These segments make the fractal look more organic, akin to the smaller branches and leaves one might see on real plants or seaweed. Similar to the main branches, the secondary branches use sir and boja for line width and color, ensuring consistent visual depth and blending them seamlessly into the overall pattern. This layering allows the fractal to resemble natural structures like foliage or underwater vegetation. The combination of primary and secondary branches contributes to both symmetry and asymmetry in the fractal. While the primary branches provide a balanced, four-way split, the secondary branches introduce slight irregularities, which lend an organic feel to the pattern. Finally, by plotting each segment separately, the code achieves a highly customizable structure. Line thickness, color, and endpoint coordinates can be easily adjusted for each recursion level, allowing flexibility in the appearance and feel of the fractal.
11. Setting Transparency and Recursion
% Set transparency for each plot segment
s1.Color(4) = 0.95;
s2.Color(4) = 0.95;
s3.Color(4) = 0.95;
s4.Color(4) = 0.95;
s5.Color(4) = 0.95;
s6.Color(4) = 0.95;
% Continue recursive drawing if there are levels left ( prstiter > 0)
if prstiter - 1 > 0
% Recursive calls for each of the main branches with
% updated angles and decreased recursion depth
crta([b1, a1], ug1, prstiter - 1, r);
crta([ugb3, uga2], uga1, prstiter - 1, r);
crta([ugda1, ugc2], ugb2, prstiter - 1, r);
crta([e4, d4], ug4, prstiter - 1, r);
end
end
end
Lines 58-63: Sets the transparency of each branch segment to 0.95, creating a slightly translucent effect.
Lines 65-71: Checks if recursion should continue (i.e., if prstiter > 0). If so, the crta function recursively calls itself with updated angles and positions, generating the next level of branching until prstiter reaches the value of 0.
This code applies transparency to each branch segment to enhance the visual layering effect and initiates further recursion for drawing deeper levels of the fractal. Lines s1.Color(4) = 0.95; through s6.Color(4) = 0.95; apply transparency to each of the plot segments, allowing branches to be slightly see-through. In MATLAB, the fourth element of the Color property, Color(4), represents the alpha (transparency) value. That is, setting it to 0.95 makes each branch segment 95% opaque, meaning it is just translucent enough to create a layered effect where overlapping branches blend slightly. This subtle transparency creates depth, giving the impression that some branches are behind others, which enhances the natural, three-dimensional appearance of the fractal structure. The transparency effect also softens the overall image, making the fractal appear less rigid and more fluid in water.
Line: if prstiter - 1 > 0, checks if further recursion should occur by verifying that prstiter (the current recursion depth) is greater than 1. If prstiter is greater than 1, the function proceeds to recursively call crta, reducing prstiter by 1 with each call. This gradual reduction in prstiter ensures that recursion continues until the maximum depth, defined by r, is reached. As the recursion depth decreases with each call, the branch segments become progressively shorter and thinner, creating a tapered effect that adds to the realistic, fractal-like branching.
Recursive Calls of the function crta, calls itself four times, once for each main branch direction (ug1, ug2, ug3, ug4), using updated coordinates and angles:
  • crta([b1, a1], ug1, prstiter - 1, r); initiates a recursive call for the branch at angle ug1.
  • crta([ugb3, uga2], uga1, prstiter - 1, r); starts recursion from the midpoint branch at angle uga1.
  • crta([ugda1, ugc2], ugb2, prstiter - 1, r); continues recursion from the midpoint branch at angle ugb2.
  • crta([e4, d4], ug4, prstiter - 1, r); initiates recursion from the branch at angle ug4.
Each recursive call passes a new starting point (calculated in previous steps) and an adjusted angle. These recursive calls add the next level of branching, gradually building out the entire fractal structure. The recursive calls are fundamental to constructing the fractal pattern. By creating multiple levels of branching, each progressively smaller and more complex, the fractal develops a rich, layered structure that mimics natural growth patterns. The recursive structure also allows for variations in each level, as each branch is influenced by slightly different angles and positions, resulting in an organic, non-uniform look. This natural irregularity is key to creating a visually appealing fractal. Additionally, since each recursive call has transparency applied to its branches, the resulting fractal has a soft, blended appearance. Overlapping branches appear to merge gently, creating a cohesive, three-dimensional visual effect.
End of Code
end
This line closes the entire drawframe function, completing the recursive fractal drawing of the seaweed structure.
Sometimes, neglecting to include the necessary closure for a function can lead to unexpected surprises in the code. Always be vigilant about ensuring that functions, loops, and other structures are properly closed.
Final result: Whispers of the Ocean's Breeze
Summary: This whole code uses recursion and geometry to create natural-looking, fractal-inspired patterns that mimic the movement and appearance of seaweed, achieving complexity and organic flow through simple recursive structure and dynamic angle variations.
Hi MATLAB Central community! 👋
I’m currently working on a project where I’m integrating MATLAB analytics into a mobile app, mainly to handle data-heavy tasks like processing sensor data and running predictive models. The app is built for Android, and while it’s not entirely MATLAB-based, I use MATLAB for a lot of data preprocessing and model training.
I wanted to reach out and see if anyone else here has experience with using MATLAB for similar mobile or embedded applications. Here are a few areas I’m focusing on:1. Optimizing MATLAB Code for Mobile Compatibility
I’ve found that some MATLAB functions work perfectly on desktop but may run slower or encounter limitations on mobile. I’ve tried using code generation and reducing function calls where possible, but I’m curious if anyone has other tips for optimizing MATLAB code for mobile environments?
2. Using MATLAB for Sensor Data Processing
I’m working with accelerometer and GPS data, and MATLAB has been great for preprocessing. However, I wonder if anyone has suggestions for handling large sensor datasets efficiently in MATLAB, especially if you've managed data in mobile contexts?
3. Integrating MATLAB Models into Mobile Apps
I’ve heard about using MATLAB Compiler SDK to integrate MATLAB algorithms into other environments. For those who have done this, what’s the best way to maintain performance without excessive computational strain on the device?
4. Data Visualization Tips
Has anyone had experience with mobile-friendly data visualizations using MATLAB? I’ve been using basic plots, but I’d love to know if there are any resources or toolboxes that make it easier to create lightweight, interactive visuals for mobile.
If anyone here has tips, tools, or experiences with MATLAB in mobile development, I’d love to hear them! Thanks in advance for any advice you can share!
Tianyi
Tianyi
Last activity on 6 Nov 2024 at 6:57

Mini Hack is brilliant!Let's use MATLAB to create the future!
Teodo
Teodo
Last activity on 5 Nov 2024

Here presented MATLAB code is designed to create a seamless loop animation that visualizes an isosurface derived from random data.
This entry, titled "The Scrambled Predator's Cube", builds upon my previous work and has been adapted to include dynamic elements.
MATLAB Shorts Mini Hack: The Scrambled Predator's Cube
In this explanation, I will break down the relatively short code, making it accessible whether you are a beginner in MATLAB or an experienced user. Let's go through the MATLAB code step by step to understand each line in detail.
Code Breakdown
d = rand(8,8,8);
Random Data Generation: This line creates a three-dimensional array d with dimensions 8×8×8 filled with random values. The rand function generates values uniformly distributed in the interval (0,1). This array serves as the input data for generating the isosurface.
iv = .5 + (f / 10000);
Isovalue Calculation: Here, the isovalue iv is computed based on the frame number f. The expression f / 10000 causes iv to increase very slowly as f increments. Starting from 0.50, this means that for every increment of f, iv changes slightly (specifically, by 0.0001). This gradual increase creates a smooth transition effect in the isosurface over time, making it look dynamic as the animation progresses.
h = patch(isosurface(d, iv), 'FaceColor', 'blue', 'EdgeColor', 'none');
Isosurface Creation: The isosurface function extracts a 3D surface from the data array d at the specified isovalue iv. The result is a patch object h that represents the isosurface in the 3D plot. The 'FaceColor', 'blue' argument sets the face color of the surface to blue, while 'EdgeColor', 'none' specifies that no edges should be drawn, giving the surface a solid appearance.
isonormals(d, h);
Surface Normals Calculation: This function calculates the normals at each vertex of the isosurface h, based on the data in d. Normals are vectors perpendicular to the surface at each point and are crucial for proper lighting calculations. By using isonormals, the appearance of depth and texture is enhanced, allowing the lighting to interact more realistically with the surface.
patch(isocaps(d, iv), 'FaceColor', 'interp', 'EdgeColor', 'none');
Isocaps Visualization: The isocaps function creates flat surfaces (caps) at the boundaries of the isosurface where the data values meet the isovalue iv. The resulting caps are then rendered as patches with 'FaceColor', 'interp', meaning the colors of the caps are interpolated based on the data values. The caps provide a more complete visual representation of the isosurface, improving its overall appearance.
colormap hsv;
Color Map Setup: This line sets the colormap of the current figure to HSV (Hue, Saturation, Value). The HSV colormap allows for a wide range of colors, which can enhance the visual appeal of the rendering by mapping different values in the data to different colors.
daspect([1, 1, 1]);
Aspect Ratio Setting: The daspect function sets the data aspect ratio of the plot to be equal in all three dimensions. This means that one unit in the x-direction is the same length as one unit in the y-direction and z-direction, ensuring that the visual representation of the 3D data is not distorted.
axis tight;
Tight Axis Setting: This command adjusts the limits of the axes so that they fit tightly around the data, removing any excess white space. It helps to focus the viewer's attention on the isosurface and related visual elements.
view(3);
3D View Configuration: The view(3) command sets the current view to a 3D perspective, allowing the viewer to see the structure of the isosurface from an angle that reveals its three-dimensional nature.
camlight right;
camlight left;
Lighting Effects: These commands add two light sources to the scene, positioned to the right and left of the view. The additional lighting enhances the shading and depth perception of the isosurface, making it appear more three-dimensional and visually appealing.
axis off;
Hide Axes: This command turns off the display of the axes in the plot. Removing the axes provides a cleaner visual representation, allowing the viewer to focus solely on the isosurface and its lighting effects without distraction from the grid lines or axis labels.
lighting phong;
Lighting Model: This line sets the lighting model to Phong. The Phong model is widely used in computer graphics as it provides smooth shading and realistic reflections. It calculates how light interacts with surfaces, enhancing the overall appearance by creating a more natural look.
MATLAB Shorts Mini Hack: The Scrambled Predator's Cube
This code creates a visually dynamic and appealing representation of an isosurface derived from random data. The gradual change in the isovalue allows for smooth transitions, while the combination of lighting, colors, and shading contributes to a rich 3D visualization. Each component plays a vital role in rendering the final output, showcasing advanced techniques in data visualization using MATLAB.
This year's MATLAB Shorts Mini Hack contest has kicked off, and there are already lots of interesting entries. The contest features creating a 96-frame, 4-second animation, which is looped 3 times to compose a 12-second short movie. There is an option to add audio to enhance the animation, and it's restricted to a an upper limit of 2,000 characters to promote efficient coding.
Many of the contestants have already realized the potential for creating a seamless loop, which provides a smooth transition and avoids any discontinuities when the animation is repeated. There are several ways to achieve this. An efficient method for example is utilizing sinusoidal functions, which are periodic, meaning that they repeat themselves over time:
An intuitive example of a seamless loop is @Edgar Guevara's EKG pulse entry, which features an electrocardiogram signal on an oscilloscope. The animation is perfectly matched by the audio, as explained in their post.
Another, rather sophisticated approach is featured in @Tim's Moonrun animation in last year's contest. This seamless loop is achieved by cleverly manipulating the camera position and target over a periodic spatial domain, producing this stunning result:
This essentially tells us that for a seamless loop in the spatial domain, the first frame must match the last frame (with a single timestep difference to be more precise, more on that later). But surely this cannot be achieved by zooming in, unless you are simulating a fractal. Well, there are always workarounds.
One way to achieve this is by zooming into a section that contains the first frame of the animation. This is featured in my Winter Loop entry. This is a remix of @Oliver Jaros's Winter entry, which was selected as a one of the weekly winners in the nature & space category for Week 1. The code was modified to lower the character count, but all credits for the original idea and graphics go to them. I also drew inspiration from one of my favourite games of all time, Super Mario 64. Oliver's animation reminded me of the Cool, Cool Mountain level of the game. In the game, you can enter various levels by jumping into paintings serving as portals.
This inspired the idea of zooming into a rectangular photograph frame containing the first frame of the animation to facilitate restarting the loop. One could argue that it would probably take a crazy person to have a photo of their house framed inside their own house. Well, in this economy and with the current house prices, I don't think this scenario is too far-fetched:
The implementation for this in 2-D is rather simple. Essentially, a second axes is used as the photograph. This is an efficient way of neatly updating the graphics while zooming in. The way this was implemented is explained in the following code snippet, which is a slight modification of the code in the entry:
m = 96; % Number of frames
% Axes limits for the first frame
xm = [xm1,xm2];
ym = [ym1,ym2];
% Axes limits for the last frame (photograph frame edges)
xf = [xf1,xf2];
yf = [yf1,yf2];
% Zoom-in vectors
x1 = linspace(xm(1),xf(1),m+1); % Axes left edge to left photo frame edge
x2 = linspace(xm(2),xf(2),m+1); % Axes right edge to right photo frame edge
y1 = linspace(ym(1),yf(1),m+1); % Axes bottom edge to bottom photo frame edge
y2 = linspace(ym(2),yf(2),m+1); % Axes top edge to top photo frame edge
if f==1
axis([x1(f),x2(f),y1(f),y2(f)]); % Set main axes limits
ax2 = copyobj(gca,gcf); % Create axes for the photo frame containing the first frame graphics objects
end
axis([x1(f+1),x2(f+1),y1(f+1),y2(f+1)]); % Zoom in main axes
lims = axis; % Main axes updated limits
pos = get(gca,'Position'); % Main axes position
% This keeps the relative position of the 2 axes constant:
pos = [pos(1)+diff([lims(1),xf(1)])/diff(lims(1:2))*pos(3),...
pos(2)+diff([lims(3),yf(1)])/diff(lims(3:4))*pos(4),...
diff(xf)/diff(lims(1:2))*pos(3),...
diff(yf)/diff(lims(3:4))*pos(4)];
ax2.Position = pos; % Adjust the relative position
Let's break down the code to explain the process:
  • m is the total number of frames in the animation, i.e. 96 frames.
  • xm & ym are the main axes limits for frame 1.
  • xf & yf are the main axes limits for frame 96, corresponding to the photograph frame's edges.
  • x1, x2, y1 & y2 are the zoom-in vectors, linearly spaced from the left, right, bottom & top main axes edges to the corresponding photograph edges. You have probably noticed that these contain m+1=97 points, which is 1 more than the total number of frames. This is done so that the first frame of the animation and the contents of the photograph frame are offset by a single timestep, so that there are no overlapping frames when the animation is looped, thus creating a perfect, seamless loop. That means that the first frame of the animation will contain the main axes zoomed-in by a single timestep, while the last frame of the animation (i.e. the zoomed-in photograph frame) will contain the most zoomed-out version of the graphics. This neatly wraps the animation, and displays the full zoomed-out view when the video stops playing.
  • The photograph frame axes are created when f==1 (after setting the initial axes limits) by using the immensely useful copyobj function. This one-liner creates axes containing all graphics objects for the first frame.
  • Zooming in on the main axes is then achieved by adjusting the limits using axis([x1(f+1),x2(f+1),y1(f+1),y2(f+1)]). The main axes current limits and position are then saved using the variables lims and pos respectively, in order to adjust the position of the photograph frame axes.
  • While zooming in, it's important that the relative position of the 2 axes is kept constant. This is achieved by simply adjusting the position of the photograph frame axes at every frame, by calculating their relative ratios using the abovementioned formula. The first 2 arguments correspond to the (normalized) x and y positions of the lower left corner of the axes, while the third and fourth arguments correspond to the (normalized) width and height respectively. While this formula will work for any position of the main axes, it's a good idea to set the position as set(gca,'Position',[0 0 1 1]) for this contest, in order to take full advantage of the whole allocated window for the animation.
  • Finally, note that the graphics are updated for the main axes only, and the above process is repeated for each frame until fully zooming into the photograph frame's axes.
Some of the most curious minds might wonder that while this is well and all with using the second axes to simulate the photograph, what happens to the photograph inside the photograph (and so on...)? Well, the beauty of this method is that you can repeat this as many times as necessary (just apply the formula using the current position and limits of the second axes to adjust the position of the third axes and so on). Given the speed of the animation and the very small size of the photograph inside the photograph, it would be very unlikely that you would need more than 3 axes, but the process is always good to know.
This is the final result:
I hope you found these tips useful and I'm looking forward to seeing many creative seamless loop animations in the contest.