Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 9 of 9
  1. #1
    New to the CF scene
    Join Date
    May 2013
    Posts
    9
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Organise Coordinates in to particular order

    Hi,

    I am working on a script that allows someone to plot markers to make a rectangle (well a polygon in GD) on an image. The whole system works however I noticed an issue that if the vertices aren't done in the correct order then the polygon isn't drawn correctly (looks like two triangles |><| if that makes sense?)

    So obviously I need to rearrange the coordinates into an order so that they ultimately end up like this:

    1.-------2.
    |######|
    3.-------4.

    The array comes from my script like so;

    [[1111,1111],[1111,1111],[1111,1111],[1111,1111]]

    There will only ever be 4 coordinates and this is validated before hand.

    Any math genius have an idea of where to start? I did try doing something along the lines of checking what 1st element of each subarray was smallest and then finding out what was also the smallest second element to work out the first point, but I played with it so much that I completely broke it so scrapped it.

    Thanks!

  • #2
    New to the CF scene
    Join Date
    May 2013
    Posts
    9
    Thanks
    3
    Thanked 0 Times in 0 Posts
    Apologies, correction the diagram. The correct order is:

    1.-------2.
    |######|
    4.-------3.

    Goes round in a clockwise order from the top left point.

  • #3
    Senior Coder
    Join Date
    Sep 2010
    Posts
    1,899
    Thanks
    15
    Thanked 226 Times in 226 Posts
    This is the third post you've made about this problem. It sounds like something that could be done with enough conditional statements.

  • #4
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,979
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    The problem is that the order of the vertices does matter when drawing a polygon. So both of these would be valid:
    PHP Code:
    $aVertices = array(
        
    00,
        
    0100,
        
    100100,
        
    1000
    ); 
    And
    PHP Code:
    $aVertices = array(
        
    00,
        
    100100,
        
    0100,
        
    1000
    ); 
    The end results are either a rectangle in the first (assuming I did these mental vertices correct :P), or an hourglass shape. But both are completely valid, so determining its "not correct" isn't the easiest thing to do.
    Ultimately, if you need to make just a rectangle, I'd suggest you simply track the requirements for the rectangle. That is the top left corner and the bottom right corner. That guarantees your rectangular shape at any given time, and you only need to track two coordinates instead of 4.

    In order to "correct" a malformed ordered collection, you'd need to go through and calculate the angles between each of the three given vertices. If its 90 degrees, its good. If its not, than its out of order. The problem is shifting them around until you ultimately get the 90 degrees, which looks to me that you've at least thought of what you'd need to do which is good. Personally I wouldn't even consider this as a feasible option for a rectangle since its much easier just to draw a rectangle. All you need to do instead is calculate the paired coordinates to get the lowest possible x/y coordinates and the highest possible x/y coordinates in order to calculate the start and end positions for use in the imagerectangle methods.
    That can be done easily by simply sorting the items based on x and y values. Lets see if I can get that right:
    PHP Code:
    <?php

    function cmpVertices(array $a, array $b)
    {
        return (
    $a[0] - $b[0]) + ($a[1] - $b[1]);
    }

    $aVertices = array(
        
    00,
        
    100100,
        
    0100,
        
    1000
    );

    $split array_chunk($aVertices2);
    usort($split'cmpVertices');
    $aRectangle array_merge($split[0], end($split));
    print_r($aRectangle);
    Lets see, so those vertices should do an hourglass except the intention is to use the 0,0 as the lowest and the 100,100 as the highest. Comparator should sort it by the x's, and the y's independently and then factor them together. Simple as that.
    That looks like it'll work to give you the min and max coordinates for the rectangle. The $aRectangle will contain x0, y0, x1, y1 in order. Use those for the imagerectangle method instead. Also available is by taking these coordinates from the $aRectangle, you now know your position of "1" and "3". You can extrapolate the "2" and "4" if you really want to and use them in the imagepolygon as well.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 

  • Users who have thanked Fou-Lu for this post:

    JasonO (05-22-2013)

  • #5
    New to the CF scene
    Join Date
    May 2013
    Posts
    9
    Thanks
    3
    Thanked 0 Times in 0 Posts
    Thanks for the detailed reply! I read through and looked into your code, to test it, only to find it only produced 2 actual coordinate figures which produced..

    Code:
    Array
    (
        [0] => Array
            (
                [0] => 0
                [1] => 0
            )
    
        [1] => Array
            (
                [0] => 100
                [1] => 100
            )
    
        [2] => Array
            (
                [0] => 0
                [1] => 100
            )
    
        [3] => Array
            (
                [0] => 100
                [1] => 0
            )
    
    )
    
    
    Array
    (
        [0] => 0
        [1] => 0
        [2] => 100
        [3] => 100
    )
    
    
    Warning: imagefilledpolygon() [function.imagefilledpolygon]: You must have at least 3 points in your array in /home/jasono/public_html/aboutjason.co.uk/other/hidemyplate/imagegen.php on line 48
    Then I realised the paragraph at the bottom of your code! Doh, my fault for not scrolling down! I've had a little play with the function in trying to get 8 figures back instead of 4, but I'm not getting the result I need. As imagefilledpolygon needs 4 coordinates I need to order all 8 figures. I know I need to pass the last 2 arrays into the function, but I can't see how? I tried adding array $c and array $d to it and then playing with the calculation but it seems only 2 arrays are being passed to the function? Where is that being limited? Error I get is:

    Code:
    Catchable fatal error:  Argument 3 passed to cmpVertices() must be an array, none given
    The reason I'm using polygon over rectangle is because the angle between vertices may not be 90 degrees. As the user is drawing around a box on the screen, this could be any 4 sided shape depending on scale and perspective. I don't think imagefilledrectangle would work with this as from what I read it works from 2 coordinates and assumes the rest following the rules of drawing a rectangle (2 pairs of sides of equal size etc)

    Apologies if I'm blindly missing out to work it out. I've not done maths for a very long time so this really is picking at the brains. I was trying to work out what the function is doing but stumped by why only 2 arrays are being passed, as yet when I checked the $split variable it's an array with 4 arrays within it?

    Thanks again for your help.

  • #6
    New to the CF scene
    Join Date
    May 2013
    Posts
    9
    Thanks
    3
    Thanked 0 Times in 0 Posts
    So digging more into my code, I realised a lot of what I said above is wrong.

    The function doesn't handle 4 parameters as I thought (I thought it was handling the $split array when in fact its dealing with the arrays within it?) and the reason I'm only getting 4 figures is because of the array_merge function. I tried adding more of the arrays into the final array like so:

    Code:
    $aRectangle = array_merge($split[0], $split[1], $split[2], end($split));
    Now, I 'think' this is working somewhat. It is resorting the figures but not the right way. I've tried plotting the points on the image and doing it the way that didn't work before still creates the eggtime shape polygon.. however the old method that DID work now does the egg timer polygon - so I believe it is sorting it but it's doing the opposite of what it's supposed to.

    So I played around with the + and - signs in the function. I thought for a moment I done it when I changed it to this

    Code:
    return ($a[0] + $b[0]) + ($a[1] - $b[1]);
    However this really did reverse the issue I had before. The top left, top right, bottom left, bottom right order that didn't work before did now work! (Yipee!).. but the previous working combination of going clockwise from top left now made the egg timer.

    I've tried various combinations, but I don't think the function can correctly calculate the correct 8 figures using that one line alone? Each combination I try will work for half the combinations I do the markers, but the other half is the egg timer. Swapping them around will just change which ones work and which ones don't.

  • #7
    New to the CF scene
    Join Date
    May 2013
    Posts
    9
    Thanks
    3
    Thanked 0 Times in 0 Posts
    Sorry to post a lot, but can't see an edit button.

    Below is the output of what I mean. Each using the same function, but with just the markers placed differently.




  • #8
    New to the CF scene
    Join Date
    May 2013
    Posts
    9
    Thanks
    3
    Thanked 0 Times in 0 Posts
    Okay, my fault for probably working up to silly o'clock to work on this. But I completely forgot I had already posted with the same question in this section previously. I know I had posted in JavaScript before and when I wrote this I completely forgot about my post. I hadn't subscribed to that one so didn't notice the reply either. Oops!

    The solution there worked for me, I think that's ultimately where this would have ended up; it checks all the combinations and works out which is the correct way. GD Polygons and Custom Coordinates

    Either way, going through your code I learnt a lot about the PHP array functions and sorting them; so don't think your time was wasted! Thank you very much for your replies. Next time I'll, umm.. keep a better tab of what I've posted

  • #9
    Regular Coder Arcticwarrio's Avatar
    Join Date
    May 2012
    Location
    UK
    Posts
    709
    Thanks
    20
    Thanked 84 Times in 84 Posts
    nvm just read your last post lol
    There are 10 types of people on CodingForums,
    Those who understand Binary and those who dont.
    Get Cloud Hosting now from only£59 / month


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •