SPCA - simplified 2d polygon clipping algorithm
In „Achieving color uniformity across multi projector displays“ A. Majumder (et al) formed a well known algorithm that addresses how to achieve colour uniformity across multiple projectors. Tiled walls with 3 Chip DLP/LCD projectors of the same make/model and therefore equal XYZ rgb gamut behaviour this complex algorithm can be simplified to a 2d polygon clipping algorithm - SPCA. The polygon clipping library mentioned here is the Polygon module for python. It relies on the "general polygon clipper library" provided by the University of Manchester.
import sys import clr
g1, g2,….gn represent CIExy gamuts and their values.
// r(x, y) g(x, y) b(x, y) g1 = Polygon.Polygon(((0.651, 0.302), (0.196, 0.691), (0.145, 0.092))) g2 = Polygon.Polygon(((0.626, 0.332), (0.216, 0.711), (0.162, 0.058))) g3 = Polygon.Polygon(((0.571, 0.322), (0.167, 0.646), (0.191, 0.044))) a = g1 & g2 & g3 // & = intersection
By adding all gamuts up with the & operator the result a is another polygon representing the area all gamut polygons share. This polygon consist of n vertices, all potential r, g and b candidates. To calculate the vertices that serve best for r, g and b we use the distance formula...
with x and y at theoretical reddest red(1,0), greenest green(0,1) and bluest blue(0,0)
In Python this formula can be written as seen below inside the for loop which iterates through every vertex in a
redDist; //will contain all distances from every a(x, y) to r(1,0) greenDis; //will contain all distances from every a(x, y) to g(0,1) blueDist; //will contain all distances from every a(x, y) to b(0,0) for point in a: redDist.append(math.sqrt((1-point)**2+(0-point)**2)) greenDist.append(math.sqrt((0-point)**2+(1-point)**2)) blueDist.append(math.sqrt((0-point)**2+(0-point)**2))
After all distances where calculated we need to get the x, y coordinates of the nearest vertex to the corresponding colour. Since we calculated distances in the same order as the vertices were stored in array a the index() method returns the position of the respective vertex to the value we got with min(colourDist).
redRefx = a[redDist.index(min(redDist))] redRefy = a[redDist.index(min(redDist))] greenRefx = a[greenDist.index(min(greenDist))] greenRefy = a[greenDist.index(min(greenDist))] blueRefx = a[blueDist.index(min(blueDist))] blueRefy = a[blueDist.index(min(blueDist))]
References:  A. Majumder, Z. He, H. Towles, and G. Welch. Achieving color uniformity across multiprojector displays. In Proceedings of IEEE Visualisation, 2000.  General Polygon Clipper library (University of Manchester - http://www.cs.man.ac.uk/~toby/gpc/ Designer and implementor: Alan Murta)  Python module - polygon clipping python library(Jörg Rädler - http://www.j-raedler.de/projects/polygon/)
Ventuz3, algorithm, math