# Get intersection point of line and CIE chromaticity curve

**URL:** https://discourse.processing.org/t/get-intersection-point-of-line-and-cie-chromaticity-curve/6685
**Category:** Coding Questions
**Created:** [December 17, 2018, 2:45am UTC](https://discourse.processing.org/t/get-intersection-point-of-line-and-cie-chromaticity-curve/6685 "2018-12-17T02:45:53Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![ProsExplorer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/prosexplorer/32/1649_2.png) [@ProsExplorer](https://discourse.processing.org/u/ProsExplorer)
#### Post date: [December 17, 2018, 2:45am UTC](https://discourse.processing.org/t/get-intersection-point-of-line-and-cie-chromaticity-curve/6685/1 "2018-12-17T02:45:53Z")

</div>

First, let me lay out what I’ve done so far and what I’m trying to do with this partially completed program.  
I’m attempting to convert the RGB pixel values to their corresponding wavelength by:

Converting RGB to XYZ [check],  
Converting XYZ to Yxy [check], and  
Defining the dominant wavelength of xy [in progress].

The process of calculating the dominant wavelength of xy is laid out in [1,2]  
and summarized as follows for my purposes:

'Construct a line between the chromaticity coordinates of the reference white point on the diagram [CIE-D65 --\> x = 0.3127 , y = 0.3291] and the chromaticity coordinates [x1,y1 - in code below], and then extrapolate the line [via slopes] from the end that terminates at the filter point [graphed chromaticity curve].

The wavelength associated with the point on the horseshoe-shaped curve at which the extrapolated line intersects is the dominant wavelength.’

Essentially, the starting point x = 0.3127, y = 0.3291 is drawn to the RGB-converted x1, y1 point.  
Then the slope, rise and run [slopeY, slopeX respectively] are calculated and followed until it intersects the horseshoe graph of the CIE 1931 2-deg, x,y chromaticity coordinates.

 ![](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/a/ae365a03c7daea5f8efbe307bf55a8b99cf70360.jpeg)

Here is where I’m having trouble. The horseshoe graph [picture above] of the “CIE x,y chromaticity coordinates, CIE 1931 2-deg chromaticity coordinates” which describe each corresponding wavelength are made up of many different points x,y and is listed here in CSV files [3].  
[This annotated version I’m using is here, for clarity as to the x, y axis’]:

| nm | x | y |
| --- | --- | --- |
| 360 | 0.17556 | 0.005294 |
| 365 | 0.175161 | 0.005256 |
| 370 | 0.174821 | 0.005221 |
| 375 | 0.17451 | 0.005182 |
| 380 | 0.174112 | 0.004964 |
| 385 | 0.174008 | 0.004981 |
| 390 | 0.173801 | 0.004915 |
| 395 | 0.17356 | 0.004923 |
| 400 | 0.173337 | 0.004797 |
| 405 | 0.173021 | 0.004775 |
| 410 | 0.172577 | 0.004799 |
| 415 | 0.172087 | 0.004833 |
| 420 | 0.171407 | 0.005102 |
| 425 | 0.170301 | 0.005789 |
| 430 | 0.168878 | 0.0069 |
| 435 | 0.166895 | 0.008556 |
| 440 | 0.164412 | 0.010858 |
| 445 | 0.161105 | 0.013793 |
| 450 | 0.156641 | 0.017705 |
| 455 | 0.150985 | 0.02274 |
| 460 | 0.14396 | 0.029703 |
| 465 | 0.135503 | 0.039879 |
| 470 | 0.124118 | 0.057803 |
| 475 | 0.109594 | 0.086843 |
| 480 | 0.091294 | 0.132702 |
| 485 | 0.068706 | 0.200723 |
| 490 | 0.045391 | 0.294976 |
| 495 | 0.02346 | 0.412703 |
| 500 | 0.008168 | 0.538423 |
| 505 | 0.003859 | 0.654823 |
| 510 | 0.01387 | 0.750186 |
| 515 | 0.038852 | 0.812016 |
| 520 | 0.074302 | 0.833803 |
| 525 | 0.114161 | 0.826207 |
| 530 | 0.154722 | 0.805864 |
| 535 | 0.192876 | 0.781629 |
| 540 | 0.22962 | 0.754329 |
| 545 | 0.265775 | 0.724324 |
| 550 | 0.301604 | 0.692308 |
| 555 | 0.337363 | 0.658848 |
| 560 | 0.373102 | 0.624451 |
| 565 | 0.408736 | 0.589607 |
| 570 | 0.444062 | 0.554714 |
| 575 | 0.478775 | 0.520202 |
| 580 | 0.512486 | 0.486591 |
| 585 | 0.544787 | 0.454434 |
| 590 | 0.575151 | 0.424232 |
| 595 | 0.602933 | 0.396497 |
| 600 | 0.627037 | 0.372491 |
| 605 | 0.648233 | 0.351395 |
| 610 | 0.665764 | 0.334011 |
| 615 | 0.680079 | 0.319747 |
| 620 | 0.691504 | 0.308342 |
| 625 | 0.700606 | 0.299301 |
| 630 | 0.707918 | 0.292027 |
| 635 | 0.714032 | 0.285929 |
| 640 | 0.719033 | 0.280935 |
| 645 | 0.723032 | 0.276948 |
| 650 | 0.725992 | 0.274008 |
| 655 | 0.728272 | 0.271728 |
| 660 | 0.729969 | 0.270031 |
| 665 | 0.731089 | 0.268911 |
| 670 | 0.731993 | 0.268007 |
| 675 | 0.732719 | 0.267281 |
| 680 | 0.733417 | 0.266583 |
| 685 | 0.734047 | 0.265953 |
| 690 | 0.73439 | 0.26561 |
| 695 | 0.734592 | 0.265408 |
| 700 | 0.73469 | 0.26531 |
| 705 | 0.73469 | 0.26531 |
| 710 | 0.73469 | 0.26531 |
| 715 | 0.734548 | 0.265452 |
| 720 | 0.73469 | 0.26531 |
| 725 | 0.73469 | 0.26531 |
| 730 | 0.73469 | 0.26531 |
| 735 | 0.73469 | 0.26531 |
| 740 | 0.73469 | 0.26531 |
| 745 | 0.73469 | 0.26531 |
| 750 | 0.73469 | 0.26531 |
| 755 | 0.73469 | 0.26531 |
| 760 | 0.73469 | 0.26531 |
| 765 | 0.73469 | 0.26531 |
| 770 | 0.73469 | 0.26531 |
| 775 | 0.73469 | 0.26531 |
| 780 | 0.73469 | 0.26531 |
| 785 | 0.73469 | 0.26531 |
| 790 | 0.73469 | 0.26531 |
| 795 | 0.73469 | 0.26531 |
| 800 | 0.73469 | 0.26531 |
| 805 | 0.73469 | 0.26531 |
| 810 | 0.73469 | 0.26531 |
| 815 | 0.73469 | 0.26531 |
| 820 | 0.73469 | 0.26531 |
| 825 | 0.73469 | 0.26531 |
| 830 | 0.73469 | 0.26531 |

I’m unsure of how to take all the x,y points in the CSV table [above] and algorithmically create the curve through which my line will intersect and output a specific wavelength.

How could I go about mapping the x,y chromaticity coordinates so that my slope-based line values [x\_val, y\_val] will intersect it and output the value?

```auto
float R2;
float G2;
float B2;

float X;
float Y;
float Z;

float x1;
float y1;
float z1;

float slopeY;
float slopeX;
float slope;

float lineX;
float lineY;
float x_val;
float y_val;

void setup() {
  size(1024,768);
}

void draw() {
  loadPixels();
  for (int x = 0; x < width; x++) {
   for (int y = 0; y < height; y++) {
    // Total X-Y Pixel Array Scan
    int loc = x+y*width;
    float r = 0;
    float g = 255;
    float b = 162;
    
    //Convert from RGB to XYZ
    R2 = r/255;
    G2 = g/255;
    B2 = b/255;
    
    if ( R2 > 0.04045 ) {
      R2 = pow(( ( R2 + 0.055 ) / 1.055 ), 2.4);
    }else{                   
      R2 = R2 / 12.92;
    }
    if ( G2 > 0.04045 ) {
      G2 = pow(( ( G2 + 0.055 ) / 1.055 ), 2.4);
    }else{
      G2 = G2 / 12.92;
    }
    if ( B2 > 0.04045 ){ 
      B2 = pow(( ( B2 + 0.055 ) / 1.055 ), 2.4);
    }else{                   
    B2 = B2 / 12.92;
    }
    
    R2 = R2 * 100;
    G2 = G2 * 100;
    B2 = B2 * 100;
    
    //Observer. = 2°, Illuminant = D65 [reference white]
    X = R2 * 0.4124 + G2 * 0.3576 + B2 * 0.1805;
    Y = R2 * 0.2126 + G2 * 0.7152 + B2 * 0.0722;
    Z = R2 * 0.0193 + G2 * 0.1192 + B2 * 0.9505;
    
        //println(X,Y,Z);
    
    //Convert from XYZ to Yxy [chromaticity coordinates]
    x1 = X / (X+Y+Z);
    y1 = Y / (X+Y+Z);
    z1 = 1 - (x1+y1); // thus, chromaticity coordinates are usually given as just x and y
    
        //println(x1,y1);
        //0.25991857, 0.45569262

    //Calculate the dominant wavelength of xy
    // construct a line between the chromaticity coordinates of the reference 
    // white point on the diagram (for instance, CIE-D65, CIE-E, CIEC, etc.) 
    // and the chromaticity coordinates [x1,y1], and then
    // extrapolate the line from the end that terminates at the filter point
    
    // The wavelength associated with the point on the horseshoe-shaped curve 
    // at which the extrapolated line intersects is the dominant wavelength.
    
    // Reference White [Illuminant]
    // CIE-D65 --> x = 0.3127 , y = 0.3291
      lineX = 0.3127;
      lineY = 0.3291;
    // Chromaticity coordinates of filter [x1,y1],
      x_val = x1; //0.25991857;
      y_val = y1; //0.45569262;
    
        // slopeY = [YA - YB]  
        // slopeX = [XA - XB]
        slopeY = (lineY - y_val); // YB = Current xy point 0.45569262
        slopeX = (lineX - x_val); // XB = Current xy point 0.25991857
        
        slope = slopeY/slopeX; // -2.3984306
        
        if (slope < 0){
          
          while (x_val>0 && y_val>0){
          x_val = x_val - slopeX; 
          y_val = y_val - slopeY;
          }
            if (x_val<0 || y_val<0){
            x_val = x_val + slopeX; 
            y_val = y_val + slopeY;
            }
          
        } else {
 
        }
       
        //println(slope);
        //println(x_val, y_val);

    

    //float d = dist(width/2, height/2, x, y);
    pixels[loc] = color(r, g, b);
   }
  }  
  updatePixels();
}

```

References:

Yxy Equations -  
[1] [https://www.semrock.com/how-to-calculate-luminosity-dominant-wavelength-and-excitation-purity.aspx](https://www.semrock.com/how-to-calculate-luminosity-dominant-wavelength-and-excitation-purity.aspx)  
[2] [https://www.hunterlab.se/wp-content/uploads/2012/11/Yxy-CIE-Chromaticity-Coordinates.pdf](https://www.hunterlab.se/wp-content/uploads/2012/11/Yxy-CIE-Chromaticity-Coordinates.pdf).

CIE 1931 2-deg, x,y chromaticity coordinates / Filter Points -  
[3] [http://www.cvrl.org/ccs.htm](http://www.cvrl.org/ccs.htm)

CIE Basics-  
[http://hyperphysics.phy-astr.gsu.edu/hbase/vision/cie.html#c4](http://hyperphysics.phy-astr.gsu.edu/hbase/vision/cie.html#c4)

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [December 17, 2018, 4:09am UTC](https://discourse.processing.org/t/get-intersection-point-of-line-and-cie-chromaticity-curve/6685/2 "2018-12-17T04:09:01Z")

</div>

- [Forum.Processing.org/two/discussion/6903/unexpected-result-in-color-conversion-from-lab-to-rgb#Item\_2](http://Forum.Processing.org/two/discussion/6903/unexpected-result-in-color-conversion-from-lab-to-rgb#Item_2)

---

<div class="post-metadata">

### Author: ![ProsExplorer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/prosexplorer/32/1649_2.png) [@ProsExplorer](https://discourse.processing.org/u/ProsExplorer)
#### Post date: [December 17, 2018, 4:21am UTC](https://discourse.processing.org/t/get-intersection-point-of-line-and-cie-chromaticity-curve/6685/4 "2018-12-17T04:21:20Z")

</div>

Thanks but I’m not converting LAB to XYZ to RGB. And I’ve already converted the RGB to XYZ and then XYZ to Yxy in the above code. I’m trying to find the intersect point of the x\_val and y\_val (of Yxy) and the entire chromaticity coordinates graph.

Edit [1]:  
I was thinking maybe something like using PVectors and storing the x,y values of all the chromaticity coordinates graph, though how I’d define the intersect point of x\_val and y\_val and the graph boundary points is murky.

Edit [2]:  
I’ve run with the PVectors idea and wrote a separate program to create the chromaticity coordinates curve with beginShape and then used the equations from the original program to draw the dominant wavelength line.

I’ve managed to cause the line to intersect the curve, but how can I define the new x,y intersect point?

```auto
float lineX;
float lineY;
float x_val;
float y_val;

float slopeY;
float slopeX;
float slope;

float cycle = 0;

void setup(){  
size(640,360);
 background(0);
}
void draw(){  
  
// declaring the array (notice the brackets)
PVector[] nm;

// setting up the array (96 = 96 items)
nm = new PVector[96];

// filling the array :
nm[0] = new PVector(0.175560, 0.005294);
nm[1] = new PVector(0.175161, 0.005256);
nm[2] = new PVector(0.174821, 0.005221);
nm[3] = new PVector(0.174510, 0.005182);
nm[4] = new PVector(0.174112, 0.004964);
nm[5] = new PVector(0.174008, 0.004981);
nm[6] = new PVector(0.173801, 0.004915);
nm[7] = new PVector(0.173560, 0.004923);
nm[8] = new PVector(0.173337, 0.004797);
nm[9] = new PVector(0.173021, 0.004775);
nm[10] = new PVector(0.172577, 0.004799);
nm[11] = new PVector(0.172087, 0.004833);
nm[12] = new PVector(0.171407, 0.005102);
nm[13] = new PVector(0.170301, 0.005789);
nm[14] = new PVector(0.168878, 0.0069);
nm[15] = new PVector(0.166895, 0.008556);
nm[16] = new PVector(0.164412, 0.010858);
nm[17] = new PVector(0.161105, 0.013793);
nm[18] = new PVector(0.156641, 0.017705);
nm[19] = new PVector(0.150985, 0.02274);
nm[20] = new PVector(0.143960, 0.029703);
nm[21] = new PVector(0.135503, 0.039879);
nm[22] = new PVector(0.124118, 0.057803);
nm[23] = new PVector(0.109594, 0.086843);
nm[24] = new PVector(0.091294, 0.132702);
nm[25] = new PVector(0.068706, 0.200723);
nm[26] = new PVector(0.045391, 0.294976);
nm[27] = new PVector(0.023460, 0.412703);
nm[28] = new PVector(0.008168, 0.538423);
nm[29] = new PVector(0.003859, 0.654823);
nm[30] = new PVector(0.013870, 0.750186);
nm[31] = new PVector(0.038852, 0.812016);
nm[32] = new PVector(0.074302, 0.833803);
nm[33] = new PVector(0.114161, 0.826207);
nm[34] = new PVector(0.154722, 0.805864);
nm[35] = new PVector(0.192876, 0.781629);
nm[36] = new PVector(0.229620, 0.754329);
nm[37] = new PVector(0.265775, 0.724324);
nm[38] = new PVector(0.301604, 0.692308);
nm[39] = new PVector(0.337363, 0.658848);
nm[40] = new PVector(0.373102, 0.624451);
nm[41] = new PVector(0.408736, 0.589607);
nm[42] = new PVector(0.444062, 0.554714);
nm[43] = new PVector(0.478775, 0.520202);
nm[44] = new PVector(0.512486, 0.486591);
nm[45] = new PVector(0.544787, 0.454434);
nm[46] = new PVector(0.575151, 0.424232);
nm[47] = new PVector(0.602933, 0.396497);
nm[48] = new PVector(0.627037, 0.372491);
nm[49] = new PVector(0.648233, 0.351395);
nm[50] = new PVector(0.665764, 0.334011);
nm[51] = new PVector(0.680079, 0.319747);
nm[52] = new PVector(0.691504, 0.308342);
nm[53] = new PVector(0.700606, 0.299301);
nm[54] = new PVector(0.707918, 0.292027);
nm[55] = new PVector(0.714032, 0.285929);
nm[56] = new PVector(0.719033, 0.280935);
nm[57] = new PVector(0.723032, 0.276948);
nm[58] = new PVector(0.725992, 0.274008);
nm[59] = new PVector(0.728272, 0.271728);
nm[60] = new PVector(0.729969, 0.270031);
nm[61] = new PVector(0.731089, 0.268911);
nm[62] = new PVector(0.731993, 0.268007);
nm[63] = new PVector(0.732719, 0.267281);
nm[64] = new PVector(0.733417, 0.266583);
nm[65] = new PVector(0.734047, 0.265953);
nm[66] = new PVector(0.734390, 0.26561);
nm[67] = new PVector(0.734592, 0.265408);
nm[68] = new PVector(0.734690, 0.26531);
nm[69] = new PVector(0.734690, 0.26531);
nm[70] = new PVector(0.734690, 0.26531);
nm[71] = new PVector(0.734548, 0.265452);
nm[72] = new PVector(0.734690, 0.26531);
nm[73] = new PVector(0.734690, 0.26531);
nm[74] = new PVector(0.734690, 0.26531);
nm[75] = new PVector(0.734690, 0.26531);
nm[76] = new PVector(0.734690, 0.26531);
nm[77] = new PVector(0.734690, 0.26531);
nm[78] = new PVector(0.734690, 0.26531);
nm[79] = new PVector(0.734690, 0.26531);
nm[80] = new PVector(0.734690, 0.26531);
nm[81] = new PVector(0.734690, 0.26531);
nm[82] = new PVector(0.734690, 0.26531);
nm[83] = new PVector(0.734690, 0.26531);
nm[84] = new PVector(0.734690, 0.26531);
nm[85] = new PVector(0.734690, 0.26531);
nm[86] = new PVector(0.734690, 0.26531);
nm[87] = new PVector(0.734690, 0.26531);
nm[88] = new PVector(0.734690, 0.26531);
nm[89] = new PVector(0.734690, 0.26531);
nm[90] = new PVector(0.734690, 0.26531);
nm[91] = new PVector(0.734690, 0.26531);
nm[92] = new PVector(0.734690, 0.26531);
nm[93] = new PVector(0.734690, 0.26531);
nm[94] = new PVector(0.734690, 0.26531);
nm[95] = new PVector(0.734690, 0.26531);

while (cycle == 0){
  translate(260, 280);
  noFill();
  stroke(255);
  strokeWeight(1);
  beginShape();    

    int x1;  
    for (x1=0; x1<96; x1++){
    PVector v = nm[x1];
    float x = v.x;
    float y = v.y; 
    int nm_val = 360;
        nm_val = nm_val + (5*x1);
          println(nm_val+"nm = "+x,y);
      
    // Create chromasticity curve using beginShape
    vertex(x * pow(2,8),-y * pow(2,8)); //inverted y-ais for chromasticity graph
   }
   
  endShape(CLOSE);
  
  // lineX, lineY (starting point): lineX2, lineY2 (Endpoint) 
  //line(0.3127 * pow(2,8), -0.3291 * pow(2,8), 0.25991857 * pow(2,8), -0.45569262 * pow(2,8));

    lineX = 0.3127 * pow(2,8);
    lineY = 0.3291 * pow(2,8);
    x_val = 0.25991857 * pow(2,8);
    y_val = 0.45569262 * pow(2,8);
    
        slopeY = (lineY - y_val); // YB = Current xy point 0.45569262
        slopeX = (lineX - x_val); // XB = Current xy point 0.25991857
        
        slope = slopeY/slopeX; // -0.41693923389846896288267041159271
        
        if (slope < 0){
          
          while (x_val>0 && y_val>0){
          x_val = x_val - slopeX; 
          y_val = y_val - slopeY;
          }
            if (x_val<0 || y_val<0){
            x_val = x_val + slopeX; 
            y_val = y_val + slopeY;
            }
          
        } else {
 
        }
        
  line(lineX, -lineY, x_val, -y_val);
  
  cycle = 1;
  }
}

```

---

<div class="post-metadata">

### Author: ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)
#### Post date: [December 19, 2018, 12:15am UTC](https://discourse.processing.org/t/get-intersection-point-of-line-and-cie-chromaticity-curve/6685/5 "2018-12-19T00:15:18Z")

</div>

> [@ProsExplorer](#):
>
> I’ve managed to cause the line to intersect the curve, but how can I define the new x,y intersect point?

Are you, in general, wanting a line/line intersection formula for this? If I’m understanding your code right, your “curve” is actually a series of line segments. If you iterated over those curve segments and checked each against your line, zero or more of them will return a solution for a line-line intersection point.

> **[Collision Detection](http://www.jeffreythompson.org/collision-detection/line-line.php)**
>
> An online book about collision detection using Processing.

- [Collision Detection](http://www.jeffreythompson.org/collision-detection/line-line.php)

---

<div class="post-metadata">

### Author: ![ProsExplorer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/prosexplorer/32/1649_2.png) [@ProsExplorer](https://discourse.processing.org/u/ProsExplorer)
#### Post date: [December 19, 2018, 3:42am UTC](https://discourse.processing.org/t/get-intersection-point-of-line-and-cie-chromaticity-curve/6685/6 "2018-12-19T03:42:07Z")

</div>

> [jeremydouglass](https://discourse.processing.org/t/get-intersection-point-of-line-and-cie-chromaticity-curve/6685/5):  
> Are you, in general, wanting a line/line intersection formula for this?

If the line/line intersection formula can also provide the x and y intersect coordinates then yes, because in order to calculate the exact dominant wavelength I need to know the coordinates in which the line intersects the graphed curve.

> [jeremydouglass](https://discourse.processing.org/t/get-intersection-point-of-line-and-cie-chromaticity-curve/6685/5):  
> If I’m understanding your code right, your “curve” is actually a series of line segments.

Yes exactly, though I used the beginShape() method in the second code, the same method could easily be applied with producing lines between each point.

> [jeremydouglass](https://discourse.processing.org/t/get-intersection-point-of-line-and-cie-chromaticity-curve/6685/5):  
> If you iterated over those curve segments and checked each against your line, zero or more of them will return a solution for a line-line intersection point.

Well actually the dominant wavelength line will always have a set starting point:

```auto
    lineX = 0.3127 * pow(2,8);
    lineY = 0.3291 * pow(2,8);

```

and have a fixed point defined by the RGB pixel–\>XYZ–\>xy conversion

```auto
    x_val = 0.25991857 * pow(2,8);
    y_val = 0.45569262 * pow(2,8);

```

which then sets the fixed slope and allows the calculation of the whole line, defining the [x,y] intersection point with the graphed curve. Given that, there should only be a single possible intersection point, as shown below.

![Graphv3](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/0/02deeffc14af04b598f7c3227ccd5ae45a3819dd.jpeg)

---

<div class="post-metadata">

### Author: ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)
#### Post date: [December 19, 2018, 6:42pm UTC](https://discourse.processing.org/t/get-intersection-point-of-line-and-cie-chromaticity-curve/6685/7 "2018-12-19T18:42:57Z")

</div>

> [@ProsExplorer](#):
>
> Given that, there should only be a single possible intersection point, as shown below.

Great! Sounds like you have a solution, then. Loop over your segments and test them against your line for intersection.

Here is Thompson’s tutorial method that I linked to earlier, modified to return the intersection point (or null if no intersection):

```auto
PVector lineLine(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) {
  // calculate the distance to intersection point
  float uA = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
  float uB = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
  // if uA and uB are between 0-1, lines are colliding
  if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {
    // computer intersection point
    float intersectionX = x1 + (uA * (x2-x1));
    float intersectionY = y1 + (uA * (y2-y1));
    return new PVector(intersectionX, intersectionY);
  }
  return null;
}

```

So given a list of curve segments `segments` and a line `line`, you could use that method something like this:

```auto
// loop over segments and mark the point if intersection is not null
for (float[] seg : segments){
  PVector intersection = lineLine(seg[0], seg[1], seg[2], seg[3], line[0], line[1], line[2], line[3]);
  if(intersection != null){
    ellipse(intersection.x, intersection.y, 20, 20);
    break; 
  }
}

```

---

<div class="post-metadata">

### Author: ![ProsExplorer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/prosexplorer/32/1649_2.png) [@ProsExplorer](https://discourse.processing.org/u/ProsExplorer)
#### Post date: [December 23, 2018, 5:40pm UTC](https://discourse.processing.org/t/get-intersection-point-of-line-and-cie-chromaticity-curve/6685/8 "2018-12-23T17:40:58Z")

</div>

That’s great thank you! However, I’m relatively new to the PVector() method could you perhaps demonstrate that mathematical method with PVector() in an example?

---

<div class="post-metadata">

### Author: ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)
#### Post date: [December 26, 2018, 11:43pm UTC](https://discourse.processing.org/t/get-intersection-point-of-line-and-cie-chromaticity-curve/6685/9 "2018-12-26T23:43:08Z")

</div>

Sure. First, your draw coordinates and your data coordinates are not the same, and you switch back and forth a lot in your code – computing the line as draw coordinates, but storing nm as data coordinates. To simplify a demonstrated solution let’s create a second nm array for our draw coordinates:

```
PVector[] nmDraw;

```

…and store them like this:

```
  // Create chromasticity curve using beginShape
  PVector pt = new PVector(x * pow(2, 8), -y * pow(2, 8));
  nmDraw[x1] = pt;
  vertex(pt.x, pt.y); //inverted y-ais for chromasticity graph

```

Now, IF we had found the line first, we could find the intersection while in the loop to draw our curve. But instead of doing that, let’s add something to find the intersection as a separate stage, at the very end of draw:

```
  println(lineX, -lineY, x_val, -y_val);
  PVector resultPoint = colorPoint(nmDraw, lineX, -lineY, x_val, -y_val);
  println(resultPoint);
  ellipse(resultPoint.x, resultPoint.y, 20, 20);
}

```

We call colorPoint to solve for the intersection, which loops through the draw segments and compares them to the draw line. Notice that if we computed our line in data space then we could compare it to nm instead with the same function.

```auto
PVector colorPoint(PVector[] nm, float x1, float y1, float x2, float y2) {
  PVector resultPoint;
  for (int i=1; i<nm.length; i++) {
    PVector seg1 = nm[i-1];
    PVector seg2 = nm[i];
    // println(seg1.x, seg1.y, seg2.x, seg2.y, x1, y1, x2, y2);
    resultPoint = lineLine(seg1.x, seg1.y, seg2.x, seg2.y, x1, y1, x2, y2);
    if (resultPoint != null) {
      return resultPoint;
    }
  }
  return null;
}

```

This function is built on many calls to lineLine, the line-line intersection detection which I showed you earlier, and looks like this:

```auto
PVector lineLine(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) {
  // calculate the distance to intersection point
  float uA = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
  float uB = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
  // if uA and uB are between 0-1, lines are colliding
  if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {
    // computer intersection point
    float intersectionX = x1 + (uA * (x2-x1));
    float intersectionY = y1 + (uA * (y2-y1));
    return new PVector(intersectionX, intersectionY);
  }
  return null;
}

```

The result prints your line and your intersection point between the curve and the line

> 80.0512 -84.2496 12.490967 -246.28815  
> [26.798986, -211.97136, 0.0]

and draws a circle around that point.

 ![09%20PM](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/3/3cc7ff4f35677da77f20fdebba0ff1ca1ed0c8a2.png)

> **Complete sketch code**
>
> ```auto
> float lineX;
> float lineY;
> float x_val;
> float y_val;
> 
> float slopeY;
> float slopeX;
> float slope;
> 
> float cycle = 0;
> 
> PVector[] nm;
> PVector[] nmDraw;
> 
> void setup() {  
> size(640, 360);
> 
> // setting up the array (96 = 96 items)
> nm = new PVector[96];
> nmDraw = new PVector[96];
> // filling the array :
> nm[0] = new PVector(0.175560, 0.005294);
> nm[1] = new PVector(0.175161, 0.005256);
> nm[2] = new PVector(0.174821, 0.005221);
> nm[3] = new PVector(0.174510, 0.005182);
> nm[4] = new PVector(0.174112, 0.004964);
> nm[5] = new PVector(0.174008, 0.004981);
> nm[6] = new PVector(0.173801, 0.004915);
> nm[7] = new PVector(0.173560, 0.004923);
> nm[8] = new PVector(0.173337, 0.004797);
> nm[9] = new PVector(0.173021, 0.004775);
> nm[10] = new PVector(0.172577, 0.004799);
> nm[11] = new PVector(0.172087, 0.004833);
> nm[12] = new PVector(0.171407, 0.005102);
> nm[13] = new PVector(0.170301, 0.005789);
> nm[14] = new PVector(0.168878, 0.0069);
> nm[15] = new PVector(0.166895, 0.008556);
> nm[16] = new PVector(0.164412, 0.010858);
> nm[17] = new PVector(0.161105, 0.013793);
> nm[18] = new PVector(0.156641, 0.017705);
> nm[19] = new PVector(0.150985, 0.02274);
> nm[20] = new PVector(0.143960, 0.029703);
> nm[21] = new PVector(0.135503, 0.039879);
> nm[22] = new PVector(0.124118, 0.057803);
> nm[23] = new PVector(0.109594, 0.086843);
> nm[24] = new PVector(0.091294, 0.132702);
> nm[25] = new PVector(0.068706, 0.200723);
> nm[26] = new PVector(0.045391, 0.294976);
> nm[27] = new PVector(0.023460, 0.412703);
> nm[28] = new PVector(0.008168, 0.538423);
> nm[29] = new PVector(0.003859, 0.654823);
> nm[30] = new PVector(0.013870, 0.750186);
> nm[31] = new PVector(0.038852, 0.812016);
> nm[32] = new PVector(0.074302, 0.833803);
> nm[33] = new PVector(0.114161, 0.826207);
> nm[34] = new PVector(0.154722, 0.805864);
> nm[35] = new PVector(0.192876, 0.781629);
> nm[36] = new PVector(0.229620, 0.754329);
> nm[37] = new PVector(0.265775, 0.724324);
> nm[38] = new PVector(0.301604, 0.692308);
> nm[39] = new PVector(0.337363, 0.658848);
> nm[40] = new PVector(0.373102, 0.624451);
> nm[41] = new PVector(0.408736, 0.589607);
> nm[42] = new PVector(0.444062, 0.554714);
> nm[43] = new PVector(0.478775, 0.520202);
> nm[44] = new PVector(0.512486, 0.486591);
> nm[45] = new PVector(0.544787, 0.454434);
> nm[46] = new PVector(0.575151, 0.424232);
> nm[47] = new PVector(0.602933, 0.396497);
> nm[48] = new PVector(0.627037, 0.372491);
> nm[49] = new PVector(0.648233, 0.351395);
> nm[50] = new PVector(0.665764, 0.334011);
> nm[51] = new PVector(0.680079, 0.319747);
> nm[52] = new PVector(0.691504, 0.308342);
> nm[53] = new PVector(0.700606, 0.299301);
> nm[54] = new PVector(0.707918, 0.292027);
> nm[55] = new PVector(0.714032, 0.285929);
> nm[56] = new PVector(0.719033, 0.280935);
> nm[57] = new PVector(0.723032, 0.276948);
> nm[58] = new PVector(0.725992, 0.274008);
> nm[59] = new PVector(0.728272, 0.271728);
> nm[60] = new PVector(0.729969, 0.270031);
> nm[61] = new PVector(0.731089, 0.268911);
> nm[62] = new PVector(0.731993, 0.268007);
> nm[63] = new PVector(0.732719, 0.267281);
> nm[64] = new PVector(0.733417, 0.266583);
> nm[65] = new PVector(0.734047, 0.265953);
> nm[66] = new PVector(0.734390, 0.26561);
> nm[67] = new PVector(0.734592, 0.265408);
> nm[68] = new PVector(0.734690, 0.26531);
> nm[69] = new PVector(0.734690, 0.26531);
> nm[70] = new PVector(0.734690, 0.26531);
> nm[71] = new PVector(0.734548, 0.265452);
> nm[72] = new PVector(0.734690, 0.26531);
> nm[73] = new PVector(0.734690, 0.26531);
> nm[74] = new PVector(0.734690, 0.26531);
> nm[75] = new PVector(0.734690, 0.26531);
> nm[76] = new PVector(0.734690, 0.26531);
> nm[77] = new PVector(0.734690, 0.26531);
> nm[78] = new PVector(0.734690, 0.26531);
> nm[79] = new PVector(0.734690, 0.26531);
> nm[80] = new PVector(0.734690, 0.26531);
> nm[81] = new PVector(0.734690, 0.26531);
> nm[82] = new PVector(0.734690, 0.26531);
> nm[83] = new PVector(0.734690, 0.26531);
> nm[84] = new PVector(0.734690, 0.26531);
> nm[85] = new PVector(0.734690, 0.26531);
> nm[86] = new PVector(0.734690, 0.26531);
> nm[87] = new PVector(0.734690, 0.26531);
> nm[88] = new PVector(0.734690, 0.26531);
> nm[89] = new PVector(0.734690, 0.26531);
> nm[90] = new PVector(0.734690, 0.26531);
> nm[91] = new PVector(0.734690, 0.26531);
> nm[92] = new PVector(0.734690, 0.26531);
> nm[93] = new PVector(0.734690, 0.26531);
> nm[94] = new PVector(0.734690, 0.26531);
> nm[95] = new PVector(0.734690, 0.26531);
> 
> noLoop();
> }
> 
> void draw() {  
> background(0);
> while (cycle == 0) {
> translate(260, 280);
> noFill();
> stroke(255);
> strokeWeight(1);
> beginShape();    
> 
> int x1;  
> for (x1=0; x1<96; x1++) {
> PVector v = nm[x1];
> float x = v.x;
> float y = v.y; 
> int nm_val = 360;
> nm_val = nm_val + (5*x1);
> // println(nm_val+"nm = "+x, y);
> 
> // Create chromasticity curve using beginShape
> PVector pt = new PVector(x * pow(2, 8), -y * pow(2, 8));
> nmDraw[x1] = pt;
> vertex(pt.x, pt.y); //inverted y-ais for chromasticity graph
> }
> 
> endShape(CLOSE);
> 
> // lineX, lineY (starting point): lineX2, lineY2 (Endpoint) 
> //line(0.3127 * pow(2,8), -0.3291 * pow(2,8), 0.25991857 * pow(2,8), -0.45569262 * pow(2,8));
> 
> lineX = 0.3127 * pow(2, 8);
> lineY = 0.3291 * pow(2, 8);
> x_val = 0.25991857 * pow(2, 8);
> y_val = 0.45569262 * pow(2, 8);
> 
> slopeY = (lineY - y_val); // YB = Current xy point 0.45569262
> slopeX = (lineX - x_val); // XB = Current xy point 0.25991857
> slope = slopeY/slopeX; // -0.41693923389846896288267041159271
> 
> if (slope < 0) {
> while (x_val>0 && y_val>0) {
> x_val = x_val - slopeX; 
> y_val = y_val - slopeY;
> }
> if (x_val<0 || y_val<0) {
> x_val = x_val + slopeX; 
> y_val = y_val + slopeY;
> }
> } else {
> }
> line(lineX, -lineY, x_val, -y_val);
> cycle = 1;
> }
> println(lineX, -lineY, x_val, -y_val);
> PVector resultPoint = colorPoint(nmDraw, lineX, -lineY, x_val, -y_val);
> println(resultPoint);
> ellipse(resultPoint.x, resultPoint.y, 20, 20);
> }
> 
> PVector colorPoint(PVector[] nm, float x1, float y1, float x2, float y2) {
> PVector resultPoint;
> for (int i=1; i<nm.length; i++) {
> PVector seg1 = nm[i-1];
> PVector seg2 = nm[i];
> // println(seg1.x, seg1.y, seg2.x, seg2.y, x1, y1, x2, y2);
> resultPoint = lineLine(seg1.x, seg1.y, seg2.x, seg2.y, x1, y1, x2, y2);
> if (resultPoint != null) {
> return resultPoint;
> }
> }
> return null;
> }
> 
> PVector lineLine(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) {
> // calculate the distance to intersection point
> float uA = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
> float uB = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
> // if uA and uB are between 0-1, lines are colliding
> if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {
> // computer intersection point
> float intersectionX = x1 + (uA * (x2-x1));
> float intersectionY = y1 + (uA * (y2-y1));
> return new PVector(intersectionX, intersectionY);
> }
> return null;
> }
> 
> ```
