Query Mongoid for all circle areas that include a given point - ruby

Let say I have two classes:
class Cirle
include Mongoid::Document
field :lat, type: Float
field :lon, type: Float
field :radius, type: Integer
end
class Point
include Mongoid::Document
field :lat, type: Float
field :lon, type: Float
end
How can I find all Circles that include a given Point?

I'm not familiar with Mongoid, but perhaps the following will help. Suppose:
circles = [
{ x: 1, y: 2, radius: 3 },
{ x: 3, y: 1, radius: 2 },
{ x: 2, y: 2, radius: 4 },
]
and
point = { x: 4.5, y: 1 }
then the circles containing point are obtained with the help of Math::hypot:
circles.select { |c|
Math.hypot((c[:x]-point[:x]).abs, (c[:y]-point[:y]).abs) <= c[:radius] }
#=> [{ x: 3, y: 1, radius: 2 }, { x: 2, y: 2, radius: 4 }]
Edit: to improve efficiency as #Drenmi suggests:
x, y = point.values_at(:x, :y)
circles.select do |c|
d0, d1, r = (c[:x]-x).abs, (c[:y]-y).abs, c[:radius]
d0*d0 + d1*d1 <= r*r
end

Related

Get coordinate with NaN at x axis

i got the following block of code to generate a new enemy each 1.5.
each new enemy is added to an array using scan operator
i did the replace suggested.
i did a small change to be able to replicate
const enemies$ = rxjs.from([0,1])
.pipe(
rxjs.scan( (enemyArray) => {
const enemy = {
x: Math.floor(Math.random() * 100),
y: -30
}
console.log(enemy)
enemyArray.push(enemy);
console.log(enemyArray); //debug.
return enemyArray;
}, [])
);
enemies$.subscribe(
(enemies) => console.log(enemies)
);
The result in the console is the following for the first element (enemy)
{x: 312, y: -30}
But when the enemy is added to enemyArray , the following results are shown in the console
(1)[{...}]
0: {x: NaN, y: 515}
1: {x: NaN, y: 65}
length: 2
[[Prototype]]: Array(0)
parseInt() takes a string as the first argument, so it should be
parseInt(String(Math.random() * 100), 10)

How to animate something at the same time in GASP?

I want to animate these two things at the same time, and not one by one.
t1.fromTo(searchForm, { scaleX: 0 }, { duration: 1, autoAlpha: 1, scaleX: 1 });
t1.fromTo(loupe, {x: '-=0'}, {duration: 1, x: '+=265'})
I want to move them together; how can I do that?
Just use the position parameter to position your tween(s) wherever you want in the timeline.
t1.fromTo(searchForm, { scaleX: 0 }, { duration: 1, autoAlpha: 1, scaleX: 1 });
t1.fromTo(loupe, {x: '-=0'}, {duration: 1, x: '+=265'}, 0);
There's more info about the position parameter at https://greensock.com/position-parameter.
Also, there's no reason to use a .fromTo() in the second case because x: "-=0" does absolutely nothing, so you can just to a normal .to() tween and omit that whole object.
Happy tweening!

What is the attribute for a uicontrol object equivalent to deprecated uititle method

I want to pretty much replicate the GUI implemented here:
and here is what I have got so far:
// first create the GUI panel
figw = 220;
figh = 160;
close(1)
f = figure(1, "position", [0 0 figw figh]);
//PUSH TO STOP
hstop = uicontrol(f, "style", "pushbutton", "Min", 0, "Max", 1, "string", " STOP",..
"position", [10 10 61 50], "callback", "infiniteloop=%F");
// TRIGGERED MODE
htrig = uicontrol(f, "style", "radiobutton", "Min", 0, "Max", 1, "string", "free/trig", "value", 0,..
"position", [80 10 20 20]);
//httrig=uititle(htrig,"free/trig","r")
// BINNING x2
hbin = uicontrol(f, "style", "radiobutton", "Min", 0, "Max", 1, "value", 0,..
"position", [80 40 20 20]);
//htbin=uititle(hbin,"bin x2","r")
// GREYSCALE
hbri = uicontrol("style", "slider", "Min", 1, "Max", 255, "value", 128,..
"position", [10 70 200 20]);
//htbri=uititle(hbri,"greyscale")
// EXPOSURE (only for untriggered)
hexp = uicontrol("style", "slider", "Min", 1, "Max", 1200, "value", 40,..
"position", [10 120 200 20]);
//htexp=uititle(hexp,"exposure time")
my main issue at this moment is that I can't find the equivalent attribute / property for the uicontrol objects which corresponds to the deprecated uititle method.
I could indeed use textboxes and find a workaround but that's not the ideal solution given all the positioning headaches. I was wondering if there is still such an attribute which accepts a stering and the put in the described position like r, t, l and b? Thanks for your help in advance.
The famous uititle from Enrico Segre (emeritus Scilab contributor) could reborn like this, thanks to new layout features of uicontrols:
function t=uititle(h,text)
pos = h.Position;
pos(4)=pos(4)*2;
f = uicontrol("style","frame","position",pos,"layout","grid")
lay_opt = createLayoutOptions("grid", [2,1])
set(f,"layout_options",lay_opt);
c = createConstraints("grid");
h.parent = f;
t=uicontrol(f,"style","text","string",text,"horizontalalignment","center",...
"constraints",c);
endfunction
clf
sl=uicontrol("style","slider","position",[10 10 200 20])
uititle(sl,"a slider")

find upper face of cube on demand

The general problem I'm trying to solve is to find out what face of a cube faces upwards. The cube can be rolled 90° at a time and in any direction. If a certain face faces up, the cube disappears. I'm working with tweens to rotate the cube and change the position of it.
I'm currently trying to solve this by creating a new ray, with its origin set just above the cube and its direction going downwards for a short distance, so it intersects with the upper face of the cube only.
violet thingy on top of die is ray cast downward into the cube
So far so good. I get my cube as the object of intersection when I check per console.log(), but as soon as I try to access the face of intersection by faceIntersect.face it seems to be undefined.
Function in question:
function checkUpperFace(posX, posZ) {
// get position from passed x- and z-values (y is always above cube)
// and set direction and length of ray
var position = new THREE.Vector3( posX, 3, posZ );
var direction = new THREE.Vector3(0, -1, 0);
var far = 2;
// create ray, that goes downwards from above the cube
var cubeRaycaster = new THREE.Raycaster( position, direction, 0, far );
// get intersection with upper face of rolled cube
var faceIntersect = cubeRaycaster.intersectObject( currentCube );
// add a helper to see the ray
var arrowHelper = new THREE.ArrowHelper( direction, position, far, 0x770077 );
scene.add( arrowHelper );
console.log(faceIntersect); // object is shown with everything I want to know
console.log(faceIntersect.face); // is shown to be undefined
}
In the end I did it in a way #unx recommended but I really wanted to avoid the huge if-else statement, so I did it with an array rotationLibrary that has all possible rotations with the corresponding top face of the die. But because of the tween I use to rotate and move the die its rotation values are not really on point and therefore hard to compare to fixed rotation values as I use them in the array.
So I "normalize" the rotation values of the die to values I can use to compare them to my values in rotationLibrary. The last step is to store/update the result on what face is on top in the cube object itself, so I can get it whenever I want.
// spawn condition:
// 1 on top, 2 facing camera, 3 facing right (seen from camera),
// 4 facing left (see 3), 5 facing away from camera, 6 facing down
var rotationLibrary = [
{x: 0, y: 0, z: 0, face: 1},
{x: 0, y: 90, z: 0, face: 1},
{x: 180, y: 0, z: 180, face: 1},
{x: 0, y: -90, z: 0, face: 1},
{x: -90, y: 0, z: 0, face: 2},
{x: -90, y: 0, z: 90, face: 2},
{x: -90, y: 0, z: 180, face: 2},
{x: -90, y: 0, z: -90, face: 2},
{x: 0, y: 0, z: 90, face: 3},
{x: 90, y: 90, z: 0, face: 3},
{x: -90, y: -90, z: 0, face: 3},
{x: -90, y: 90, z: 180, face: 3},
{x: 180, y: 0, z: -90, face: 3},
{x: 0, y: 0, z: -90, face: 4},
{x: 90, y: -90, z: 0, face: 4},
{x: -90, y: 90, z: 0, face: 4},
{x: 180, y: 0, z: 90, face: 4},
{x: 90, y: 0, z: 0, face: 5},
{x: 90, y: 0, z: -90, face: 5},
{x: 90, y: 0, z: 180, face: 5},
{x: 90, y: 0, z: 90, face: 5},
{x: 90, y: 90, z: 90, face: 5},
{x: 0, y: 0, z: 180, face: 6},
{x: 180, y: -90, z: 0, face: 6},
{x: 180, y: 90, z: 0, face: 6},
{x: 180, y: 0, z: 0, face: 6}
];
function checkRotationsToGetUpperFace(cube) {
// create object with "normalized" (brought to quarter-circle-degree-values) degrees
var normalizedRotation = {
x: 0,
y: 0,
z: 0
};
normalizedRotation.x = getNormalizedDegree(cube.rotation._x);
normalizedRotation.y = getNormalizedDegree(cube.rotation._y);
normalizedRotation.z = getNormalizedDegree(cube.rotation._z);
// go through the library that has all the degrees with the corresponding upper face
for (var i = 0; i < rotationLibrary.length; i++) {
// check if the objects match, then get the face
if (rotationLibrary[i].x == normalizedRotation.x &&
rotationLibrary[i].y == normalizedRotation.y &&
rotationLibrary[i].z == normalizedRotation.z) {
cube.face = rotationLibrary[i].face;
}
}
// reattach cube for correct movement later
THREE.SceneUtils.attach(cube, scene, pivot);
}
function getNormalizedDegree(rotationValue) {
// transform rotation value into degree value
var rotValue = rotationValue / (Math.PI / 180);
// default value is 0, so only check if it should be 90°, 180° or -90°
var normalizedDegree = 0;
// x between 45° and 135° ( ~ 90)
if (rotValue > 45 && rotValue < 135) {
normalizedDegree = 90;
}
// x between -45° and -135° ( ~ -90)
else if (rotValue < -45 && rotValue > -135) {
normalizedDegree = -90;
}
// x between 135° and 215° or x between -135° and -215° ( ~ 180)
else if ((rotValue > 135 && rotValue < 215) || (rotValue < -135 && rotValue > -215)) {
normalizedDegree = 180;
}
return normalizedDegree;
}
(http://jsfiddle.net/b2an3pq7/3/)
Might not be the solution to your raycast problem but another approach: Why don't you simply detect the upper face by comparing the rotation euler angles? E.g. (pseudo code):
if(cube.rotation.x % 360 == 0)
{
// upper face upwards
}
else if(cube.rotation.x % 360 == 90)
{
// left face upwards
}
You would have to deal with value tolerance (85° - 95°) negative rotation values and values out of the range of PI*2 but other than that, isn't that much easier?

Compare two images in terms of width and height

EDIT: I believe I didn't state correctly my question, so here is the edit.
I want to be able to compare (and score) a set of images with one image in terms of width and height.
Ideally, I would have a BASE_SCORE value (for example 100) that would be used in order to score each image depending on how close they look to the main image (in terms of width and height).
So, if for example, the main image looks like {:width => 100, :height => 100}, and set_images look like [{:width => 100, :height => 100}, {:width => 10, :height => 40}], the first element would have a score of BASE_SCORE, because they look exactly the same.
I fail to see how to compare width/heights in order to score each element of set_images.
Is there a problem with just using the Euclidean distance? Zero represents equality:
def euclidean_distance(a, b)
dx = a[:width] - b[:width]
dy = a[:height] - b[:height]
Math.sqrt((dx * dx) + (dy * dy))
end
test_subject = { width: 200, height: 50 }
samples = [
{ width: 100, height: 100 },
{ width: 80, height: 200 },
{ width: 200, height: 50 },
{ width: 10, height: 10 }
]
distances = samples.map { |s| euclidean_distance(test_subject, s) }
samples.zip(distances) { |img, dist| puts "#{img[:width]}x#{img[:height]} => #{dist}" }
Output:
100x100 => 111.80339887498948
80x200 => 192.09372712298546
200x50 => 0.0
10x10 => 194.164878389476
You can then use sort easily enough:
sorted = samples.sort { |a, b| euclidean_distance(test_subject, a) <=> euclidean_distance(test_subject, b) }
Something like this seems to work. Excuse the formatting...
$ cat foo.rb
require 'pp'
main_image = {:width => 100, :height => 50}
set_of_images = [{:width => 200, :height => 300, :id => 2},
{:width => 100, :height => 50, :id => 9}]
aspect_ratio = main_image[:width] / main_image[:height].to_f
sorted_images = set_of_images.
map{|i| i[:score] = (aspect_ratio - i[:width]/i[:height].to_f).abs; i}.
sort_by{|i| i[:score]}
pp sorted_images
$ ruby foo.rb
[{:width=>100, :height=>50, :id=>9, :score=>0.0},
{:width=>200, :height=>300, :id=>2, :score=>1.3333333333333335}]

Resources