Calculate Max Width and Height - math

I need to calculate the width and height of X number of elements based on the overall width and height of the screen in pixels so I can write a function. The individual elements x and y should be the same for each element.
I know the height and width of the screen but the number of elements could vary.
For example, if I have 20 elements/buttons, I want them to take up the whole screen and likewise, if I have 10 elements/buttons, I want them to take up the whole screen.
Example: Screen is 628x1289 and I have 20 elements. How can I calculate the size of each element?
This is similar to web responsive but it's not for a web application so I need to figure out how to calculate it using the pixels.
I hope that makes sense but please let me know if it doesn't.
Steve
P.S. This seems relevant but I'm no math expert so have no idea exactly what they're saying...
https://en.wikipedia.org/wiki/Knapsack_problem
Seems like they already know the size of the objects which is the opposite to my needs. I have a space and want to know what x and y I need to set each object to fit the space.

There are too many free parameters. Make some restrictions to solve the task.
Example: Let's element proportions (width/height ratio) are equal to screen proportions
C = ScreenWidth / ScreenHeight
Now let's unknown element height is h, so width is w = C * h
So every row may contain ScreenWidth div (C * h), every column ScreenHeight div h, where div is integer division.
Now you can find solution (max h value) of inequality
numberX <= (ScreenWidth div (C * h)) * (ScreenHeight div h)
and get height and width of numberX elements filling the screen (last row might be incomplete)

Related

How to precisely find thumb position of input [type="range"]?

The idea was to put a tooltip with value related to slider. I thought initially to accomplish that task by using css grid. CSS provides you with grid of any size, 10 or 1000 cols, doesn't matter. By utilizing grid functionality, we can align out tooltip as we wish.
What we really get is:
Thumb position is sort of unpredictable. It seems that it is being offset, and the direction of that offset is dependent on whether input value is in the left or right part of slider.
Note: default thumb behaves exactly the same way. I mean, shape of thumb is not of concern.
So, how does html calculate position of thumb based on its value?
For anyone else stumbling upon this problem, the issue is that the first and last position of thumb are offset by half the width of thumb. Because of this, all of the other positions are slightly offset to compensate for the first and last one.
One simple solution for this is to normalize the thumb position between actual first and last thumb positions which are actually 0 + halfThumb and width - halfThumb respectively.
To normalize, we can use the formula recommended in this answer.
So the left offset of absolutely positioned element in px would be:
const left = (((value - minValue) / (valueMax - valueMin)) * ((totalInputWidth - thumbHalfWidth) - thumbHalfWidth)) + thumbHalfWidth;
Where
value is actual input value.
minValue is actual minimum value for input.
maxValue is actual maximum value for input.
thumbHalfWidth is half of the width of thumb used for slider drag.
totalInputWidth is width of input element in pixels.
You have to take into consideration the size of your thumb
It is possible to achieve this using a little bit of javascript (unless you can get the range ratio which I am not aware of as of now)
Therorical
Calculate the ratio of your current value relative to the min and max of your input (between 0 and 1)
(value - el.min) / (el.max - el.min)
So its position (starting from the arrow relative to the input container) would be:
thumbSize / 2 + ratio * 100% - ration * thumbSize
Method
This might give an idea of how to implement this in javascript
const thumbSize = 10
const range = document.querySelector('input[type=range]')
const tooltip = document.querySelector('.tooltip')
range.addEventListener('input', e => {
const ratio = (range.value - range.min) / (range.max - range.min)
tooltip.style.left = `calc(${thumbSize / 10}px + ${ratio * 100} - ${ratio} * ${thumbSize}px)`
}
This above code has not been tested but the same method has been implemented

Is it possible to get the screenwidth in pixels, without units, with CSS's calc()?

I'm trying to calculate a zoom-value using calc(), but since zoom only takes either a no-units value or a percentage value, I'm having a hard time getting what I want using calc().
Am I doomed to using JavaScript for this, or is there a way?
I want to calculate the ratio between an element on the page and the screen width minus a set width, so the calculation would be (screenWidth - setWidth) / elementWidth. I can get setWidth and elementWidth as plain numbers, but I can't figure out a way to get screenWidth other than 100vw, and that just ends up being (100vw - 300) / 900) => -200vw / 900 => -0.222222vw which, as you might guess, is not what I want.

Xamarin Forms - AbsoluteLayout - How does works positions

I'm working with Xamarin.Forms with AbsoluteLayout, however, I'm not sure to understand how to works the positionning of elements.
I'm working with Proportional Values so if I'm placing an element at AbsoluteLayout.LayoutBounds="1, 0.05, 0.15, 0.1" where each values is Proportional (so the flags are "all" AbsoluteLayout.LayoutFlags="All")
It will be placed at the top/right of the screen. It will not take a place a bit outside however. So what does it means? Each element are repositionned into the screen if they go outside?
But now, another question comes, when you place an element, on what is based the X/Y position? Does is the center or another point?
On this example, I tried with 0.15 but the rendering was a bit weird, so I put 0 and then the rendering match with what I want.
You could say "Test it and you'll see.", however, It's a waste of time for the designer and me, to position every elements, because we're not sure to understand how does it works. So we juste make try with debuging..
We are also searching to know if a software exist to generate positions about the design made by the designer. We mean the position X/Y of the element in percent.
Thank in advance !
With AbsoluteLayoutFlag.All, the Rectangle bounds parameters have the following meaning:
x means the percentage of the remaining space (i.e parent width - control width) which should be on the left of the control
y means the percentage of the remaining space (i.e parent height - control height) which should be on the top of the control
width is the width of the control in percentage of the parent width
height is the height of the control in percentage of the parent height
Width and height are what people usually expect. However, x and y are not as people are more used to "left" and "top". So you can write a converter to convert left percentage into x and top percentage into y:
x = left / (1 - width)
y = top / (1 - height)
<AbsoluteLayout BackgroundColor="Yellow">
<BoxView
Color="Red"
AbsoluteLayout.LayoutBounds="1.0, 1.0, 0.5, 0.5"
AbsoluteLayout.LayoutFlags="All" />
<BoxView
Color="Green"
WidthRequest="50"
HeightRequest="50"
AbsoluteLayout.LayoutBounds="0.1, 0.1, AutoSize, AutoSize"
AbsoluteLayout.LayoutFlags="PositionProportional" />
<BoxView
Color="Blue"
AbsoluteLayout.LayoutBounds="0.25, 0.25, 0.5, 0.5"
AbsoluteLayout.LayoutFlags="All" />
</AbsoluteLayout>
When I researched AbsoluteLayout I created this sample and
Test it and you'll see
What I've decided from my investigation:
X and Y are coordinates of top left corner of View. It's relative position. As you can see for red rectangle 1.0, 1.0 is center position, so, as I understand, 100% width of screen is 2.0(same for height). All views inside AbsoluteLayout positioned dependently on values of parent AbsoluteLayout.
Edited:
X and Y are center coordinate of View, not left top corner. And 100% of Width is 1.0.
I did some testing and found that,With AbsoluteLayoutFlag.All, essentially the X value given as a Percentage basically represents where the anchor is on a rectangle. As in if X = 10% then the anchor is 10% from the left of the Rectangle:
example
At X = 0.1 with a given width of 20%. 90% of the length will go to the right and 10% will go to the left.
At X = 0.5 with a given width of 20%. 10% will go to left and 10% to the right.
Formula for X bounds
Variables in Rectangle (Ax, Ay, Wx, Wy):
W - required width
Ax - X value. (anchor position)
X1 - X position value of top left corner relative to left side (X = 0)
X2 - x position value of top right corner relative to left side (X = 0)
The Formula has 5 possible scenarios for an Anchor value
Ax = 0:
X1 = 0 & X2 = Wx
Ax = 1:
X2 = 1 & X1 = (1 - Wx)
Ax = 0.5
X1 = Ax - (0.5)(Wx)
X2 = Ax + (0.5)(Wx)
0 < Ax < 0.5
X1 = Ax - (Ax)(Wx)
X2 = Ax + (1 - Ax)(Wx)
0.5 < Ax < 1
X1 = Ax - (Ax)(Wx)
X2 = Ax + (1-Ax)(Wx)
X && Y are the center of the element
As a late answer, I've put a nuget package with a fork of AbsoluteLayout but working as I'd expect.
Install nuget package SmartMachines.AbsoluteLayout, add namespace xmlns:sm="clr-namespace:SmartMachines;assembly=AbsoluteLayout" and you will have exactly same AbsoluteLayout as native Xamarin, but with expected Proportional alignment behavior.
Hope that will save other people several hours on googling and debugging.
With AbsoluteLayout.LayoutFlags="All", the LayoutBounds (x, y, width, height) should be interpreted as follows:
width and height simply represent the respective dimensions of the child as a proportion of the AbsoluteLayout's overall size. For example, a width of 0.1 would create a child 10% of the width of the layout, 0.9 would cover 90% and 1.0 will fill the parent from left to right.
x and y represent the position within the parent, relative to the extremes of movement possible with the child still wholly visible within the layout. So: an x value of 0.0 places the left edge of the child against the left edge of the layout container and a value of 1.0 aligns the child's right edge with the container's right edge. Values between 0 and 1 represent positions between those extremes, moving the child proportionately through the range of movement available to it when the child is kept completely within the layout.
A nice way to think about the x / y positioning is to compare it with a window scroll bar or a value slider control because the whole scroll bar is visible at all times and it can be thought of as sliding between a value of 0 (document at top) and 1 (document at bottom).
Needless to say, centring a child is done by setting x or y to 0.5, regardless of width or height values.

Calculating Largest Possible Rectangle

I'm uploading some images to website. They're all sorts of different dimensions. How can I determine the largest 4:3 rectangle that I could get out of that particular image without rotating the image?
If the aspect ratio is less than 4:3, keep the original width and use a height of width*3/4. If the aspect ratio is greater than 4:3, keep the original height and use a width of height*4/3.
IIUC this problem is very similar to the common problem of maximizing an image in a given rectangular area.
Supposing your screen is W * H pixels (with W = 4 * H / 3) and that the image is dx * dy then you can stretch the image to maximize it inside the screen using a scale factor of
sf = min(W / dx, H / dy)
because W / dx would be a scale factor that makes the image the same width of your screen and H / dy would be the scale factor that make it the same height instead.
Taking the minimum of the two will ensure that the image can entirely fit and that no pixel will get outside the screen... taking the maximum instead will ensure that the screen will be completely covered with (part of) the image and could be useful if you are trying to get a wallpaper out of an image.
Once you have the scale factor the formulas needed for centering are easy:
x0 = (W - dx * sf) / 2
y0 = (H - dy * sf) / 2
and you simply need to draw the image scaled by sf starting at position (x0, y0).
First rotate your image so that its aspect ratio is at least 1. Now if your aspect ratio is larger than 4/3, keep the height and crop the width; if the aspect ratio is smaller, keep the width and crop the height.

How to compute viewport from scrollbar?

This is probably straight forward enough but for some reason I just can't crack it (well actually its because I'm terrible at maths sadly!).
I have a viewport that shows 800 pixels at a time and I want to move it left and right over a virtual number of pixels say 2400 pixels wide.
I use the relative position of a scrollbar (0-1) to determine the virtual pixel that the viewport should have moved to.
I have a loop n = 800 that I run through.
I want to start reading an array of plottin points from the position the slider tells me and iterate through the next 800 points from that point.
The problem I have is when my scrollbar is all the way to the right and its relative position = 1 my readpoint = 2400..... which in a way is right. But that makes my read position of plotting points go to the last point and when I begin my iteration I have no points left to read.
Based on my moving an 800 pixel wide sliding box analagy the left point of the box should be 1600 in this case and its right point should be 2400
How can I achieve this?
Do I need some sort of value mapping formula?
private function calculateShuttleRelativePosition():void
{
var _x:Number=_scrollthumb.x
_sliderCenter=_x + (_scrollthumb.width / 2)
_sliderRange=_scrollbar.width - _scrollthumb.width;
_slider_rel_pos=(_sliderCenter - _sliderCenterMinLeft) / _sliderRange
}
pixel = slider relative position * 2400
readpoint= pixel
The range of your scrollbar should be the range that the left most pixel can take, not the range of all the pixels.
So your range would be 1600 (2400 - 800), not 2400 alone. This is the scaling factor you should apply to determine your offset.
As a word of warning always be on the lookout for off by one errors in these kinds of things. Since your bar ranges from 0 to 1 your outputted pixels will range from 0 to 800 if you are not careful, which could overflow your array if you don't watch out :).
The answer is actually pretty easy -- instead of making the relative position slide across the entire width (which is what you have above), you start at 0 and run to width - 800 (or the width of your viewport).
Some C-ish code for that would look like:
int viewPortWidth = 800;
int virtualWindowWidth = 2400;
// I'm assuming your code above is right -- I didn't check
float sliderRelativePosition = calculateShuttleRelativePosition();
// The casts (int and float here), make sure that you're rounding down to an integer
// pixel between 0 and virtualWindowWidth - 1, inclusive
int pixel = (int)(sliderRelativePosition * (float)(virtualWindowWidth - viewPortWidth - 1));
readPixels(pixel, viewPortWidth); // Function that loops through the pixels you want

Resources