예제 #1
0
        public CIE1931Point NearestContainedPoint(CIE1931Point point)
        {
            if (Contains(point))
            {
                // If this gamut already contains the point, then no adjustment is required.
                return(point);
            }

            // Find the closest point on each line in the triangle.
            CIE1931Point pAB = GetClosestPointOnLine(Red, Green, point);
            CIE1931Point pAC = GetClosestPointOnLine(Red, Blue, point);
            CIE1931Point pBC = GetClosestPointOnLine(Green, Blue, point);

            //Get the distances per point and see which point is closer to our Point.
            double dAB = GetDistanceBetweenTwoPoints(point, pAB);
            double dAC = GetDistanceBetweenTwoPoints(point, pAC);
            double dBC = GetDistanceBetweenTwoPoints(point, pBC);

            double       lowest       = dAB;
            CIE1931Point closestPoint = pAB;

            if (dAC < lowest)
            {
                lowest       = dAC;
                closestPoint = pAC;
            }

            if (dBC < lowest)
            {
                lowest       = dBC;
                closestPoint = pBC;
            }

            return(closestPoint);
        }
예제 #2
0
        private static double GetDistanceBetweenTwoPoints(CIE1931Point one, CIE1931Point two)
        {
            double dx = one.x - two.x; // horizontal difference
            double dy = one.y - two.y; // vertical difference

            return(Math.Sqrt(dx * dx + dy * dy));
        }
예제 #3
0
        private static bool IsAbove(CIE1931Point blue, CIE1931Point red, CIE1931Point point)
        {
            double slope     = (blue.y - red.y) / (blue.x - red.x);
            double intercept = blue.y - slope * blue.x;

            double minY = point.x * slope + intercept;

            return(point.y >= minY);
        }
예제 #4
0
        private static bool IsBelow(CIE1931Point a, CIE1931Point b, CIE1931Point point)
        {
            double slope     = (a.y - b.y) / (a.x - b.x);
            double intercept = a.y - slope * a.x;

            double maxY = point.x * slope + intercept;

            return(point.y <= maxY);
        }
예제 #5
0
 public bool Contains(CIE1931Point point)
 {
     // Arrangement of points in color space:
     //
     //   ^             G
     //  y|
     //   |                  R
     //   |   B
     //   .------------------->
     //                      x
     //
     return(IsBelow(Blue, Green, point) &&
            IsBelow(Green, Red, point) &&
            IsAbove(Red, Blue, point));
 }
예제 #6
0
        private static CIE1931Point GetClosestPointOnLine(CIE1931Point a, CIE1931Point b, CIE1931Point p)
        {
            CIE1931Point AP = new CIE1931Point(p.x - a.x, p.y - a.y);
            CIE1931Point AB = new CIE1931Point(b.x - a.x, b.y - a.y);

            double ab2   = AB.x * AB.x + AB.y * AB.y;
            double ap_ab = AP.x * AB.x + AP.y * AB.y;

            double t = ap_ab / ab2;

            // Bound to ends of line between A and B.
            if (t < 0.0f)
            {
                t = 0.0f;
            }
            else if (t > 1.0f)
            {
                t = 1.0f;
            }

            return(new CIE1931Point(a.x + AB.x * t, a.y + AB.y * t));
        }
예제 #7
0
 public CIE1931Gamut(CIE1931Point red, CIE1931Point green, CIE1931Point blue)
 {
     this.Red   = red;
     this.Green = green;
     this.Blue  = blue;
 }