Open In App

Line Clipping | Set 1 (Cohen–Sutherland Algorithm)

Improve
Improve
Like Article
Like
Save
Share
Report

Description:- In this algorithm, we are given 9 regions on the screen. Out of which one region is of the window and the rest 8 regions are around it given by 4 digit binary.  The division of the regions are based on (x_max, y_max) and (x_min, y_min).

The central part is the viewing region or window, all the lines which lie within this region are completely visible. A region code is always assigned to the endpoints of the given line.

To check whether the line is visible or not.

                                                                                  

Region Codes

Formula to check binary digits:- TBRL which can be defined as top, bottom, right, and left accordingly.                                                                                              

                                                                                                 

TBRL Rule

Algorithm

Steps

1) Assign the region codes to both endpoints.

2) Perform OR operation on both of these endpoints.

3) if  OR = 0000,

            then it is completely visible (inside the window).

   else

           Perform AND operation on both these endpoints.

                      i) if  AND ? 0000,

                                  then the line is invisible and not inside the window. Also, it can’t be considered for clipping.

                     ii) else

                                 AND = 0000, the line is partially inside the window and considered for clipping.

4)  After confirming that the line is partially inside the window, then we find the intersection with the boundary of the window. By using the following formula:-

                                       Slope:- m= (y2-y1)/(x2-x1)

     a) If the line passes through top or the line intersects with the top boundary of the window.

                                           x = x + (y_wmax – y)/m

                                           y = y_wmax

     b) If the line passes through the bottom or the line intersects with the bottom boundary of the window.

                                          x = x + (y_wmin – y)/m

                                          y = y_wmin

     c) If the line passes through the left region or the line intersects with the left boundary of the window.

                                          y = y+ (x_wmin – x)*m

                                          x = x_wmin

     d) If the line passes through the right region or the line intersects with the right boundary of the window.

                                         y = y + (x_wmax -x)*m

                                         x = x_wmax  

5) Now, overwrite the endpoints with a new one and update it.

6) Repeat the 4th step till your line doesn’t get completely clipped

Given a set of lines and a rectangular area of interest, the task is to remove lines that are outside the area of interest and clip the lines which are partially inside the area.

Input : Rectangular area of interest (Defined by
below four values which are coordinates of
bottom left and top right)
x_min = 4, y_min = 4, x_max = 10, y_max = 8

A set of lines (Defined by two corner coordinates)
line 1 : x1 = 5, y1 = 5, x2 = 7, y2 = 7
Line 2 : x1 = 7, y1 = 9, x2 = 11, y2 = 4
Line 2 : x1 = 1, y1 = 5, x2 = 4, y2 = 1
Output : Line 1 : Accepted from (5, 5) to (7, 7)
Line 2 : Accepted from (7.8, 8) to (10, 5.25)
Line 3 : Rejected


Cohen-Sutherland algorithm divides a two-dimensional space into 9 regions and then efficiently determines the lines and portions of lines that are inside the given rectangular area.

The algorithm can be outlines as follows:- 

Nine regions are created, eight "outside" regions and one 
"inside" region.
For a given line extreme point (x, y), we can quickly
find its region's four bit code. Four bit code can
be computed by comparing x and y with four values
(x_min, x_max, y_min and y_max).
If x is less than x_min then bit number 1 is set.
If x is greater than x_max then bit number 2 is set.
If y is less than y_min then bit number 3 is set.
If y is greater than y_max then bit number 4 is set

Cohen-Sutherland algorithm outline

There are three possible cases for any given line. 

  1. Completely inside the given rectangle : Bitwise OR of region of two end points of line is 0 (Both points are inside the rectangle)
  2. Completely outside the given rectangle : Both endpoints share at least one outside region which implies that the line does not cross the visible region. (bitwise AND of endpoints != 0).
  3. Partially inside the window : Both endpoints are in different regions. In this case, the algorithm finds one of the two points that is outside the rectangular region. The intersection of the line from outside point and rectangular window becomes new corner point and the algorithm repeats


 

cohen-sutherland-algo1


Pseudo Code: 

Step 1 : Assign a region code for two endpoints of given line.
Step 2 : If both endpoints have a region code 0000
then given line is completely inside.
Step 3 : Else, perform the logical AND operation for both region codes.
Step 3.1 : If the result is not 0000, then given line is completely
outside.
Step 3.2 : Else line is partially inside.
Step 3.2.1 : Choose an endpoint of the line
that is outside the given rectangle.
Step 3.2.2 : Find the intersection point of the
rectangular boundary (based on region code).
Step 3.2.3 : Replace endpoint with the intersection point
and update the region code.
Step 3.2.4 : Repeat step 2 until we find a clipped line either
trivially accepted or trivially rejected.
Step 4 : Repeat step 1 for other lines


Below is implementation of above steps.

C++

// C++ program to implement Cohen Sutherland algorithm
// for line clipping.
#include <iostream>
using namespace std;

// Defining region codes
const int INSIDE = 0; // 0000
const int LEFT = 1; // 0001
const int RIGHT = 2; // 0010
const int BOTTOM = 4; // 0100
const int TOP = 8; // 1000

// Defining x_max, y_max and x_min, y_min for
// clipping rectangle. Since diagonal points are
// enough to define a rectangle
const int x_max = 10;
const int y_max = 8;
const int x_min = 4;
const int y_min = 4;

// Function to compute region code for a point(x, y)
int computeCode(double x, double y)
{
    // initialized as being inside
    int code = INSIDE;

    if (x < x_min) // to the left of rectangle
        code |= LEFT;
    else if (x > x_max) // to the right of rectangle
        code |= RIGHT;
    if (y < y_min) // below the rectangle
        code |= BOTTOM;
    else if (y > y_max) // above the rectangle
        code |= TOP;

    return code;
}

// Implementing Cohen-Sutherland algorithm
// Clipping a line from P1 = (x2, y2) to P2 = (x2, y2)
void cohenSutherlandClip(double x1, double y1,
                         double x2, double y2)
{
    // Compute region codes for P1, P2
    int code1 = computeCode(x1, y1);
    int code2 = computeCode(x2, y2);

    // Initialize line as outside the rectangular window
    bool accept = false;

    while (true) {
        if ((code1 == 0) && (code2 == 0)) {
            // If both endpoints lie within rectangle
            accept = true;
            break;
        }
        else if (code1 & code2) {
            // If both endpoints are outside rectangle,
            // in same region
            break;
        }
        else {
            // Some segment of line lies within the
            // rectangle
            int code_out;
            double x, y;

            // At least one endpoint is outside the
            // rectangle, pick it.
            if (code1 != 0)
                code_out = code1;
            else
                code_out = code2;

            // Find intersection point;
            // using formulas y = y1 + slope * (x - x1),
            // x = x1 + (1 / slope) * (y - y1)
            if (code_out & TOP) {
                // point is above the clip rectangle
                x = x1 + (x2 - x1) * (y_max - y1) / (y2 - y1);
                y = y_max;
            }
            else if (code_out & BOTTOM) {
                // point is below the rectangle
                x = x1 + (x2 - x1) * (y_min - y1) / (y2 - y1);
                y = y_min;
            }
            else if (code_out & RIGHT) {
                // point is to the right of rectangle
                y = y1 + (y2 - y1) * (x_max - x1) / (x2 - x1);
                x = x_max;
            }
            else if (code_out & LEFT) {
                // point is to the left of rectangle
                y = y1 + (y2 - y1) * (x_min - x1) / (x2 - x1);
                x = x_min;
            }

            // Now intersection point x, y is found
            // We replace point outside rectangle
            // by intersection point
            if (code_out == code1) {
                x1 = x;
                y1 = y;
                code1 = computeCode(x1, y1);
            }
            else {
                x2 = x;
                y2 = y;
                code2 = computeCode(x2, y2);
            }
        }
    }
    if (accept) {
        cout << "Line accepted from " << x1 << ", "
             << y1 << " to " << x2 << ", " << y2 << endl;
        // Here the user can add code to display the rectangle
        // along with the accepted (portion of) lines
    }
    else
        cout << "Line rejected" << endl;
}

// Driver code
int main()
{
    // First Line segment
    // P11 = (5, 5), P12 = (7, 7)
    cohenSutherlandClip(5, 5, 7, 7);

    // Second Line segment
    // P21 = (7, 9), P22 = (11, 4)
    cohenSutherlandClip(7, 9, 11, 4);

    // Third Line segment
    // P31 = (1, 5), P32 = (4, 1)
    cohenSutherlandClip(1, 5, 4, 1);

    return 0;
}
Java

// Java program to implement Cohen Sutherland algorithm
// for line clipping.
import java.io.*;

class GFG {

    // Defining region codes
    static final int INSIDE = 0; // 0000
    static final int LEFT = 1; // 0001
    static final int RIGHT = 2; // 0010
    static final int BOTTOM = 4; // 0100
    static final int TOP = 8; // 1000

    // Defining x_max, y_max and x_min, y_min for
    // clipping rectangle. Since diagonal points are
    // enough to define a rectangle
    static final int x_max = 10;
    static final int y_max = 8;
    static final int x_min = 4;
    static final int y_min = 4;

    // Function to compute region code for a point(x, y)
    static int computeCode(double x, double y)
    {
        // initialized as being inside
        int code = INSIDE;

        if (x < x_min) // to the left of rectangle
            code |= LEFT;
        else if (x > x_max) // to the right of rectangle
            code |= RIGHT;
        if (y < y_min) // below the rectangle
            code |= BOTTOM;
        else if (y > y_max) // above the rectangle
            code |= TOP;

        return code;
    }

    // Implementing Cohen-Sutherland algorithm
    // Clipping a line from P1 = (x2, y2) to P2 = (x2, y2)
    static void cohenSutherlandClip(double x1, double y1,
                                    double x2, double y2)
    {
        // Compute region codes for P1, P2
        int code1 = computeCode(x1, y1);
        int code2 = computeCode(x2, y2);

        // Initialize line as outside the rectangular window
        boolean accept = false;

        while (true) {
            if ((code1 == 0) && (code2 == 0)) {
                // If both endpoints lie within rectangle
                accept = true;
                break;
            }
            else if ((code1 & code2) != 0) {
                // If both endpoints are outside rectangle,
                // in same region
                break;
            }
            else {
                // Some segment of line lies within the
                // rectangle
                int code_out;
                double x = 0, y = 0;

                // At least one endpoint is outside the
                // rectangle, pick it.
                if (code1 != 0)
                    code_out = code1;
                else
                    code_out = code2;

                // Find intersection point;
                // using formulas y = y1 + slope * (x - x1),
                // x = x1 + (1 / slope) * (y - y1)
                if ((code_out & TOP) != 0) {
                    // point is above the clip rectangle
                    x = x1
                        + (x2 - x1) * (y_max - y1)
                              / (y2 - y1);
                    y = y_max;
                }
                else if ((code_out & BOTTOM) != 0) {
                    // point is below the rectangle
                    x = x1
                        + (x2 - x1) * (y_min - y1)
                              / (y2 - y1);
                    y = y_min;
                }
                else if ((code_out & RIGHT) != 0) {
                    // point is to the right of rectangle
                    y = y1
                        + (y2 - y1) * (x_max - x1)
                              / (x2 - x1);
                    x = x_max;
                }
                else if ((code_out & LEFT) != 0) {
                    // point is to the left of rectangle
                    y = y1
                        + (y2 - y1) * (x_min - x1)
                              / (x2 - x1);
                    x = x_min;
                }

                // Now intersection point x, y is found
                // We replace point outside rectangle
                // by intersection point
                if (code_out == code1) {
                    x1 = x;
                    y1 = y;
                    code1 = computeCode(x1, y1);
                }
                else {
                    x2 = x;
                    y2 = y;
                    code2 = computeCode(x2, y2);
                }
            }
        }
        if (accept) {
            System.out.println("Line accepted from " + x1
                               + ", " + y1 + " to " + x2
                               + ", " + y2);
            // Here the user can add code to display the
            // rectangle along with the accepted (portion
            // of) lines
        }
        else
            System.out.println("Line rejected");
    }

    public static void main(String[] args)
    {
        // First Line segment
        // P11 = (5, 5), P12 = (7, 7)
        cohenSutherlandClip(5, 5, 7, 7);

        // Second Line segment
        // P21 = (7, 9), P22 = (11, 4)
        cohenSutherlandClip(7, 9, 11, 4);

        // Third Line segment
        // P31 = (1, 5), P32 = (4, 1)
        cohenSutherlandClip(1, 5, 4, 1);
    }
}

// This code is contributed by jain_mudit.
C#
using System;

public class GFG{
  
// C# program to implement Cohen Sutherland algorithm
// for line clipping.

// Defining region codes
public const int INSIDE = 0; // 0000
public const int LEFT = 1; // 0001
public const int RIGHT = 2; // 0010
public const int BOTTOM = 4; // 0100
public const int TOP = 8; // 1000

// Defining x_max, y_max and x_min, y_min for
// clipping rectangle. Since diagonal points are
// enough to define a rectangle
public const int x_max = 10;
public const int y_max = 8;
public const int x_min = 4;
public const int y_min = 4;

// Function to compute region code for a point(x, y)
public static int computeCode(double x, double y)
{
    // initialized as being inside
    int code = INSIDE;

    if (x < x_min) // to the left of rectangle
        code |= LEFT;
    else if (x > x_max) // to the right of rectangle
        code |= RIGHT;
    if (y < y_min) // below the rectangle
        code |= BOTTOM;
    else if (y > y_max) // above the rectangle
        code |= TOP;

    return code;
}

// Implementing Cohen-Sutherland algorithm
// Clipping a line from P1 = (x2, y2) to P2 = (x2, y2)
public static void cohenSutherlandClip(double x1, double y1,
                         double x2, double y2)
{
    // Compute region codes for P1, P2
    int code1 = computeCode(x1, y1);
    int code2 = computeCode(x2, y2);

    // Initialize line as outside the rectangular window
    bool accept = false;

    while (true) {
        if ((code1 == 0) && (code2 == 0)) {
            // If both endpoints lie within rectangle
            accept = true;
            break;
        }
        else if ((code1 & code2)!=0) {
            // If both endpoints are outside rectangle,
            // in same region
            break;
        }
        else {
            // Some segment of line lies within the
            // rectangle
            int code_out;
            double x=0.0;
            double y=0.0;

            // At least one endpoint is outside the
            // rectangle, pick it.
            if (code1 != 0)
                code_out = code1;
            else
                code_out = code2;

            // Find intersection point;
            // using formulas y = y1 + slope * (x - x1),
            // x = x1 + (1 / slope) * (y - y1)
            if ((code_out & TOP)!=0) {
                // point is above the clip rectangle
                x = x1 + (x2 - x1) * (y_max - y1) / (y2 - y1);
                y = y_max;
            }
            else if ((code_out & BOTTOM)!=0) {
                // point is below the rectangle
                x = x1 + (x2 - x1) * (y_min - y1) / (y2 - y1);
                y = y_min;
            }
            else if ((code_out & RIGHT)!=0) {
                // point is to the right of rectangle
                y = y1 + (y2 - y1) * (x_max - x1) / (x2 - x1);
                x = x_max;
            }
            else if ((code_out & LEFT)!=0) {
                // point is to the left of rectangle
                y = y1 + (y2 - y1) * (x_min - x1) / (x2 - x1);
                x = x_min;
            }

            // Now intersection point x, y is found
            // We replace point outside rectangle
            // by intersection point
            if (code_out == code1) {
                x1 = x;
                y1 = y;
                code1 = computeCode(x1, y1);
            }
            else {
                x2 = x;
                y2 = y;
                code2 = computeCode(x2, y2);
            }
        }
    }
    if (accept) {
        Console.WriteLine("Line accepted from "+x1+", "
             +y1+" to "+x2+", "+y2);
        // Here the user can add code to display the rectangle
        // along with the accepted (portion of) lines
    }
    else
        Console.WriteLine("Line rejected");
}

// Driver code

    static public void Main (){
        // First Line segment
    // P11 = (5, 5), P12 = (7, 7)
    cohenSutherlandClip(5, 5, 7, 7);

    // Second Line segment
    // P21 = (7, 9), P22 = (11, 4)
    cohenSutherlandClip(7, 9, 11, 4);

    // Third Line segment
    // P31 = (1, 5), P32 = (4, 1)
    cohenSutherlandClip(1, 5, 4, 1);

        
    }
}

// This code is contributed by akashish__
Javascript
// JavaScript program to implement Cohen Sutherland algorithm
// for line clipping.

// Defining region codes
const INSIDE = 0; // 0000
const LEFT = 1; // 0001
const RIGHT = 2; // 0010
const BOTTOM = 4; // 0100
const TOP = 8; // 1000

// Defining x_max, y_max and x_min, y_min for
// clipping rectangle. Since diagonal points are
// enough to define a rectangle
const x_max = 10;
const y_max = 8;
const x_min = 4;
const y_min = 4;

// Function to compute region code for a point(x, y)
function computeCode(x, y)
{
    // initialized as being inside
    let code = INSIDE;

    if (x < x_min) // to the left of rectangle
        code |= LEFT;
    else if (x > x_max) // to the right of rectangle
        code |= RIGHT;
    if (y < y_min) // below the rectangle
        code |= BOTTOM;
    else if (y > y_max) // above the rectangle
        code |= TOP;

    return code;
}

// Implementing Cohen-Sutherland algorithm
// Clipping a line from P1 = (x2, y2) to P2 = (x2, y2)
function cohenSutherlandClip(x1, y1, x2, y2)
{
    // Compute region codes for P1, P2
    let code1 = computeCode(x1, y1);
    let code2 = computeCode(x2, y2);

    // Initialize line as outside the rectangular window
    let accept = false;

    while (true) {
        if ((code1 == 0) && (code2 == 0)) {
            // If both endpoints lie within rectangle
            accept = true;
            break;
        }
        else if (code1 & code2) {
            // If both endpoints are outside rectangle,
            // in same region
            break;
        }
        else {
            // Some segment of line lies within the
            // rectangle
            let code_out;
            let x, y;

            // At least one endpoint is outside the
            // rectangle, pick it.
            if (code1 != 0)
                code_out = code1;
            else
                code_out = code2;

            // Find intersection point;
            // using formulas y = y1 + slope * (x - x1),
            // x = x1 + (1 / slope) * (y - y1)
            if (code_out & TOP) {
                // point is above the clip rectangle
                x = x1 + (x2 - x1) * (y_max - y1) / (y2 - y1);
                y = y_max;
            }
            else if (code_out & BOTTOM) {
                // point is below the rectangle
                x = x1 + (x2 - x1) * (y_min - y1) / (y2 - y1);
                y = y_min;
            }
            else if (code_out & RIGHT) {
                // point is to the right of rectangle
                y = y1 + (y2 - y1) * (x_max - x1) / (x2 - x1);
                x = x_max;
            }
            else if (code_out & LEFT) {
                // point is to the left of rectangle
                y = y1 + (y2 - y1) * (x_min - x1) / (x2 - x1);
                x = x_min;
            }

            // Now intersection point x, y is found
            // We replace point outside rectangle
            // by intersection point
            if (code_out == code1) {
                x1 = x;
                y1 = y;
                code1 = computeCode(x1, y1);
            }
            else {
                x2 = x;
                y2 = y;
                code2 = computeCode(x2, y2);
            }
        }
    }
    if (accept) {
        console.log("Line accepted from", x1, ",", y1, "to", x2, ",", y2);
        // Here the user can add code to display the rectangle
        // along with the accepted (portion of) lines
    }
    else
        console.log("Line rejected");
}

// Driver code
// First Line segment
// P11 = (5, 5), P12 = (7, 7)
cohenSutherlandClip(5, 5, 7, 7);

// Second Line segment
// P21 = (7, 9), P22 = (11, 4)
cohenSutherlandClip(7, 9, 11, 4);

// Third Line segment
// P31 = (1, 5), P32 = (4, 1)
cohenSutherlandClip(1, 5, 4, 1);

// The code is contributed by Nidhi goel
Python3
# Python program to implement Cohen Sutherland algorithm
# for line clipping.

# Defining region codes
INSIDE = 0  # 0000
LEFT = 1  # 0001
RIGHT = 2  # 0010
BOTTOM = 4  # 0100
TOP = 8  # 1000

# Defining x_max, y_max and x_min, y_min for rectangle
# Since diagonal points are enough to define a rectangle
x_max = 10.0
y_max = 8.0
x_min = 4.0
y_min = 4.0


# Function to compute region code for a point(x, y)
def computeCode(x, y):
    code = INSIDE
    if x < x_min:  # to the left of rectangle
        code |= LEFT
    elif x > x_max:  # to the right of rectangle
        code |= RIGHT
    if y < y_min:  # below the rectangle
        code |= BOTTOM
    elif y > y_max:  # above the rectangle
        code |= TOP
    return code


# Implementing Cohen-Sutherland algorithm
# Clipping a line from P1 = (x1, y1) to P2 = (x2, y2)
# Implementing Cohen-Sutherland algorithm
# Clipping a line from P1 = (x1, y1) to P2 = (x2, y2)
def cohenSutherlandClip(x1, y1, x2, y2):

    # Compute region codes for P1, P2
    code1 = computeCode(x1, y1)
    code2 = computeCode(x2, y2)
    accept = False

    while True:

        # If both endpoints lie within rectangle
        if code1 == 0 and code2 == 0:
            accept = True
            break

        # If both endpoints are outside rectangle
        elif (code1 & code2) != 0:
            break

        # Some segment lies within the rectangle
        else:

            # Line needs clipping
            # At least one of the points is outside,
            # select it
            x = 1.0
            y = 1.0
            if code1 != 0:
                code_out = code1
            else:
                code_out = code2

            # Find intersection point
            # using formulas y = y1 + slope * (x - x1),
            # x = x1 + (1 / slope) * (y - y1)
            if code_out & TOP:
                # Point is above the clip rectangle
                x = x1 + (x2 - x1) * (y_max - y1) / (y2 - y1)
                y = y_max
            elif code_out & BOTTOM:
                # Point is below the clip rectangle
                x = x1 + (x2 - x1) * (y_min - y1) / (y2 - y1)
                y = y_min
            elif code_out & RIGHT:
                # Point is to the right of the clip rectangle
                y = y1 + (y2 - y1) * (x_max - x1) / (x2 - x1)
                x = x_max
            elif code_out & LEFT:
                # Point is to the left of the clip rectangle
                y = y1 + (y2 - y1) * (x_min - x1) / (x2 - x1)
                x = x_min

            # Now intersection point (x, y) is found
            # We replace point outside clipping rectangle
            # by intersection point
            if code_out == code1:
                x1 = x
                y1 = y
                code1 = computeCode(x1, y1)
            else:
                x2 = x
                y2 = y
                code2 = computeCode(x2, y2)

    if accept:
        print("Line accepted from %.2f, %.2f to %.2f, %.2f" % (x1, y1, x2, y2))

        # Here the user can add code to display the rectangle
        # along with the accepted (portion of) lines

    else:
        print("Line rejected")

# Driver script

# First line segment
# P11 = (5, 5), P12 = (7, 7)
cohenSutherlandClip(5, 5, 7, 7)

# Second line segment
# P21 = (7, 9), P22 = (11, 4)
cohenSutherlandClip(7, 9, 11, 4)

# Third line segment
# P31 = (1, 5), P32 = (4, 1)
cohenSutherlandClip(1, 5, 4, 1)

Output: 

Line accepted from 5.00, 5.00 to 7.00, 7.00
Line accepted from 7.80, 8.00 to 10.00, 5.25
Line rejected


Below is C++ code with Graphics using graphics.h 

C++

// C++ program to implement Cohen Sutherland algorithm
// for line clipping.
// including libraries
#include <bits/stdc++.h>
#include <graphics.h>
using namespace std;

// Global Variables
int xmin, xmax, ymin, ymax;

// Lines where co-ordinates are (x1, y1) and (x2, y2)
struct lines {
    int x1, y1, x2, y2;
};

// This will return the sign required.
int sign(int x)
{
    if (x > 0)
        return 1;
    else
        return 0;
}

// CohenSutherLand LineClipping Algorithm As Described in theory.
// This will clip the lines as per window boundaries.
void clip(struct lines mylines)
{
    // arrays will store bits
    // Here bits implies initial Point whereas byte implies end points
    int bits[4], byte[4], i, var;
    // setting color of graphics to be RED
    setcolor(RED);

    // Finding Bits
    bits[0] = sign(xmin - mylines.x1);
    byte[0] = sign(xmin - mylines.x2);
    bits[1] = sign(mylines.x1 - xmax);
    byte[1] = sign(mylines.x2 - xmax);
    bits[2] = sign(ymin - mylines.y1);
    byte[2] = sign(ymin - mylines.y2);
    bits[3] = sign(mylines.y1 - ymax);
    byte[3] = sign(mylines.y2 - ymax);

    // initial will used for initial coordinates and end for final
    string initial = "", end = "", temp = "";

    // convert bits to string
    for (i = 0; i < 4; i++) {
        if (bits[i] == 0)
            initial += '0';
        else
            initial += '1';
    }
    for (i = 0; i < 4; i++) {
        if (byte[i] == 0)
            end += '0';
        else
            end += '1';
    }

    // finding slope of line y=mx+c as (y-y1)=m(x-x1)+c
    // where m is slope m=dy/dx;

    float m = (mylines.y2 - mylines.y1) / (float)(mylines.x2 - mylines.x1);
    float c = mylines.y1 - m * mylines.x1;

    // if both points are inside the Accept the line and draw
    if (initial == end && end == "0000") {
        // inbuilt function to draw the line from(x1, y1) to (x2, y2)
        line(mylines.x1, mylines.y1, mylines.x2, mylines.y2);
        return;
    }

    // this will contain cases where line maybe totally outside for partially inside
    else {
        // taking bitwise end of every value
        for (i = 0; i < 4; i++) {

            int val = (bits[i] & byte[i]);
            if (val == 0)
                temp += '0';
            else
                temp += '1';
        }
        // as per algo if AND is not 0000 means line is completely outside hence draw nothing and return
        if (temp != "0000")
            return;

        // Here contain cases of partial inside or outside
        // So check for every boundary one by one
        for (i = 0; i < 4; i++) {
            // if both bit are same hence we cannot find any intersection with boundary so continue
            if (bits[i] == byte[i])
                continue;
            // Otherwise there exist a intersection

            // Case when initial point is in left xmin
            if (i == 0 && bits[i] == 1) {
                var = round(m * xmin + c);
                mylines.y1 = var;
                mylines.x1 = xmin;
            }
            // Case when final point is in left xmin
            if (i == 0 && byte[i] == 1) {
                var = round(m * xmin + c);
                mylines.y2 = var;
                mylines.x2 = xmin;
            }
            // Case when initial point is in right of xmax
            if (i == 1 && bits[i] == 1) {
                var = round(m * xmax + c);
                mylines.y1 = var;
                mylines.x1 = xmax;
            }
            // Case when final point is in right of xmax
            if (i == 1 && byte[i] == 1) {
                var = round(m * xmax + c);
                mylines.y2 = var;
                mylines.x2 = xmax;
            }
            // Case when initial point is in top of ymin
            if (i == 2 && bits[i] == 1) {
                var = round((float)(ymin - c) / m);
                mylines.y1 = ymin;
                mylines.x1 = var;
            }
            // Case when final point is in top of ymin
            if (i == 2 && byte[i] == 1) {
                var = round((float)(ymin - c) / m);
                mylines.y2 = ymin;
                mylines.x2 = var;
            }
            // Case when initial point is in bottom of ymax
            if (i == 3 && bits[i] == 1) {
                var = round((float)(ymax - c) / m);
                mylines.y1 = ymax;
                mylines.x1 = var;
            }
            // Case when final point is in bottom of ymax
            if (i == 3 && byte[i] == 1) {
                var = round((float)(ymax - c) / m);
                mylines.y2 = ymax;
                mylines.x2 = var;
            }
            // Updating Bits at every point
            bits[0] = sign(xmin - mylines.x1);
            byte[0] = sign(xmin - mylines.x2);
            bits[1] = sign(mylines.x1 - xmax);
            byte[1] = sign(mylines.x2 - xmax);
            bits[2] = sign(ymin - mylines.y1);
            byte[2] = sign(ymin - mylines.y2);
            bits[3] = sign(mylines.y1 - ymax);
            byte[3] = sign(mylines.y2 - ymax);
        } // end of for loop
        // Initialize initial and end to NULL
        initial = "", end = "";
        // Updating strings again by bit
        for (i = 0; i < 4; i++) {
            if (bits[i] == 0)
                initial += '0';
            else
                initial += '1';
        }
        for (i = 0; i < 4; i++) {
            if (byte[i] == 0)
                end += '0';
            else
                end += '1';
        }
        // If now both points lie inside or on boundary then simply draw the updated line
        if (initial == end && end == "0000") {
            line(mylines.x1, mylines.y1, mylines.x2, mylines.y2);
            return;
        }
        // else line was completely outside hence rejected
        else
            return;
    }
}

// Driver Function
int main()
{
    int gd = DETECT, gm;

    // Setting values of Clipping window
    xmin = 40;
    xmax = 100;
    ymin = 40;
    ymax = 80;

    // initialize the graph
    initgraph(&gd, &gm, NULL);

    // Drawing Window using Lines
    line(xmin, ymin, xmax, ymin);
    line(xmax, ymin, xmax, ymax);
    line(xmax, ymax, xmin, ymax);
    line(xmin, ymax, xmin, ymin);

    // Assume 4 lines to be clipped
    struct lines mylines[4];

    // Setting the coordinated of  4 lines
    mylines[0].x1 = 30;
    mylines[0].y1 = 65;
    mylines[0].x2 = 55;
    mylines[0].y2 = 30;

    mylines[1].x1 = 60;
    mylines[1].y1 = 20;
    mylines[1].x2 = 100;
    mylines[1].y2 = 90;

    mylines[2].x1 = 60;
    mylines[2].y1 = 100;
    mylines[2].x2 = 80;
    mylines[2].y2 = 70;

    mylines[3].x1 = 85;
    mylines[3].y1 = 50;
    mylines[3].x2 = 120;
    mylines[3].y2 = 75;

    // Drawing Initial Lines without clipping
    for (int i = 0; i < 4; i++) {
        line(mylines[i].x1, mylines[i].y1,
             mylines[i].x2, mylines[i].y2);
        delay(1000);
    }

    // Drawing clipped Line
    for (int i = 0; i < 4; i++) {
        // Calling clip() which in term clip the line as per window and draw it
        clip(mylines[i]);
        delay(1000);
    }
    delay(4000);
    getch();
    // For Closing the graph.
    closegraph();
    return 0;
}
Java
import java.util.ArrayList;

public class Main {
    // Global Variables
    static int xmin = 0, xmax = 0, ymin = 0, ymax = 0;

    // Lines where co-ordinates are (x1, y1) and (x2, y2)
    static class Lines {
        int x1, y1, x2, y2;
        public Lines(int x1, int y1, int x2, int y2) {
            this.x1 = x1;
            this.y1 = y1;
            this.x2 = x2;
            this.y2 = y2;
        }
    }

    // This will return the sign required.
    static int sign(int x) {
        return x > 0 ? 1 : 0;
    }

    // CohenSutherLand LineClipping Algorithm As Described in theory.
    // This will clip the lines as per window boundaries.
    static void clip(Lines mylines) {
        // arrays will store bits
        // Here bits implies initial Point whereas byteArray implies end points
        int[] bits = new int[4];
        int[] byteArray = new int[4];

        // Finding Bits
        bits[0] = sign(xmin - mylines.x1);
        byteArray[0] = sign(xmin - mylines.x2);
        bits[1] = sign(mylines.x1 - xmax);
        byteArray[1] = sign(mylines.x2 - xmax);
        bits[2] = sign(ymin - mylines.y1);
        byteArray[2] = sign(ymin - mylines.y2);
        bits[3] = sign(mylines.y1 - ymax);
        byteArray[3] = sign(mylines.y2 - ymax);

        // initial will used for initial coordinates and end for final
        String initial = "";
        String end = "";
        for (int bit : bits) {
            initial += bit;
        }
        for (int b : byteArray) {
            end += b;
        }
        String temp = "";

        // finding slope of line y=mx+c as (y-y1)=m(x-x1)+c
        // where m is slope m=dy/dx;
        double m = (double)(mylines.y2 - mylines.y1) / (mylines.x2 - mylines.x1);
        double c = mylines.y1 - m * mylines.x1;

        // if both points are inside the Accept the line and draw
        if (initial.equals(end) && end.equals("0000")) {
            // plotting the line from (x1, y1) to (x2, y2)
            System.out.println("Line from (" + mylines.x1 + ", " + mylines.y1 + ") to (" + mylines.x2 + ", " + mylines.y2 + ")");
            return;
        }

        // this will contain cases where line maybe totally outside for partially inside
        else {
            // taking bitwise end of every value
            for (int i = 0; i < 4; i++) {
                int val = bits[i] & byteArray[i];
                temp += val == 0 ? '0' : '1';
            }
            // as per algo if AND is not 0000 means line is completely outside hence draw nothing and return
            if (!temp.equals("0000")) {
                return;
            }

            // Here contain cases of partial inside or outside
            // So check for every boundary one by one
            for (int i = 0; i < 4; i++) {
                // if both bit are same hence we cannot find any intersection with boundary so continue
                if (bits[i] == byteArray[i]) {
                    continue;
                }
                // Otherwise there exist an intersection

                // Case when initial point is in left xmin
                if (i == 0 && bits[i] == 1) {
                    int tvar = (int)Math.round(m * xmin + c);
                    mylines.y1 = tvar;
                    mylines.x1 = xmin;
                }
                // Case when final point is in left xmin
                if (i == 0 && byteArray[i] == 1) {
                    int tvar = (int)Math.round(m * xmin + c);
                    mylines.y2 = tvar;
                    mylines.x2 = xmin;
                }
                // Case when initial point is in right of xmax
                if (i == 1 && bits[i] == 1) {
                    int tvar = (int)Math.round(m * xmax + c);
                    mylines.y1 = tvar;
                    mylines.x1 = xmax;
                }
                // Case when final point is in right of xmax
                if (i == 1 && byteArray[i] == 1) {
                    int tvar = (int)Math.round(m * xmax + c);
                    mylines.y2 = tvar;
                    mylines.x2 = xmax;
                }
                // Case when initial point is in top of ymin
                if (i == 2 && bits[i] == 1) {
                    int tvar = (int)Math.round((ymin - c) / m);
                    mylines.y1 = ymin;
                    mylines.x1 = tvar;
                }
                // Case when final point is in top of ymin
                if (i == 2 && byteArray[i] == 1) {
                    int tvar = (int)Math.round((ymin - c) / m);
                    mylines.y2 = ymin;
                    mylines.x2 = tvar;
                }
                // Case when initial point is in bottom of ymax
                if (i == 3 && bits[i] == 1) {
                    int tvar = (int)Math.round((ymax - c) / m);
                    mylines.y1 = ymax;
                    mylines.x1 = tvar;
                }
                // Case when final point is in bottom of ymax
                if (i == 3 && byteArray[i] == 1) {
                    int tvar = (int)Math.round((ymax - c) / m);
                    mylines.y2 = ymax;
                    mylines.x2 = tvar;
                }
                // Updating Bits at every point
                bits[0] = sign(xmin - mylines.x1);
                byteArray[0] = sign(xmin - mylines.x2);
                bits[1] = sign(mylines.x1 - xmax);
                byteArray[1] = sign(mylines.x2 - xmax);
                bits[2] = sign(ymin - mylines.y1);
                byteArray[2] = sign(ymin - mylines.y2);
                bits[3] = sign(mylines.y1 - ymax);
                byteArray[3] = sign(mylines.y2 - ymax);
            }

            // If now both points lie inside or on boundary then simply draw the updated line
            if (initial.equals(end) && end.equals("0000")) {
                System.out.println("Line from (" + mylines.x1 + ", " + mylines.y1 + ") to (" + mylines.x2 + ", " + mylines.y2 + ")");
                return;
            }
            // else line was completely outside hence rejected
            else {
                return;
            }
        }
    }

    // Driver Function
    public static void main(String[] args) {
        // Setting values of Clipping window
        xmin = 40;
        xmax = 100;
        ymin = 40;
        ymax = 80;

        // Assume 4 lines to be clipped
        ArrayList<Lines> mylines = new ArrayList<>();

        // Setting the coordinates of 4 lines
        mylines.add(new Lines(30, 65, 55, 30));
        mylines.add(new Lines(60, 20, 100, 90));
        mylines.add(new Lines(60, 100, 80, 70));
        mylines.add(new Lines(85, 50, 120, 75));

        // Drawing Initial Lines without clipping
        for (Lines line : mylines) {
            System.out.println("Line from (" + line.x1 + ", " + line.y1 + ") to (" + line.x2 + ", " + line.y2 + ")");
        }

        // Drawing clipped Line
        for (Lines line : mylines) {
            // Calling clip() which in term clip the line as per window and draw it
            clip(line);
        }
    }
}
C#
using System;

// Class to represent a line with two points (x1, y1) and (x2, y2)
public class Lines
{
    public double x1, y1, x2, y2;

    public Lines(double x1, double y1, double x2, double y2)
    {
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
    }
}

public class Program
{
    // Define the window boundaries
    static double xmin = 0, xmax = 0, ymin = 0, ymax = 0;

    // Function to return 1 if x is greater than 0, and 0 otherwise
    static int Sign(double x)
    {
        return x > 0 ? 1 : 0;
    }

    // Function to implement the Cohen-Sutherland algorithm
    static void Clip(Lines mylines)
    {
        // Define the arrays to hold the bits for the initial and end points
        int[] bits = new int[4];
        int[] bytes = new int[4]; // Renamed 'byte' to 'bytes'

        // Calculate the bits for the initial and end points
        bits[0] = Sign(xmin - mylines.x1);
        bytes[0] = Sign(xmin - mylines.x2);
        bits[1] = Sign(mylines.x1 - xmax);
        bytes[1] = Sign(mylines.x2 - xmax);
        bits[2] = Sign(ymin - mylines.y1);
        bytes[2] = Sign(ymin - mylines.y2);
        bits[3] = Sign(mylines.y1 - ymax);
        bytes[3] = Sign(mylines.y2 - ymax);

        // Convert the bits to strings for comparison
        string initial = string.Join("", bits);
        string end = string.Join("", bytes);
        string temp = "";

        // Calculate the slope and y-intercept of the line
        double m = (mylines.y2 - mylines.y1) / (mylines.x2 - mylines.x1);
        double c = mylines.y1 - m * mylines.x1;

        // If both points are inside the window, print the line
        if (initial == end && end == "0000")
        {
            Console.WriteLine($"Line from ({mylines.x1}, {mylines.y1}) to ({mylines.x2}, {mylines.y2})");
            return;
        }
        else
        {
            // Calculate the bitwise AND of the bits for the initial and end points
            for (int i = 0; i < 4; i++)
            {
                int val = bits[i] & bytes[i]; // Changed '&&' to '&'
                temp += val == 0 ? '0' : '1';
            }

            // If the line is completely outside the window, return
            if (temp != "0000")
            {
                return;
            }

            // Check each boundary of the window
            for (int i = 0; i < 4; i++)
            {
                // If the bit for the initial point is the same as the bit for the end point, continue
                if (bits[i] == bytes[i])
                {
                    continue;
                }

                // If the initial point is to the left of xmin, calculate the intersection with the left boundary
                if (i == 0 && bits[i] == 1)
                {
                    double tvar = Math.Round(m * xmin + c);
                    mylines.y1 = tvar;
                    mylines.x1 = xmin;
                }

                // If the end point is to the left of xmin, calculate the intersection with the left boundary
                if (i == 0 && bytes[i] == 1)
                {
                    double tvar = Math.Round(m * xmin + c);
                    mylines.y2 = tvar;
                    mylines.x2 = xmin;
                }

                // If the initial point is to the right of xmax, calculate the intersection with the right boundary
                if (i == 1 && bits[i] == 1)
                {
                    double tvar = Math.Round(m * xmax + c);
                    mylines.y1 = tvar;
                    mylines.x1 = xmax;
                }

                // If the end point is to the right of xmax, calculate the intersection with the right boundary
                if (i == 1 && bytes[i] == 1)
                {
                    double tvar = Math.Round(m * xmax + c);
                    mylines.y2 = tvar;
                    mylines.x2 = xmax;
                }

                // If the initial point is above ymin, calculate the intersection with the top boundary
                if (i == 2 && bits[i] == 1)
                {
                    double tvar = Math.Round((ymin - c) / m);
                    mylines.y1 = ymin;
                    mylines.x1 = tvar;
                }

                // If the end point is above ymin, calculate the intersection with the top boundary
                if (i == 2 && bytes[i] == 1)
                {
                    double tvar = Math.Round((ymin - c) / m);
                    mylines.y2 = ymin;
                    mylines.x2 = tvar;
                }

                // If the initial point is below ymax, calculate the intersection with the bottom boundary
                if (i == 3 && bits[i] == 1)
                {
                    double tvar = Math.Round((ymax - c) / m);
                    mylines.y1 = ymax;
                    mylines.x1 = tvar;
                }

                // If the end point is below ymax, calculate the intersection with the bottom boundary
                if (i == 3 && bytes[i] == 1)
                {
                    double tvar = Math.Round((ymax - c) / m);
                    mylines.y2 = ymax;
                    mylines.x2 = tvar;
                }

                // Update the bits for the initial and end points
                bits[0] = Sign(xmin - mylines.x1);
                bytes[0] = Sign(xmin - mylines.x2);
                bits[1] = Sign(mylines.x1 - xmax);
                bytes[1] = Sign(mylines.x2 - xmax);
                bits[2] = Sign(ymin - mylines.y1);
                bytes[2] = Sign(ymin - mylines.y2);
                bits[3] = Sign(mylines.y1 - ymax);
                bytes[3] = Sign(mylines.y2 - ymax);
            }

            // If both points are now inside the window, print the line
            if (initial == end && end == "0000")
            {
                Console.WriteLine($"Line from ({mylines.x1}, {mylines.y1}) to ({mylines.x2}, {mylines.y2})");
                return;
            }
            else
            {
                return;
            }
        }
    }

    static void Main()
    {
        // Set the window boundaries
        xmin = 40;
        xmax = 100;
        ymin = 40;
        ymax = 80;

        // Create an array of Lines objects
        Lines[] mylines = new Lines[4];

        // Set the coordinates of the lines
        mylines[0] = new Lines(30, 65, 55, 30);
        mylines[1] = new Lines(60, 20, 100, 90);
        mylines[2] = new Lines(60, 100, 80, 70);
        mylines[3] = new Lines(85, 50, 120, 75);

        // Print the initial lines
        foreach (Lines line in mylines)
        {
            Console.WriteLine($"Line from ({line.x1}, {line.y1}) to ({line.x2}, {line.y2})");
        }

        // Clip each line and print the result
        foreach (Lines line in mylines)
        {
            Clip(line);
        }
    }
}
Javascript
// Global Variables
let xmin = 0, xmax = 0, ymin = 0, ymax = 0;

// Lines where co-ordinates are (x1, y1) and (x2, y2)
class Lines {
    constructor(x1, y1, x2, y2) {
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
    }
}

// This will return the sign required.
function sign(x) {
    return x > 0 ? 1 : 0;
}

// CohenSutherLand LineClipping Algorithm As Described in theory.
// This will clip the lines as per window boundaries.
function clip(mylines) {
    // arrays will store bits
    // Here bits implies initial Point whereas byte implies end points
    let bits = Array(4).fill(0);
    let byte = Array(4).fill(0);

    // Finding Bits
    bits[0] = sign(xmin - mylines.x1);
    byte[0] = sign(xmin - mylines.x2);
    bits[1] = sign(mylines.x1 - xmax);
    byte[1] = sign(mylines.x2 - xmax);
    bits[2] = sign(ymin - mylines.y1);
    byte[2] = sign(ymin - mylines.y2);
    bits[3] = sign(mylines.y1 - ymax);
    byte[3] = sign(mylines.y2 - ymax);

    // initial will used for initial coordinates and end for final
    let initial = bits.join("");
    let end = byte.join("");
    let temp = "";

    // finding slope of line y=mx+c as (y-y1)=m(x-x1)+c
    // where m is slope m=dy/dx;
    let m = (mylines.y2 - mylines.y1) / (mylines.x2 - mylines.x1);
    let c = mylines.y1 - m * mylines.x1;

    // if both points are inside the Accept the line and draw
    if (initial === end && end === "0000") {
        // plotting the line from (x1, y1) to (x2, y2)
        console.log(`Line from (${mylines.x1}, ${mylines.y1}) to (${mylines.x2}, ${mylines.y2})`);
        return;
    }

    // this will contain cases where line maybe totally outside for partially inside
    else {
        // taking bitwise end of every value
        for (let i = 0; i < 4; i++) {
            let val = bits[i] & byte[i];
            temp += val === 0 ? '0' : '1';
        }
        // as per algo if AND is not 0000 means line is completely outside hence draw nothing and return
        if (temp !== "0000") {
            return;
        }

        // Here contain cases of partial inside or outside
        // So check for every boundary one by one
        for (let i = 0; i < 4; i++) {
            // if both bit are same hence we cannot find any intersection with boundary so continue
            if (bits[i] === byte[i]) {
                continue;
            }
            // Otherwise there exist an intersection

            // Case when initial point is in left xmin
            if (i === 0 && bits[i] === 1) {
                let tvar = Math.round(m * xmin + c);
                mylines.y1 = tvar;
                mylines.x1 = xmin;
            }
            // Case when final point is in left xmin
            if (i === 0 && byte[i] === 1) {
                let tvar = Math.round(m * xmin + c);
                mylines.y2 = tvar;
                mylines.x2 = xmin;
            }
            // Case when initial point is in right of xmax
            if (i === 1 && bits[i] === 1) {
                let tvar = Math.round(m * xmax + c);
                mylines.y1 = tvar;
                mylines.x1 = xmax;
            }
            // Case when final point is in right of xmax
            if (i === 1 && byte[i] === 1) {
                let tvar = Math.round(m * xmax + c);
                mylines.y2 = tvar;
                mylines.x2 = xmax;
            }
            // Case when initial point is in top of ymin
            if (i === 2 && bits[i] === 1) {
                let tvar = Math.round((ymin - c) / m);
                mylines.y1 = ymin;
                mylines.x1 = tvar;
            }
            // Case when final point is in top of ymin
            if (i === 2 && byte[i] === 1) {
                let tvar = Math.round((ymin - c) / m);
                mylines.y2 = ymin;
                mylines.x2 = tvar;
            }
            // Case when initial point is in bottom of ymax
            if (i === 3 && bits[i] === 1) {
                let tvar = Math.round((ymax - c) / m);
                mylines.y1 = ymax;
                mylines.x1 = tvar;
            }
            // Case when final point is in bottom of ymax
            if (i === 3 && byte[i] === 1) {
                let tvar = Math.round((ymax - c) / m);
                mylines.y2 = ymax;
                mylines.x2 = tvar;
            }
            // Updating Bits at every point
            bits[0] = sign(xmin - mylines.x1);
            byte[0] = sign(xmin - mylines.x2);
            bits[1] = sign(mylines.x1 - xmax);
            byte[1] = sign(mylines.x2 - xmax);
            bits[2] = sign(ymin - mylines.y1);
            byte[2] = sign(ymin - mylines.y2);
            bits[3] = sign(mylines.y1 - ymax);
            byte[3] = sign(mylines.y2 - ymax);
        }

        // If now both points lie inside or on boundary then simply draw the updated line
        if (initial === end && end === "0000") {
            console.log(`Line from (${mylines.x1}, ${mylines.y1}) to (${mylines.x2}, ${mylines.y2})`);
            return;
        }
        // else line was completely outside hence rejected
        else {
            return;
        }
    }
}

// Driver Function
function main() {
    // Setting values of Clipping window
    xmin = 40;
    xmax = 100;
    ymin = 40;
    ymax = 80;

    // Assume 4 lines to be clipped
    let mylines = [];

    // Setting the coordinates of 4 lines
    mylines.push(new Lines(30, 65, 55, 30));
    mylines.push(new Lines(60, 20, 100, 90));
    mylines.push(new Lines(60, 100, 80, 70));
    mylines.push(new Lines(85, 50, 120, 75));

    // Drawing Initial Lines without clipping
    for (let line of mylines) {
        console.log(`Line from (${line.x1}, ${line.y1}) to (${line.x2}, ${line.y2})`);
    }

    // Drawing clipped Line
    for (let line of mylines) {
        // Calling clip() which in term clip the line as per window and draw it
        clip(line);
    }
}

main();
Python3
import matplotlib.pyplot as plt

# Global Variables
xmin, xmax, ymin, ymax = 0, 0, 0, 0

# Lines where co-ordinates are (x1, y1) and (x2, y2)
class Lines:
    def __init__(self, x1, y1, x2, y2):
        self.x1 = x1
        self.y1 = y1
        self.x2 = x2
        self.y2 = y2

# This will return the sign required.
def sign(x):
    if x > 0:
        return 1
    else:
        return 0

# CohenSutherLand LineClipping Algorithm As Described in theory.
# This will clip the lines as per window boundaries.
def clip(mylines):
    global xmin, xmax, ymin, ymax
    # arrays will store bits
    # Here bits implies initial Point whereas byte implies end points
    bits = [0]*4
    byte = [0]*4

    # Finding Bits
    bits[0] = sign(xmin - mylines.x1)
    byte[0] = sign(xmin - mylines.x2)
    bits[1] = sign(mylines.x1 - xmax)
    byte[1] = sign(mylines.x2 - xmax)
    bits[2] = sign(ymin - mylines.y1)
    byte[2] = sign(ymin - mylines.y2)
    bits[3] = sign(mylines.y1 - ymax)
    byte[3] = sign(mylines.y2 - ymax)

    # initial will used for initial coordinates and end for final
    initial = "".join(map(str, bits))
    end = "".join(map(str, byte))
    temp = ""

    # finding slope of line y=mx+c as (y-y1)=m(x-x1)+c
    # where m is slope m=dy/dx;
    m = (mylines.y2 - mylines.y1) / (mylines.x2 - mylines.x1)
    c = mylines.y1 - m * mylines.x1

    # if both points are inside the Accept the line and draw
    if initial == end and end == "0000":
        # plotting the line from (x1, y1) to (x2, y2)
        plt.plot([mylines.x1, mylines.x2], [mylines.y1, mylines.y2], color='red')
        return

    # this will contain cases where line maybe totally outside for partially inside
    else:
        # taking bitwise end of every value
        for i in range(4):
            val = bits[i] & byte[i]
            if val == 0:
                temp += '0'
            else:
                temp += '1'
        # as per algo if AND is not 0000 means line is completely outside hence draw nothing and return
        if temp != "0000":
            return

        # Here contain cases of partial inside or outside
        # So check for every boundary one by one
        for i in range(4):
            # if both bit are same hence we cannot find any intersection with boundary so continue
            if bits[i] == byte[i]:
                continue
            # Otherwise there exist an intersection

            # Case when initial point is in left xmin
            if i == 0 and bits[i] == 1:
                var = round(m * xmin + c)
                mylines.y1 = var
                mylines.x1 = xmin
            # Case when final point is in left xmin
            if i == 0 and byte[i] == 1:
                var = round(m * xmin + c)
                mylines.y2 = var
                mylines.x2 = xmin
            # Case when initial point is in right of xmax
            if i == 1 and bits[i] == 1:
                var = round(m * xmax + c)
                mylines.y1 = var
                mylines.x1 = xmax
            # Case when final point is in right of xmax
            if i == 1 and byte[i] == 1:
                var = round(m * xmax + c)
                mylines.y2 = var
                mylines.x2 = xmax
            # Case when initial point is in top of ymin
            if i == 2 and bits[i] == 1:
                var = round((ymin - c) / m)
                mylines.y1 = ymin
                mylines.x1 = var
            # Case when final point is in top of ymin
            if i == 2 and byte[i] == 1:
                var = round((ymin - c) / m)
                mylines.y2 = ymin
                mylines.x2 = var
            # Case when initial point is in bottom of ymax
            if i == 3 and bits[i] == 1:
                var = round((ymax - c) / m)
                mylines.y1 = ymax
                mylines.x1 = var
            # Case when final point is in bottom of ymax
            if i == 3 and byte[i] == 1:
                var = round((ymax - c) / m)
                mylines.y2 = ymax
                mylines.x2 = var
            # Updating Bits at every point
            bits[0] = sign(xmin - mylines.x1)
            byte[0] = sign(xmin - mylines.x2)
            bits[1] = sign(mylines.x1 - xmax)
            byte[1] = sign(mylines.x2 - xmax)
            bits[2] = sign(ymin - mylines.y1)
            byte[2] = sign(ymin - mylines.y2)
            bits[3] = sign(mylines.y1 - ymax)
            byte[3] = sign(mylines.y2 - ymax)

        # If now both points lie inside or on boundary then simply draw the updated line
        if initial == end and end == "0000":
            plt.plot([mylines.x1, mylines.x2], [mylines.y1, mylines.y2], color='red')
            return
        # else line was completely outside hence rejected
        else:
            return

# Driver Function
def main():
    global xmin, xmax, ymin, ymax

    # Setting values of Clipping window
    xmin = 40
    xmax = 100
    ymin = 40
    ymax = 80

    # Drawing Window using Lines
    plt.plot([xmin, xmax, xmax, xmin, xmin], [ymin, ymin, ymax, ymax, ymin], color='black')

    # Assume 4 lines to be clipped
    mylines = []

    # Setting the coordinates of 4 lines
    mylines.append(Lines(30, 65, 55, 30))
    mylines.append(Lines(60, 20, 100, 90))
    mylines.append(Lines(60, 100, 80, 70))
    mylines.append(Lines(85, 50, 120, 75))

    # Drawing Initial Lines without clipping
    for line in mylines:
        plt.plot([line.x1, line.x2], [line.y1, line.y2], color='blue')
        plt.pause(1)

    # Drawing clipped Line
    for line in mylines:
        # Calling clip() which in term clip the line as per window and draw it
        clip(line)
        plt.pause(1)

    plt.show()

if __name__ == "__main__":
    main()

The Cohen–Sutherland algorithm can be used only on a rectangular clip window. For other convex polygon clipping windows, Cyrus–Beck algorithm is used. We will be discussing Cyrus–Beck Algorithm in next set.

Related Post : 
Polygon Clipping | Sutherland–Hodgman Algorithm 
Point Clipping Algorithm in Computer Graphics
Reference: 
1) https://en.wikipedia.org/wiki/Cohen–Sutherland_algorithm

2)Book:-  Computer Graphics: By Donald Hearn, M. Pauline Baker

3) College notes



Last Updated : 12 Mar, 2024
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads