Find scale amount based on new dimensions - javascript

If I have an image that has 100 x 100 size, then I resize it to 200 x 200, how can I calculate how much it was scaled?
In this example the scale amount would be 2.0. How can I get that number from the known variables (original size, new size) ?

Simply divide the new height by the original height and divide the new width by the original width...
double xfactor = (double)NewImage.Height / (double)OldImage.Height;
double yfactor = (double)NewImage.Width / (double)OldImage.Width;

Related

Ortographic Camera Aspect Ration on Resize

Is there anyway to setup an ortographic camera in THREE.JS such that:
1)It mantains a constant aspect ratio. Even when I aply a resize to the window. This aspect ratio whould be constant throughout, and not related to the window dimensions and aspect ratio, and avoid distortion.
2)The scene is always completely visible, no matter the size of the window.
Thank you very much!
Let's assume that you have your current camera and you want to make sure that your entire scene fits in its view. The variables that you can change in an OrthographicCamera are left, right, top, bottom, near, far. You usually want to make sure that left = -right and top = -bottom. And you need to make sure that the ratio is equal to the aspect ratio of the window. Thus, all you can change is essentially a single scale value.
What we are going to do to determine this is the following: We take all the points in our scene and transform them into camera space. Then, the minimum and maximum of x, y, and z, respectively, give us the minimum bounds for the camera. And then we just need to make sure that the aspect ratio is correct.
Now, doing this for all points is usually too computationally heavy. Instead, we could approximate our scene with a bounding sphere of radius r centered at c. You can either calculate those once at the beginning of your application or save them with the scene. And then, instead of making sure that the scene fits in the view, we make sure that the entire bounding sphere fits in the view.
Doing this for an orthographic camera is actually pretty simple. We just need to transform the center of the sphere into camera coordinates:
var cInCameraSpace = new THREE.Vector3(); //do this once at initialization
//transform sphere center to camera space
cInCameraSpace.copy(c);
cInCameraSpace.applyMatrix4(camera.matrixWorldInverse)
And then we can find the bounds:
var halfWidth = Math.abs(cInCameraSpace.x) + r;
var halfHeight = Math.abs(cInCameraSpace.y) + r;
camera.near = -cInCameraSpace.z - r;
camera.far = -cInCameraSpace.z + r;
Now, lets make sure that we preserve aspect ratio. I assume that we already know the window's aspect ratio as windowAspect.
if(halfWidth / halfHeight > windowAspect) {
camera.right = halfWidth;
camera.top = halfWidth / windowAspect;
} else {
camera.top = halfHeight;
camera.right = halfHeight * windowAspect;
}
camera.bottom = -camera.top;
camera.left = -camera.right;

Three.js: How do I scale and offset my image textures?

How do I scale and offset my image textures?
My image dimensions is 1024px x 1024px.
var textureMap = THREE.ImageUtils.loadTexture( 'texture.png' );
Have a look at the texture documentation:
.repeat - How many times the texture is repeated across the surface, in each direction U and V.
.offset - How much a single repetition of the texture is offset from the beginning, in each direction U and V. Typical range is 0.0 to 1.0.
.wrapS - The default is THREE.ClampToEdgeWrapping, where the edge is clamped to the outer edge texels. The other two choices are THREE.RepeatWrapping and THREE.MirroredRepeatWrapping.
.wrapT - The default is THREE.ClampToEdgeWrapping, where the edge is clamped to the outer edge texels. The other two choices are THREE.RepeatWrapping and THREE.MirroredRepeatWrapping.
NOTE: tiling of images in textures only functions if image dimensions are powers of two (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ...) in terms of pixels. Individual dimensions need not be equal, but each must be a power of two. This is a limitation of WebGL, not Three.js.
Example of scale:
// scale x2 horizontal
texture.repeat.set(0.5, 1);
// scale x2 vertical
texture.repeat.set(1, 0.5);
// scale x2 proportional
texture.repeat.set(0.5, 0.5);
Offset with texture.offset.set(u, v); where u and v are percents (e.g. 0.67).
There's not a specific scale method, but it's basically the arguments to .repeat(): texture.repeat.set(countU, countV). Smaller numbers will scale bigger: consider fitting 2 vs fitting 20 across the same axis.

Detecting mouse proximity in processing.js

I am coding with processing.js. I want the size variable to get greater as the cursor (mouse) approches the ellipse and to get smaller as the cursor moves away from the ellipse. The size should (if possible) be limited between minimum 50 and maximum 200. Is there any way to accomplish that ?
I've looked online, but there doesn't seem to be lots of documentation (at least for what I was searching for) about this.
Here is my code :
void setup()
{
// Setting up the page
size(screen.width, screen.height);
smooth();
background(0, 0, 0);
// Declaring the variable size ONCE
size = 50;
}
void draw()
{
background(0, 0, 0);
// I want the size variable to be greater as the cursor approches the ellipse and to be smaller as the cursor moves away from the ellipse. The size is limited if possible between 50 and 200
// Here is the variable that needs to be changed
size = 50;
// Drawing the concerned ellipse
ellipse(width/2, height/2, size, size);
}
Thanks.
First, you need to get the distance from the mouse to the ellipse:
float distance = dist(mouseX,mouseY, width/2,height/2);
Then, you need to convert that distance into a more usable range. We'll call the result dia, since size() is also the name of a command in Processing. We also want dia to get larger as the distance gets smaller.
For both those things, we'll use map() which takes an input value, it's range, and an output range:
float dia = map(distance, 0,width/2, 200,50);
When distance is 0, dia = 200 and when distance is the width of the screen divided by 2, dia = 50.

Calculating axis length in proportion to fixed related length

Basics
I am working on a small tool that is supposed help with some geometric calculations for print-related products.
Overview
I have two inputs (w and h) where the user is supposed to enter a width and a height for a box. This box is supposed to be a representation of the users measurements as a small CSS-based box.
The problem is that I cannot just take the measurements and apply them as pixels, or even pixels * 10, or anything, as width/height for the display box, because my space is limited.
The box can have a maximum measurement of 69 x 69.
What I want to achieve is that to apply the longer entered measurement to its according axis, then calculate the other axis in proportion to this.
My approach
I am not a maths person at all. But I did my best and I put together a function that will accomplish the above:
updateRectBox: function(w, h){
// define maximum width and height for box
var max_x=69;
var max_y=69;
var factor,x,y;
factor=w/h;
if(w==h){
// if we have a 1:1 ratio, we want the box to fill `69px` on both axis
x=max_x;
y=max_y;
} else {
if(w>h){
// if width is larger than height, we calculate the box height using the factor
x=max_x;
y=(factor>1 ? max_y/factor : max_y*factor);
} else {
// if height is larger than width, we calculate the box width using the factor
x=(factor>1 ? max_x/factor : max_x*factor);
y=max_y;
}
}
// using this to set the box element's properties
jQuery('#rect').css({
'width': (x)+'px',
'height': (y)+'px'
});
}
This function works well, but:
Question
I know this can be done more beautifully, with less code. But due to my lack of math skills, I just cannot think of anything more compact than what I wrote.
I've created a working fiddle to make it easier for you to test your optimizations.
Your function accomplishes exactly what it needs to. There are ways which are arguably more elegant to write, however.
The basic idea is that you have a box with dimensions (w × h) and you want a box which is a scaled version of this one to fit in a (69 × 69) box.
To fit in a (69 × 69) box, your (w × h) box must be less than 69 wide, and less than 69 tall. Suppose you scale by the quantity s. Then your new box has dimension (s * w × s * h). Using the above constraint, we know that:
s * w <= 69 and that s * h <= 69. Rewrite these, solving for s, and you get:
s <= 69 / w and s <= 69 / h. Both must hold true, so you can rewrite this as:
s <= min( 69 / w, 69 / h). In addition, you want s to be as large as possible (so the box completely fills the region) so s = min( 69 / w, 69 / h).
Your code accomplishes the same, but through if-statements. You can rewrite it considerably terser by doing:
updateRectBox: function(width, height) {
// define maximum width and height for box
var max_width = 69;
var max_height = 69;
var scale = Math.min( max_width / width, max_height / height );
var x = scale * width;
var y = scale * height;
// using this to set the box element's properties
jQuery('#rect').css({
'width': x+'px',
'height': y+'px'
});
}
Changing the variable names helps make it slightly more readable (w and h presumably do mean width and height, but making this explicit is helpful).
All this said, it's unlikely that there will be noticeable performance differences between this and your original. The code is extremely fast, since it does very little. That said, I made a jsperf which shows that using Math.min is about 1.7 times faster on my browser.

Javascript scale check function performance

All right people, I've got a slight performance bottle neck.
Basically I have a graph that consists of a screen div ("screen") and a chart div ("chart"), when this graph finishes rendering it checks to see what scale it needs to set on the chart in order to have the chart fit inside the screen. The problem is that whatever scale I come up with needs to be an exponent of 1.2. In other words you need to be able to get to the number of the new scale by taking 1.2 to the power of some number.
This function is what calculates the scale I need.
fitScale = function (width, height)
{
var scale = 1,
gWidth = graph.element.offsetWidth,
gHeight = graph.element.offsetHeight;
while (gWidth > width * scale && gHeight > height * scale)
scale *= 1.2;
while (gWidth < width * scale || gHeight < height * scale)
scale /= 1.2;
return 900 / scale;
}
The problem is that this sucks...
What it's doing is getting the chart size (width, height) and the screen size (gWidth, gHeight) and looping through a new scale until it hits the right number.
First it makes the scale bigger until at least one dimension of the chart times the scale is bigger than one dimension of the screen.
Than it loops back to make sure that both the dimensions of chart * scale are at least a little bit smaller than the screen.
I'de like to perform this action with just one math calculation. Maybe by calculating a snug fit and then by rounding down, but I can't figure out how to round down to an exponent of 1.2
-fix-
Here's the resulting working version...
fitScale = function (width, height)
{
var wScale = graph.element.offsetWidth / width,
hScale = graph.element.offsetHeight / height,
snugg = wScale < hScale ? wScale : hScale,
exp = Math.log(snugg) / Math.log(1 / 1.2),
scale = Math.pow(1 / 1.2, Math.ceil(exp));
return 900 / scale;
}
My math skills are rusty, so go easy if I wander off the Path of Truth here.
Basically you want to know what power y of 1.2 is equal to some given number x. While the log function would appear not to be helpful since it tells you what power of e will equal your number x, with some mad logarithm skillz you can in fact use that to get to where you want to go:
var y = Math.log(x) / Math.log(1.2);
Odds are pretty good that y won't be a whole number which is I think what you want, so if you just go ahead and Math.floor(y), you should be all set.

Categories

Resources