Search code examples
neo4jcolorscypher

How to store and find the nearest color in Neo4J using Cypher?


This problem is already solved in How to find the nearest color in SQL but I don't know how to adapt the solution to the Cypher query.


Solution

  • First, you need to convert the color hex into Red, Green, Blue points using this sql. For example; '017fff' is vivid blue

    select CONVERT(int, CONVERT(varbinary, SUBSTRING('017fff', 1, 2), 2)) AS R
            ,CONVERT(int, CONVERT(varbinary, SUBSTRING('017fff', 3, 2), 2)) AS G
            ,CONVERT(int, CONVERT(varbinary, SUBSTRING('017fff', 5, 2), 2)) AS B
    UNION ALL
    select CONVERT(int, CONVERT(varbinary, SUBSTRING('007ffe', 1, 2), 2)) AS R
            ,CONVERT(int, CONVERT(varbinary, SUBSTRING('007ffe', 3, 2), 2)) AS G
            ,CONVERT(int, CONVERT(varbinary, SUBSTRING('007ffe', 5, 2), 2)) AS B
    UNION ALL
    select CONVERT(int, CONVERT(varbinary, SUBSTRING('007fff', 1, 2), 2)) AS R
            ,CONVERT(int, CONVERT(varbinary, SUBSTRING('007fff', 3, 2), 2)) AS G
            ,CONVERT(int, CONVERT(varbinary, SUBSTRING('007fff', 5, 2), 2)) AS B
    
    Red Green Blue
    1 127 255
    0 127 254
    0 127 255

    Secondly, create the nodes in neo4j using Spatial function (3D). https://neo4j.com/docs/cypher-manual/current/functions/spatial/#functions-point-cartesian-3d

    For example:

    CREATE (:Color {coor: point({x: 1, y: 127, z: 255})})    //vivid blue
    CREATE (:Color {coor: point({x: 0, y: 127, z: 254})})    //mostly pure blue
    CREATE (:Color {coor: point({x: 0, y: 127, z: 255})})    //pure blue
    

    enter image description here

    Lastly, to calculate the distance (or closest distance), use this function. https://neo4j.com/docs/cypher-manual/current/functions/spatial/#functions-distance

    For example:

    MATCH (n:Color {coor: point({x:1, y:127, z:255})}), (m:Color)
    WITH n, m, point.distance(m.coor, n.coor) as dist WHERE n <> m
    RETURN n, m, dist ORDER by dist LIMIT 1
    

    Answer: Pure blue is closest to vivid blue

    ╒══════════════════════════════════════════════╤══════════════════════════════════════════════╤══════╕
    │"given_color"                                 │"closest_color"                               │"dist"│
    ╞══════════════════════════════════════════════╪══════════════════════════════════════════════╪══════╡
    │{"coor":point({srid:9157, x:1, y:127, z:255})}│{"coor":point({srid:9157, x:0, y:127, z:255})}│1.0   │
    └──────────────────────────────────────────────┴──────────────────────────────────────────────┴──────┘