How to plot an NxN array of circles? - arrays

I want to plot an NxN array of circles. Just to visualize, I attached an image of what I want to achieve. I'm new in MatlLab so I tried to plot a single circle first, and here is the sample code below:
n = 2^10; % size of mask
M = zeros(n);
I = 1:n;
x = I - n/2; % mask x - coordinates
y = n/2 - I; % mask y - coordinates
[X,Y] = meshgrid(x,y); % create 2-D mask grid
R = 200; % aperture radius
A = (X.^2 + Y.^2 <= R^2); % Circular aperture of radius R
M(A) = 1; % set mask elements inside aperture to 1
imagesc(M) % plot mask
axis image
I really don't have any idea on how to plot a 2D-array of circles. The distance between two circles is two radii. I need this for my research. Hoping anyone can help.A 4 x 4 array of circles.

If you just want to plot a set of circles, you can use the rectangle function within a loop
If in the call to rectangleyou set the Curvature property to 1 it will be drawn as circle (ref. to the documentation).
In the loop you hav to properly set the position of each rectangle (circle) by defining its lower left coordinates along with its width and height.
Having defined with n the number of circles and with d their diameter, you can compute the set of lower left coordinates as:
px=linspace(0,d*(nc-1),nc)
py=linspace(0,d*(nr-1),nr)
The black background can be either obtained by setting the color of the axes or by plotting another rectangle.
Then you can set the xlim and ylim to fit with the external rectangle.
You can also make the axex invisible, by setting its â—‹Visibleproperty tooff`.
Edit #1
Code updated to allow drawing a user-defined number of circles (set the number of rows and the number of columns)
% Define the number of circles
% Number of rows
nr=8
% NUmber of column
nc=8
% Define the diameter of the circle
d=6
% Create an axex and set hold to on
ax=axes
hold on
% Evalaute the lower left position of each circle
px=linspace(0,d*(nc-1),nc)
py=linspace(0,d*(nr-1),nr)
% Plot the background rectangle
rectangle('Position',[px(1),py(1),d*nc,d*nr],'Curvature',[0 0],'facecolor','k')
% Plot all the circles
for i=1:length(px)
for j=1:length(py)
rectangle('Position',[px(i) py(j) d d],'Curvature',1,'facecolor','w')
end
end
% Set the aspect ratio of the axes
daspect([1 1 1])
% Set the XLim and YLim
xlim([px(1) d*nc])
ylim([py(1) d*nr])
% Make the axes invisible
ax.Visible='off'
Edit #2
Aternative solution to address the OP comment:
If I want to make the axes fixed, say I want a meshgrid of 1024 by 1024, (the image size is independent of the circle radius) how do I incorporate it in the code?
If you want to use a fixed (1024 x 1024) mask on which to plot the circles, starting from the cde you've posted in the question, you can simply do the following:
define the number of circles you want to plot, on a (1024 x 1024) mask they can be 2, 4, 8, ...
define a basic mask holding just one circle
identify the points inside that circle and set them to 1
Replicate (using the function repmat the basic mask accoding to the numner of circles to be plotted
The implemntation, based on your code could be:
% Define the number of circles to be plotted
% on a (1024 x 1024) mask they can be 2, 4, 8, ...
n_circles=4
% Define the size of the basic mask
n0 = (2^10)/n_circles;
% Initialize the basic mask
M0 = zeros(n0);
% Define the x and y coordinates of the basic mask
I = 1:n0;
x = I - n0/2;
y = n0/2 - I;
% Create the mask
[X,Y] = meshgrid(x,y);
% Define the radius of the basic circle
R = n0/2;
% Get the indices of the points insiede the basic circle
A = (X.^2 + Y.^2 <= R^2);
% Set basic mask
M0(A) = 1;
% Open a FIgure
figure
% Replicate the basic mask accoding to the numner of circles to be plotted
M=repmat(M0,n_circles,n_circles);
% Display the mask
imagesc(M)
% Set the axes aspect ratio
daspect([1 1 1])

Related

Matlab: Plot array such that each value has random shape and a color map

In Matlab:
How do I modify plot(x,y,'o'), where x=1:10 and y=ones(1,10), such that each point in the plot will have a random shape?
And how can I give it colors chosen from a scheme where the value at x=1 is the darkest blue, and x=10 is red (namely some sort of heat map)?
Can this be done without using loops? Perhaps I should replace "plot" with a different function for this purpose (like "scatter"? I don't know...)? The reason is that I am plotting this inside another loop, which is already very long, so I am interested in keeping the running-time short.
Thanks!
First, the plain code:
x = 1:20;
nx = numel(x);
y = ones(1, nx);
% Color map
cm = [linspace(0, 1, nx).' zeros(nx, 1) linspace(1, 0, nx).'];
% Possible markers
m = 'o+*.xsd^vph<>';
nm = numel(m);
figure(1);
hold on;
for k = 1:nx
plot(x(k), y(k), ...
'MarkerSize', 12, ...
'Marker', m(ceil(nm * (rand()))), ...
'MarkerFaceColor', cm(k, :), ...
'MarkerEdgeColor', cm(k, :) ...
);
end
hold off;
And, the output:
Most of this can be found in the MATLAB help for the plot command, at the Specify Line Width, Marker Size, and Marker Color section. Colormaps are simply n x 3 matrices with RGB values ranging from 0 to 1. So, I interpreted the darkest blue as [0 0 1], whereas plain red is [1 0 0]. Now, you just need a linear "interpolation" between those two for n values. Shuffling the marker type is done by simple rand. (One could generate some rand vector with size n beforehand, of course.) I'm not totally sure, if one can put all of these in one single plot command, but I'm highly sceptical. Thus, using a loop was the easiest way right now.

How to use DrawEllipse in a LockBits array (How to generate a set of pixels that forms an ellipse)

I'm using this class to fill pixels of a bitmap based on the LockBits function:
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices.Marshal
Public Class Fill
Public Shared Function Process(ByVal b As Bitmap) As Bitmap
Dim bmd As BitmapData = _
b.LockBits(New Rectangle(0, 0, b.Width, b.Height), _
System.Drawing.Imaging.ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb)
Dim scan0 As IntPtr = bmd.Scan0
Dim stride As Integer = bmd.Stride
' Here's the speedier method.
' define an array to store each pixels color as an int32
Dim pixels(b.Width * b.Height - 1) As Integer
' this is system.runtime.interopservices.marshall.copy
Copy(scan0, pixels, 0, pixels.Length)
' loop through all pixels and fill
For i As Integer = 0 To pixels.Length - 1
pixels(i) = Color.Red.ToArgb
Next
' Copy the data back from the array to the locked memory
Copy(pixels, 0, scan0, pixels.Length)
' finally we unlock the bits.
b.UnlockBits(bmd)
Return b
End Function
End Class
Now, instead of filling all the pixels, I need to fill an ellipse (actually it's going to be many ellipses, that's why I use LockBits), so I googled for a way to draw an ellipse pixel by pixel using some kind of formula, but I didn't find much help, also I'm not good with this math stuff.
So, my question is: how to create an array of pixels that forms a filled ellipse? thank you
.
supplement (feel free to ignore):
I'll explain exactly what I'm trying to do, so it might help you understand my situation..
Actually, I'm working on a function that's supposed to generate filled ellipses with random width & height (in specific range) on a specific area of a bitmap, while the filled pixels must have a percentage of the total number of pixels in that area, that's why I need to draw the ellipse pixel by pixel (or using an array of pixels) to keep track of the number of filled pixels.
The formula for all the points inside an ellipse is:
(x - h) * (x - h) / a * a + (y - k) * (y - k) / b * b <= 1
where
x,y are the coordinates of any point on the ellipse,
a, b are the radius on the x and y axes respectively and
h,k the coordinates of the center
So the code:
Dim h, k, a, b, x, y As Integer
Dim res As Double
'arbitrary values of ellipse
h = 200
k = 200
a = 80
b = 60
For x = h - a To h + a
For y = k - b To k + b
res = CDbl((x - h) * (x - h)) / CDbl(a * a) + CDbl((y - k) * (y - k)) / CDbl(b * b)
If res <= 1.0 Then
'the point (x, y) is inside
End If
Next
Next

Ansi C re-evaluating of Y coordinates

Im trying to do a graph from evalued math function and this is last think I need to do. I have graph with limit coordinates -250:-250 left down and 250:250 right up. I have Y-limit function, which is defined as -10:10, but it could be user redefined and if it is redefined, I need to calculate new coordinates.
I have now field of y-coordinates with 20000 values and each of is multiply by:
ratioY = 25 / (fabs( up-limit - down-limit ) / 20) which will make coordinates adapt for new Y-limit (if limit is -5:5, graph looks 2x bigger), this works good, but now isnt graph exactly where it should be (see pictures). Simply 25 is multiplied for postscript coordinates and (up-limit - down-limit) / 20 is ratio for "zooming" Y coordinates. This works fine.
Now Im trying to "move coordinates" which will subtracted from revaluated value:
ycoor = (ycoor * ratioY) - move-coorY ;.
Now I have something like this:
move-coorY = 25* ( ( up-limit - down-limit) /2 );
and it doesnt work correctly. I need to do sin(0) start from 0.
This is a correct graph which is -10:10
(source: matematika.cz)
This is a bad graph which is -5:10
(source: matematika.cz)
Maybe its easier not to do this with fixed numbers (like your ratioY) but with two different coordinate systems. Physical coordinates are in your problem domain, i.e. they are the real values of your sine curves. Logical coordinates refer to the device, in your case they are the point values in Postscript, but they might be pixels on a HTML canvas or whatever.
I'll denote the physical coordinates of the first axis with a small x and the corresponding logical coordinate with a capital X. In each coordinate system we have:
Lower bound: x_min, X_max
Upper bound: x_max, X_max
Range: dx = x_max - x_min
dX = X_max - X_min
Then you can calculate your logical coordinates from the physical ones:
X(x) = X_min + (x - x_min) * dX / dx
This also works vice versa, which is not an issue for Postscript files, but max be useful for an intractive canvas where a mouse click should yield the physical coordinates.
x(X) = x_min + (X - X_min) * dx / dX
In your case, the ratio or scale factor is dX / dx, which you can calculate once for each axis. Let's plot the first point with y == 0 in your first graph:
y_min = -10
y_max = 10
dy = 20
Y_min = -250
Y_max = 250
dX = 500
Y(0) = -250 + (0 - (-10)) * 500 / 20
= -250 + 10 * 500 / 20
= 0
In the second graph, the logical coordinates are the same, but:
y_min = -5
y_max = 10
dy = 15
Y(0) = -250 + (0 - (-5)) * 500 / 15
= -250 + 5 * 500 / 15
= -83.3333
If you change the range of your graph, e.g. from (-10, 10) to (-5, 10), just adjust the physical coordinates. If you resize your graph, change the logical coordinates. (Also, calculating the point in the graph is the same as calculating the position of the tick mark for the axis. Strangely, you got the tick marks right, but not your graph. I think your problem was to account for the non-zero lower bound in both graph and curve data.)
Also, it's probably better to re-evaluate the logical coordinates when printing instead of transfroming them from a previous plot. You can do that on the fly, so that you only need to keep the physical data in an array.
(And lastly, I'll admit that I'm not entirely sure these two kinds of cooirdinates are called physical and logical. I know these terms are used, but it may be the other way round or they might even mean sonething different altogether.)
My friend did a well yob for me and programmed this...
double zeroPosition(double startY, double endY){
double range = endY - startY;
double topSize = endY / range;
return 250.0 - 500 * topSize;
}
This will calculate position of zero, which I just add to my Y position with ratio and It works exactly how I need!
But thanks M Oehm ;)

relation between light intensity and R,G,B

I have a one ambient light with intesity ( 10000,10000, 5000 ). I am trying to color the primitive.
As you know, color values for R,G, and B are between 0 and 255. How can I find color of the pixel according to light intesity ?
platform : linux and programming language c
EDIT :
In ray tracer, we are calculating
for each ambient light in the environment
color . R += Intensity of the light * ambient coefficient for color R
color . G += Intensity of the light * ambient coefficient for color G
color . B += Intensity of the light * ambient coefficient for color B
However, whenever I have tried to emit this pixel color value on the screen with openGL.
set pixel color ( color )
I have taken wrong color because of intensity is high and maximum color value is low.
The question is unclear, as written, so here's some general advice.
Colours in renderers are typically held as values with a nominal range of [0..1] for each of the RGB components.
When those colours are rendered to pixels, they're usually just multiplied by 255 to give a 24-bit colour value (8 bits per component).
If the original values are outside of the [0..1] range they must be "clamped" so that the resulting pixel values fall in the [0..255] range.
That clamping can either be done "per component", which in your case would result in (255, 255, 255), or each component could be divided by the maximum component, giving (255, 255, 127) - i.e. preserving their relative intensities in pseudo-code:
float scale = max(r, g, b);
if (scale < 1) {
scale = 1; // don't normalise colours that are "in range"
}
byte R = 255 * (r < 0 ? 0 : r / scale);
byte G = 255 * (g < 0 ? 0 : g / scale);
byte B = 255 * (b < 0 ? 0 : b / scale);
It's usual for all intermediate calculations to preserve the full dynamic range of intensities. For example, it wouldn't make sense for the Sun to have a brightness of "1", since every other object in the scene would by comparison have an almost infinitesimally small value.
The net result of the clamping will therefore be that light sources which contribute too much light to the scene will produce "saturation" of the image - i.e. the same effect that you get if you leave the shutter open too long on a picture of a bright scene.
It's this one you want:
brightness = sqrt( .241*R*R + .691*G*G + .068*B*B )
Find more here: http://www.nbdtech.com/Blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx
or here: http://en.wikipedia.org/wiki/Luminance_(relative)

MATLAB: Interpolating to find the x value of the intersection between a line and a curve

Here is the graph I currently have
:
The Dotted Blue line represented the y value that corresponds to the x value I am looking for. I am trying to find the x values of the line's intersections with the blue curve(Upper).Since the interesections do not fall on a point that has already been defined, we need to interpolate a point that falls onto the Upper plot.
Here is the information I have:
LineValue - The y value of the intersection and the value of the dotted line( y = LineValue)
Frequency - an array containing the x value coordinates seen on this plot. The interpolated values of Frequency that corresponds to LineValue are what we are looking for
Upper/Lower - arrays containing the y value info for this graph
This solution is an improvement on Amro's answer. Instead of using fzero you can simply calculate the intersection of the line by looking for transition in the first-difference of the series created by a logical comparison to LineValue. So, using Amro's sample data:
>> x = linspace(-100,100,100);
>> y = 1-2.*exp(-0.5*x.^2./20)./(2*pi) + randn(size(x))*0.002;
>> LineValue = 0.8;
Find the starting indices of those segments of consecutive points that exceed LineValue:
>> idx = find(diff(y >= LineValue))
idx =
48 52
You can then calculate the x positions of the intersection points using weighted averages (i.e. linear interpolation):
>> x2 = x(idx) + (LineValue - y(idx)) .* (x(idx+1) - x(idx)) ./ (y(idx+1) - y(idx))
x2 =
-4.24568579887939 4.28720287203057
Plot these up to verify the results:
>> figure;
>> plot(x, y, 'b.-', x2, LineValue, 'go', [x(1) x(end)], LineValue*[1 1], 'k:');
The advantages of this approach are:
The determination of the intersection points is vectorized so will work regardless of the number of intersection points.
Determining the intersection points arithmetically is presumably faster than using fzero.
Example solution using FZERO:
%# data resembling your curve
x = linspace(-100,100,100);
f = #(x) 1-2.*exp(-0.5*x.^2./20)./(2*pi) + randn(size(x))*0.002;
VALUE = 0.8;
%# solve f(x)=VALUE
z1 = fzero(#(x)f(x)-VALUE, -10); %# find solution near x=-10
z2 = fzero(#(x)f(x)-VALUE, 10); %# find solution near x=+10
%# plot
plot(x,f(x),'b.-'), hold on
plot(z1, VALUE, 'go', z2, VALUE, 'go')
line(xlim(), [VALUE VALUE], 'Color',[0.4 0.4 0.4], 'LineStyle',':')
hold off
Are the step sizes in your data series the same?
Is the governing equation assumed to be cubic, sinuisoidal, etc..?
doc interpl
Find the zero crossings

Resources