Arranging four points as a square - php

This is prob more of a geometry question, but
I have an array of 4 points (from user input), that could be in any order.
I'm trying to work out a procedure that would return what each point is likely to be, i.e.
top left,
top right,
bottom left,
bottom Right
I'm working in PHP now, but any help in any language is fine.
{'Ill add what i've got so far in PHP shortly}
Would this question be better asked on another stackexchange, math maybe?

You could sort the points by their x coordinates ascending and if there's a tie, the y coordinate ascending.
The first two points are the "left" side - the one with the greater y is the "top" and the other is "bottom".
The last two points are the "right" side, same deal.
This won't work for a diamond though! (But what's "top-left" on a diamond anyway?)
In general, for a convex set of points, you can calculate the centroid (x value is the average of all x values, y value is the average of all y values).
Then, you can calculate the argument (i.e. angle) of the line between the centroid and the point, being arctan2 of (y_pt-y_centroid,x_pt-x_centroid).
If you then sort the points by their arguments, they'll be in anticlockwise order, with -pi being the West point of the compass, 0 being the East, wrapping around again to +pi being the west point.

You could sort the points first vertically and call the top 2 points top points and the bottom 2 bottom points. Then sort the points horizontally and call the two right-most points right and the other two left. Now you have one of each.

The two-points with the lowest x-values make up the left-side, the other two make up the right.
Same goes for y and top/bottom.

Related

How do I determine the optimum variable weights when ranking the "best" candidate for a prize

Consider I am writing a program to objectively select a winner in a competition. There are 'n' human judges secretly assigning a 1st, 2nd, 3rd position ranking to the top three candidates from a pool of 'm' candidates.
The program must then go through the judges decisions, and based on weights assigned to 1st place, 2nd place and 3rd place, each candidate will be rated based on the number of 1st, 2nd, and 3rd place votes they received, multiplied by the appropriate rating for each finishing position.
However, at the start, the program has no idea of what weights are appropriate, so I have created an automated "program" that is intended to "discover" the proper weights based on how the judges would pick the winner from a hypothetical situation.
I present a table where the horizontal axis contains the finishing position, and the judges' codes (e.g. Judge W, Judge X, Judge Y, Judge Z). The vertical axis has three rows (1st place, 2nd place, 3rd place), and at the intersection of each Judge/Row, I have randomly generated a candidate ID (from the set A through F).
After rendering the table, I then ask the judge who THEY would have chosen as the winner (the judge has the option to PASS if there is not sufficient information to choose).
After the judges run through an appropriate number of scenarios, I wish to now take the results of the various runs and use that information to determine the "best fit" for the weighting of 1st, 2nd, and 3rd positions.
Let's say one of the hypothetical grids looks like this:
<table border="1"><tbody><tr><th>Position</th><th>Judge 'W'</th><th>Judge 'X'</th><th>Judge 'Y'</th><th>Judge 'Z'</th></tr><tr><td>1st</td><td><center>A</center></td><td><center>F</center></td><td><center>C</center></td><td><center>B</center></td></tr><tr><td>2nd</td><td><center>D</center></td><td><center>B</center></td><td><center>E</center></td><td><center>D</center></td></tr><tr><td>3rd</td><td><center>C</center></td><td><center>E</center></td><td><center>B</center></td><td><center>C</center></td></tr></tbody></table>
and the human judge picks candidate "B" as the winner. My program should react by calculating the (w1 + w2 + w3) > (w1 + 2w3) (i.e. B better than C) and (w1 + w2 + w3) > (2 w2) (i.e. B better than D), etc.
From these various algebraic comparisons, over a number of "hypothetical scenarios", I want to be able to calculate the optimum values for w1, w2 and w3. And then, at some point when there is enough "good" data, I want to be able to use these "discovered" weights to go back over the training data an identify areas where perhaps the human judges were mistaken.
I am using PHP as the programming language and don't know which functions or possible existing libraries are appropriate to solve this kind of "fuzzy" equation.
I'm looking for some direction to help me tackle this problem.
Thank you for your assistance.
For the winning candidate count how many times he appears in each position, then do the same for all the other candidates. Then write the following formula for each candidate:
GoodForJ=w1*nw1+w2*nw2+w3*nw3>w1*nj1+w2*nj2+w3*nj3
Where nw1-3 are the times the winner appears in each position and nj1-3 are the times the j candidate appears in each position.
If goodForJ is true for all the candidates this means that the tuple of weights is good. Now you just have to try a bounch of weights combinations and find out which one fits. Trying all combinations of weights between 1 and 10 requires 1000 iterations.
To make things a bit fuzzier, for each try you could count how many timrs goodForJ is true and choose the weights that produces the highest score.

How to make a Random Walk, PHP?

I've been trying for several hours to make a random walk (a path) like this one.
From top to down.
x 1 x
x 2 3
x x 4
7 6 5
8 x x
9 10 x
My greatest difficulty is to calculate the displacement from right to left because the cycles (for, while..) go from left to right.
I am not proficient in math, so I'm using a simple approach.
I have two arrays. One with the position of the previous row.
$previousRow=array(1=>"x",2=>"1",3=>"x");
One with the current row I have to fill.
$currentRow=array(1=>"",2=>"",3=>"");
$p //Is the current position. 1, 2 or 3. Example $currentRow[$p]
$last //the last number that increases each time the path has a new step.
I'm using some cycles and conditions to set the displacement.
Is this approach wrong?
EDIT: further specifications as requested from comments:
Start point is located in the middle point of the first row
End point is located in the last row
End point can be located in any column of the last row
per each field you have three possibilities: left, right, forward.
some cases reduce this, e.g. there is no field to the left or right or that field was visited already.
so find out about possible moves, pick one at random and go on.

Searching for matrix way finding algorithm

i am developing a board game in php and now i have problems in writing an algorithm...
the game board is a multidimensional array ($board[10][10]) to define rows and columns of the board matrix or vector...
now i have to loop through the complete board but with a dynamic start point. for example the user selects cell [5,6] this is the start point for the loop. goal is to find all available board cells around the selected cell to find the target cells for a move method. i think i need a performant and efficient way to do this. does anyone know an algorithm to loop through a matrix/vector, only ones every field to find the available and used cells?
extra rule...
in the picture appended is a blue field selected (is a little bigger than the other). the available fields are only on the right side. the left side are available but not reachable from the current selected position... i think this is a extra information which makes the algorithm a little bit complicated....
big thx so far!
kind regards
not completely sure that I got the requirements right, so let me restate them:
You want an efficient algorithm to loop through all elements of an nxn matrix with n approximately 10, which starts at a given element (i,j) and is ordered by distance from (i,j)!?
I'd loop through a distance variable d from 0 to n/2
then for each value of d loop for l through -(2*d) to +(2*d)-1
pick the the cells (i+d, j+l), if i>=0 also pick (i+l,j-d),(i+l, j+d)
for each cell you have to apply a modulo n, to map negativ indexes back to the matrix.
This considers the matrix basically a torus, glueing upper and lower edge as well as left and right edge together.
If you don't like that you can let run d up to n and instead of a modulo operation just ignore values outside the matrix.
These aproaches give you the fields directly in the correct order. For small fields I do doubt any kind of optimization on this level has much of an effect in most situations, Nicholas approach might be just as good.
Update
I slightly modified the cells to pick in order to honor the rule 'only consider fields that are right from the current column or on the same column'
If your map is only 10x10, I'd loop through from [0][0], collecting all the possible spaces for the player to move, then grade the spaces by distance to current player position. N is small, so the fact that the algorithm has O(N^2) shouldn't affect your performance much.
Maybe someone with more background in algorithms has something up their sleeve.

What is the most efficient way to find the euclidean distance in 3d using mysql?

I have a MySQL table with thousands of data points stored in 3 columns R, G, B. how can I find which data point is closest to a given point (a,b,c) using Euclidean distance?
I'm saving RGB values of colors separately in a table, so the values are limited to 0-255 in each column. What I'm trying to do is find the closest color match by finding the color with the smallest euclidean distance.
I could obviously run through every point in the table to calculate the distance but that wouldn't be efficient enough to scale. Any ideas?
I think the above comments are all true, but they are - in my humble opinion - not answering the original question. (Correct me if I'm wrong). So, let me here add my 50 cents:
You are asking for a select statement, which, given your table is called 'colors', and given your columns are called r, g and b, they are integers ranged 0..255, and you are looking for the value, in your table, closest to a given value, lets say: rr, gg, bb, then I would dare trying the following:
select min(sqrt((rr-r)*(rr-r)+(gg-g)*(gg-g)+(bb-b)*(bb-b))) from colors;
Now, this answer is given with a lot of caveats, as I am not sure I got your question right, so pls confirm if it's right, or correct me so that I can be of assistance.
Since you're looking for the minimum distance and not exact distance you can skip the square root. I think Squared Euclidean Distance applies here.
You've said the values are bounded between 0-255, so you can make an indexed look up table with 255 values.
Here is what I'm thinking in terms of SQL. r0, g0, and b0 represent the target color. The table Vector would hold the square values mentioned above in #2. This solution would visit all the records but the result set can be set to 1 by sorting and selecting only the first row.
select
c.r, c.g, c.b,
mR.dist + mG.dist + mB.dist as squared_dist
from
colors c,
vector mR,
vector mG,
vector mB
where
c.r-r0 = mR.point and
c.g-g0 = mG.point and
c.b-b0 = mB.point
group by
c.r, c.g, c.b
The first level of optimization that I see you can do would be square the distance to which you want to limit the query so that you don't need to perform the square root for each row.
The second level of optimization I would encourage would be some preprocessing to alleviate the need for extraneous squaring for each query (which could possibly create some extra run time for large tables of RGB's). You'd have to do some benchmarking to see, but by substituting in values for a, b, c, and d and then performing the query, you could alleviate some stress from MySQL.
Note that the performance difference between the last two lines may be negligible. You'll have to use test queries on your system to determine which is faster.
I just re-read and noticed that you are ordering by distance. In which case, the d should be removed everything should be moved to one side. You can still plug in the constants to prevent extra processing on MySQL's end.
I believe there are two options.
You have to either as you say iterate across the entire set and compare and check against a maximum that you set initially at an impossibly low number like -1. This runs in linear time, n times (since you're only comparing 1 point to every point in the set, this scales in a linear way).
I'm still thinking of another option... something along the lines of doing a breadth first search away from the input point until a point is found in the set at the searched point, but this requires a bit more thought (I imagine the 3D space would have to be pretty heavily populated for this to be more efficient on average though).
If you run through every point and calculate the distance, don't use the square root function, it isn't necessary. The smallest sum of squares will be enough.
This is the problem you are trying to solve. (Planar case, select all points sorted by a x, y, or z axis. Then use PHP to process them)
MySQL also has a Spatial Database which may have this as a function. I'm not positive though.

Space a series of values so they don't overlap

There have been a couple of questions very close to this topic, but none really helped me.
Ive been programming a graphing library, and I need an algorithm to vertically place labels without overlapping. I've been stuck on this for a couple of days now, and managed to distil it to the most basic function:
If given a series of label positions along the Y axis, say, 1 1 2 3 5 6 9, and an upper and a lower limits 10 and 0 respectively, I need a way to space out the values to output 1 2 3 4 5 6 9
333467 should be 234567 weighted to be close to the original coordinates.
This should also work backwards, if values are bunched up at the upper end of the scale, they should be spread as much as possible (before overflowing)
I'm not looking for a definitive answer, but I'd like some help on how to approach this problem. Im completely stuck.
Last train of thought was to scan all labels for possible collisions and position them as one big block, aligning to the centre of all the Y coordinates. But this will not work if there are multiple sets of collisions.
EDIT: To put this algorithm in a bigger context, have a look at these two google chart API pie charts:
1) Top stacked labels
2) Bottom Stacked Labels
The labels are almost springy, they avoid collisions by joining together and moving their entire mass to the center of their mass.
Make the set of labels unique by inserting into an ordered set. Divide the difference between the y-axis upper and lower bound by the number of elements in the set. This is your spacing increment. Iterate over the set in order and position one label every spacing increment.
You didn't say anything about needing to preserve a scale...
Well, After some thought and advice from other sources i came up with a solution:
Pseudocode:
foreach labels as label
if label->collidesWith(labels->lowerLimit)
label->moveAwayFrom(labels->lowerLimit)
if label->collidesWith(labels->upperLimit)
label->moveAwayFrom(labels->upperLimit)
if label->collidesWith(label->previous)
label->moveAwayFrom(label->previous)
label->previous->moveAwayFrom(label)
if label->collidesWith(label->next)
label->moveAwayFrom(label->next)
label->next->moveAwayFrom(label)
endforeach
MoveAwayFrom moves 1 pixel at a time. When this function is run multiple times it rejiggles the labels until none of them collide. (in reality im calling this loop 100 times, havent figured out a way to do it more inteligently)

Categories