Need a little help on an equation for a GUI "Slider" - user-interface

This is a small equation that's giving me a headache, I'm close to solving but- Ugh.
I'll try to be prompt.
I have this:
As you see it is a slider that goes from 0.1x to 3x Difficulty.
I have other sliders like this, for audio for example that just go from 0% to 100%.
That works fine.
However, with a minimum value greater than 0 my math breaks a bit and I'm stuck not being able to
perfectly slide the bar all the way to the bottom because it isn't 0 and it is 0.1 instead.
I want to make it to where even if the minimum value isn't 0, the bar goes all the way to empty.
Here is the relevant equations/calculations at play:
var percent = val/val_max
var adjustment = ((x2-x1)*val_min)-((((x2-x1)*val_min)*percent)*val_min)
var x2_final = (x1+((x2-x1)*percent))-adjustment
percent is the percentage of the current value relative to the max value (0.0 to 1.0)
adjustment is trying to find how much to additionally add/remove from x2_final based on the current value to keep the slider properly scaled when the minimum value isn't 0. (This is where the problem is)
x2_final is the final (in pixels) coordinate where the slider should stop based on the previous calculations.
Initially the slider would over fill when full (that was fixed by the current adjustments) but now the slider doesn't go all the way empty and leaves a "0.1" worth of slider.
I don't usually use forums or stackoverflow as I try to figure out things on my own but so I apologize if my explanation needs work.
Here is what the slider looks like when I set it as low as it will go:
Also, if I have more math related problems, are there any good tools I can use to help simulate my calculations like this so people can run it for them selves or something?
Thanks in advance!

Solved it!
So my equation was a bit wrong for the adjustment.
As now it looks like this:
var percent = val/val_max
var percent_min = val_min/val_max
var adjustment = ((x2-x1)*percent_min)-(((x2-x1)*percent_min)*percent)
var x2_final = (x1+((x2-x1)*percent))-adjustment
And now the slider properly fills to full as well as empties to the bottom,
regardless of what the minimum value is.
But I also noticed then the bar as I was sliding it wasn't following my mouse.
So to fix that I had to go later in my code where I update the current value of the slider as the user clicks and changes it...
var mouse_x_percent = round2((mouse_x-x1+adjustment)/(x2-x1+adjustment),2)
Just had to add the adjustment to both sides of that calculation (getting the mouse_x's percentage relative to the beginning and end of the slider itself which would then be used to calculate the new value by multiplying the mouse_x_percent with the max value).
(Round2() takes two numbers, the first being the number to round, and the second to what decimal place)
Always love solving a problem, I hope this helps someone else.

Related

How to reduce 10k data points and show them on smaller display? Arduino

I‘m working on a visual data logger for my DMM, it writes every measurement to RS232 inteface. There I connect a Teensy 3.6 and collect the data points.
For each point I have the timestamp and the measured value. I will collect 10.000 readings.
I want to display the measured data on a display (800x480) in two ways. First as a rolling graph, that scrolls from right to left and shows the last minute or so. This is working fine.
Second, I want to display all collected measurements in total (max. 10k points). So I have to shrink or compress the data, but I want to preserve the shape of the curve.
To give you an idea how it should look like, please watch the video from Dave on EEV at YT (https://youtu.be/SObqPuUozNo) and skip to 41:20. There you see how another DMM is shrinking the incomming data and displays it. At about 1:01:05 10k measurements are shown on the display area of only 400px wide.
Question is, how is this done?
I’ve heard about Douglas-Pucker algorithm, but have no idea if this is the right way and how to use it on the Arduino/ Teensy platform.
Any help is very welcome, thank you....
I cannot just display all data points, because I‘m using an FT81x as display controller, and this can take only up to 2000 drawing commands per frame. And it takes more time.
Anyway, I solved the problem using the simple way.
I create bins and calculate the min and max values in this bin. Then simply draw a line between these points. Works fine!
BTW, I‘m the TO :-)
For cases where you got many more samples than pixels in x axis instead of LineTo like graph use vertical lines graph instead...
So depending on the number of samples per rendered time frame and x resolution you should compute ymin and ymax for eaxch x and render vertical line ...
something like:
xs=800;
for (x0=x,i=sample_left,y0=y1=sample[i],i<sample_right;i++)
{
x = (i-sample_left)*xs/(sample_right-sample_left);
y = sample[i]; // here add y scaling and offset
if (x0!=x) { line(x0,y0,x0,y1); x0=x; y0=y; y1=y; }
if (y0>y) y0=y;
if (y1<y) y1=y;
}
where sample[] are your stored values , sample_left,sample_right is the range to render and xs is graph x resolution. To speed up you can pre-compute the y0,y1 for each x and render that (recompute only on range or samples change) ... So as you can see you will use just xs line commands which shoul dbe fast enough. The x linear interpolation can be done without multiplication nor division if you rewrite it to integer DDA style ...
These QAs might interest you:
plotting real time Data on (qwt )Oscillocope
i don't really understand FFT and sample rates
[note]
After a second look The deleted answer is with the same approach as this (got deleted by review probably before the edit which transformed it from not an answer (comment) to the correct answer) so I voted for undelete even if it is considerably lower quality than mine but was posted sooner.

Gradually move from one color to another

I have a program where I have a slider, and when i move it up or down (left or right) the color changes gradually. Sadly I am not able to achieve this. My colors change yes, but it is very sudden! I have the 7 colors of the rainbow on seperate .png files and when I scroll the respective one comes up. I was wondering if there was anything I could do to make the colors morph or blend into each other better to make the transaction appear muuch more smoothly.
Thank you
UPDATE
if(self.slider.value > 7 (
{
self.label.text=#"red";
//self.imgView.backgroundColor=[UIColor redColor];
// self.imgView.backgroundColor=[UIColor colorWithPatternImage:#"redPicture"];
self.view.backgroundColor=[UIColor colorWithRed:146 green:50 blue:146 alpha:1];
}
This is going to be a generalized answer because I'm not going to write your code for you (not least because I have never written a letter of xcode in my life), but this should put you on the right track.
You want a continuous spectrum of color, so that should tell you right off the bat that using a series of if statements is the wrong way to go. Instead, you should calculate the color you want by doing some math with the slider value directly.
You haven't told me what your slider range is and whether it's discrete, so for the purposes of this answer let's call the lowest value min and the highest value max, just to keep things general. So your total range is max - min. Let's express the value of your slider as a percentage along this range; we can calculate this as (self.slider.value - min) / (max - min). (For instance, for a slider that goes from 0 to 50, a slider value of 37 gives you (37-0)/(50-0) = 0.74.)
So now you should have a decimal value between 0 and 1, which you can map along the Hue-Saturation-Value color scale. I don't know if xcode has a HSV method directly (this answer has some code which might be helpful), but if not it's pretty easy to convert HSV to RGB.

How to find screen coordinates of a smaller image within a screenshot

How do you get the coordinates of a image that exists within a screenshot?
I have a screen shot that looks like this. (partial)
and I would like to find out the coordinates of the progress indicator
and the play button
My script is written in ruby and I am running OSX 10.7
Is there anything that exists that can do this?
If a brute force search is needed whats the best language to do this in?
if you know the target size then use brute force attack ...
this is pretty basic shape/pattern
so if the size is known it is quite easy and not too slow ...
1.find possible locations
create control points to check for possible location of your button
they should describe your image to discard most invalid loactions
something like this:
red dots are the control points
the less tne number of points the faster it will be
but also less precise ...
now just go through entire screen and compute
maxdiff = max(|scrpnt(i)-ctrlpnt(i)|)
avgdiff = sum(|scrpnt(i)-ctrlpnt(i)|) / n
n - is number of control points (in picture n = 11)
i = 0,1,2...n-1
if both maxdiff and avgdiff < treshold then this is possible location on button
2.test possible location
now do the check for all points of possible location arrea
if both maxdiff and avgdiff < treshold then this is button location
if the image is big enough you can speed it up by testing not all pixels at first
but with some step ... for example:
first test with step = 8px
if it pass then step = 1px
[Notes]
I do not code for your platform so I can not consider language but any with pixel access will do
I saw few similar questions here on SE in past
so if you search a bit you will probably find some solutions (try pattern recognition)

To make all peaks clearly visible in Matlab

I finally solved my problem here with lennon310.
I have a picture of thousands of thin peaks in Time-Frequency picture.
I cannot see all the same time in one picture.
Depending on the physical width of my time window, some windows appear and some come visible.
Pictures of my data which I plot by imagesc
All pictures are from the same data points T, F, B.
How can you plot all peaks at once in a picture in Matlab?
You need to resize the image using resampling to prevent the aliasing effect (that craigim described as unavoidable).
For example, the MATLAB imresize function can perform anti-aliasing. Don't use the "nearest" resize method, that's what you have now.
Extension to #BenVoigt's answer
My try
B = abs(B);
F1 = filter2(B,T); % you need a different filter kernel because resolution is lower
T = filter2(B,F);
F = F1;
image1 = imagesc(B);
display1 = imresize(image1, [600 600], 'bilinear');
imshow(T*t, F*fs, display1);
where are some problems.
I get again picture where the resolution is not enough
2nd Extension to BenVoigt's answer
My suggestion for one kernel filter is with convolution of relative random error
data(find(data ~= 0)) = sin(pi .* data(find(data ~= 0))) ./ (pi*data(find(data ~= 0)));
data(find(data == 0)) = 1; % removing lastly the discontinuity
data1 = data + 0.0000001 * mean(abs(data(:))) * randn(size(data));
data = conv(data, data1);
Is this what BenVoigt means by the kernel filter for distribution?
This gives results like
where the resolution is still a problem.
The central peaks tend to multiply easily if I resize the window.
I had old code active in the above picture but it did not change the result.
The above code is still not enough for the kernel filter of the display.
Probably, some filter functions has to be applied to the time and frequency axis separately still, something like:
F1 = filter2(B,T); % you need a different kernel filter because resolution is lower
T = filter2(B,F);
F = F1;
These filters mess up the values on the both axis.
I need to understand them better to fix this.
But first to understand if they are the right way to go.
The figure has be resized still.
The size of the data was 5001x1 double and those of F and T 13635x1 double.
So I think I should resize lastly after setting axis, labels and title by
imresize(image, [13635 13635], 'bilinear');
since the distirbution is bilinear.
3rd Extension to BenVoigt's answer
I plot the picture now by
imagesc([0 numel(T)], [0 numel(F)], B);
I have a big aliasing problem in my pictures.
Probably, something like this should be to manipulate the Time-Frequency Representation
T = filter2(B,t); % you need a different filter kernel because resolution is lower
F = filter2(B,fs);
4th extension to BenVoigt's answer and comment
I remove the filters and addition of random relative errors.
I set the size of T,F,B, and run
imagesc([0 numel(T)], [0 numel(F)], B, [0 numel(B)])
I get still with significant aliasing but different picture
This isn't being flippant, but I think the only way is to get a wider monitor with a higher pixel density. MATLAB and your video card can only show so many pixels on the screen, and must decide which to show and which to leave out. The data is still there, it just isn't getting displayed. Since you have a lot of very narrow lines, some of them are going to get skipped when decisions are made as to which pixels to light up. Changing the time window size changes which lines get aliased away and which ones get lucky enough to show up on the screen.
My suggestions are, in no particular order: convolute your lines with a Gaussian along the time axis to broaden them, thus increasing the likelihood that part of the peak will appear on the screen. Print them out on a 600 dpi printer and see if they appear. Make several plots, each zooming in on a separate time window.
3rd Extension to BenVoigt's answer
My attempt to tell imagesc how big to make the image, instead of letting to use the monitor size, so it won't away data.
imagesc(T*t, F*fs, B, [50 50]);
% imagesc(T*t, F*fs, B');
% This must be last
imresize(image, 'bilinear', [64 30],);
I am not sure where I should specify the amount of pixels in x-axis and y-axis, either in the command imagesc or imresize.
What is the correct way of resizing the image here?

Raphael animate based on position not time

I have two path elements. For the sake of description lets just say one is a heart and the other is a square with rounded corners.
I'm trying to get one to interpolate into the other like this:
http://raphaeljs.com/animation.html
This is easy enough to do but I need to do it based off the elements X position and not time.
So as I drag the path element between an Xval of 100 and 200 it will slowly morph into the second path until it finally completes the transformation at an X value of 200.
Does anyone have any idea how I might do this?
I'd use the drag handler (or you could bind to the mousemove event and feed the coordinates in as well) and use that to move between a starting position and a target animation based on the x or y coordinate and using Element.status. Check out the fiddle (based on yours):
And I'm sorry -- I gave you a copy of your own fiddle back originally. Terribly poor form =( Try this one instead:
http://jsfiddle.net/kevindivdbyzero/MqFkP/2/
So far this is what I have come up with:
http://jsfiddle.net/jocose/CkL5F/139/
This works but relies on a delay which I am afraid is going to break on slower machines, and plus it seams really hacky. If anyone knows of a better solution please let me know.

Resources