# Chain Code for 2D Line

Chain code is a lossless compression technique used for representing an object in images. The co-ordinates of any continuous boundary of an object can be represented as a string of numbers where each number represents a particular direction in which the next point on the connected line is present. One point is taken as the reference/starting point and on plotting the points generated from the chain, the original figure can be re-drawn.

This article describes how to generate a 8-neighbourhood chain code of a 2-D straight line. In a rectangular grid, a point can have at most 8 surrounding points as shown below. The next point on the line has to be one of these 8 surrounding points. Each direction is assigned a code. Using this code we can find out which of the surrounding point should be plotted next.

The chain codes could be generated by using conditional statements for each direction but it becomes very tedious to describe for systems having large number of directions(3-D grids can have up to 26 directions). Instead we use a hash function. The difference in X() and Y() co-ordinates of two successive points are calculated and hashed to generate the key for the chain code between the two points.

Chain code list:

Hash function:

Hash table:-

The function does not generate the value 4 so a dummy value is stored there.

Examples:

```Input : (2, -3), (-4, 2)
Output : Chain code for the straight line from (2, -3) to (-4, 2) is 333433```

```Input : (-7, -4), (9, 3)
Output : Chain code for the straight line from (-7, -4) to (9, 3) is 0101010100101010```

` `

## C++

 `// C++ code for generating 8-neighbourhood chain` `// code for a 2-D line` `#include ` `#include ` `#include `   `std::vector<``int``> codeList = { 5, 6, 7, 4, -1, 0, 3, 2, 1 };`   `// This function generates the chaincode` `// for transition between two neighbour points` `int` `getChainCode(``int` `x1, ``int` `y1, ``int` `x2, ``int` `y2)` `{` `    ``int` `dx = x2 - x1;` `    ``int` `dy = y2 - y1;` `    ``int` `hashKey = 3 * dy + dx + 4;` `    ``return` `codeList[hashKey];` `}`   `// This function generates the list of` `// chaincodes for given list of points` `std::vector<``int``> generateChainCode(` `    ``std::vector > ListOfPoints)` `{` `    ``std::vector<``int``> chainCode;` `    ``for` `(``int` `i = 0; i < ListOfPoints.size() - 1; i++) {` `        ``std::vector<``int``> a = ListOfPoints[i];` `        ``std::vector<``int``> b = ListOfPoints[i + 1];` `        ``chainCode.push_back(` `            ``getChainCode(a[0], a[1], b[0], b[1]));` `    ``}` `    ``return` `chainCode;` `}`   `// This function generates the list of points for` `// a straight line using Bresenham's Algorithm` `std::vector > Bresenham2D(``int` `x1, ``int` `y1,` `                                           ``int` `x2, ``int` `y2)` `{` `    ``std::vector > ListOfPoints;` `    ``ListOfPoints.push_back({ x1, y1 });` `    ``int` `xdif = x2 - x1;` `    ``int` `ydif = y2 - y1;` `    ``int` `dx = ``abs``(xdif);` `    ``int` `dy = ``abs``(ydif);` `    ``int` `xs;` `    ``if` `(xdif > 0) {` `        ``xs = 1;` `    ``}` `    ``else` `{` `        ``xs = -1;` `    ``}`   `    ``int` `ys;` `    ``if` `(ydif > 0) {` `        ``ys = 1;` `    ``}` `    ``else` `{` `        ``ys = -1;` `    ``}`   `    ``if` `(dx > dy) {` `        ``// Driving axis is the X-axis` `        ``int` `p = 2 * dy - dx;` `        ``while` `(x1 != x2) {` `            ``x1 += xs;` `            ``if` `(p >= 0) {` `                ``y1 += ys;` `                ``p -= 2 * dx;` `            ``}` `            ``p += 2 * dy;` `            ``ListOfPoints.push_back({ x1, y1 });` `        ``}` `    ``}` `    ``else` `{` `        ``// Driving axis is the Y-axis` `        ``int` `p = 2 * dx - dy;` `        ``while` `(y1 != y2) {` `            ``y1 += ys;` `            ``if` `(p >= 0) {` `                ``x1 += xs;` `                ``p -= 2 * dy;` `            ``}` `            ``p += 2 * dx;` `            ``ListOfPoints.push_back({ x1, y1 });` `        ``}` `    ``}`   `    ``return` `ListOfPoints;` `}`   `void` `DriverFunction()` `{` `    ``int` `x1 = -9;` `    ``int` `y1 = -3;` `    ``int` `x2 = 10;` `    ``int` `y2 = 1;` `    ``std::vector > ListOfPoints` `        ``= Bresenham2D(x1, y1, x2, y2);` `    ``std::vector<``int``> chainCode` `        ``= generateChainCode(ListOfPoints);`   `    ``std::string chainCodeString = ``""``;` `    ``for` `(``int` `i = 0; i < chainCode.size(); i++) {` `        ``chainCodeString += std::to_string(chainCode[i]);` `    ``}`   `    ``std::cout << ``"Chain code for the straight line from ("` `              ``<< x1 << ``","` `<< y1 << ``") to ("` `<< x2 << ``","` `              ``<< y2 << ``") is "` `<< chainCodeString` `              ``<< std::endl;` `}`   `int` `main()` `{` `    ``DriverFunction();` `    ``return` `0;` `}`   `// This code is contributed by ishankhndelwals.`

## Java

 `import` `java.util.ArrayList;` `import` `java.util.List;`   `public` `class` `Main {` `  ``static` `List codeList` `    ``= ``new` `ArrayList();` `  ``static` `  ``{` `    ``codeList.add(``5``);` `    ``codeList.add(``6``);` `    ``codeList.add(``7``);` `    ``codeList.add(``4``);` `    ``codeList.add(-``1``);` `    ``codeList.add(``0``);` `    ``codeList.add(``3``);` `    ``codeList.add(``2``);` `    ``codeList.add(``1``);` `  ``}`   `  ``// This function generates the chaincode` `  ``// for transition between two neighbour points` `  ``static` `int` `getChainCode(``int` `x1, ``int` `y1, ``int` `x2, ``int` `y2)` `  ``{` `    ``int` `dx = x2 - x1;` `    ``int` `dy = y2 - y1;` `    ``int` `hashKey = ``3` `* dy + dx + ``4``;` `    ``return` `codeList.get(hashKey);` `  ``}`   `  ``// This function generates the list of` `  ``// chaincodes for given list of points` `  ``static` `List` `    ``generateChainCode(List > ListOfPoints)` `  ``{` `    ``List chainCode = ``new` `ArrayList();` `    ``for` `(``int` `i = ``0``; i < ListOfPoints.size() - ``1``; i++) {` `      ``List a = ListOfPoints.get(i);` `      ``List b = ListOfPoints.get(i + ``1``);` `      ``chainCode.add(getChainCode(a.get(``0``), a.get(``1``),` `                                 ``b.get(``0``), b.get(``1``)));` `    ``}` `    ``return` `chainCode;` `  ``}`   `  ``// This function generates the list of points for` `  ``// a straight line using Bresenham's Algorithm` `  ``static` `List > Bresenham2D(``int` `x1, ``int` `y1,` `                                          ``int` `x2, ``int` `y2)` `  ``{` `    ``List > ListOfPoints` `      ``= ``new` `ArrayList >();` `    ``ListOfPoints.add(List.of(x1, y1));` `    ``int` `xdif = x2 - x1;` `    ``int` `ydif = y2 - y1;` `    ``int` `dx = Math.abs(xdif);` `    ``int` `dy = Math.abs(ydif);` `    ``int` `xs;` `    ``if` `(xdif > ``0``) {` `      ``xs = ``1``;` `    ``}` `    ``else` `{` `      ``xs = -``1``;` `    ``}`   `    ``int` `ys;` `    ``if` `(ydif > ``0``) {` `      ``ys = ``1``;` `    ``}` `    ``else` `{` `      ``ys = -``1``;` `    ``}`   `    ``if` `(dx > dy) {` `      ``// Driving axis is the X-axis` `      ``int` `p = ``2` `* dy - dx;` `      ``while` `(x1 != x2) {` `        ``x1 += xs;` `        ``if` `(p >= ``0``) {` `          ``y1 += ys;` `          ``p -= ``2` `* dx;` `        ``}` `        ``p += ``2` `* dy;` `        ``ListOfPoints.add(List.of(x1, y1));` `      ``}` `    ``}` `    ``else` `{` `      ``// Driving axis is the Y-axis` `      ``int` `p = ``2` `* dx - dy;` `      ``while` `(y1 != y2) {` `        ``y1 += ys;` `        ``if` `(p >= ``0``) {` `          ``x1 += xs;` `          ``p -= ``2` `* dy;` `        ``}` `        ``p += ``2` `* dx;` `        ``ListOfPoints.add(List.of(x1, y1));` `      ``}` `    ``}`   `    ``return` `ListOfPoints;` `  ``}`   `  ``static` `void` `DriverFunction()` `  ``{` `    ``int` `x1 = -``9``;` `    ``int` `y1 = -``3``;` `    ``int` `x2 = ``10``;` `    ``int` `y2 = ``1``;` `    ``List > ListOfPoints` `      ``= Bresenham2D(x1, y1, x2, y2);` `    ``List chainCode` `      ``= generateChainCode(ListOfPoints);`   `    ``StringBuilder chainCodeString = ``new` `StringBuilder();` `    ``for` `(``int` `i = ``0``; i < chainCode.size(); i++) {` `      ``chainCodeString.append(` `        ``Integer.toString(chainCode.get(i)));` `    ``}`   `    ``System.out.println(` `      ``"Chain code for the straight line from ("` `+ x1` `      ``+ ``","` `+ y1 + ``") to ("` `+ x2 + ``","` `+ y2 + ``") is "` `      ``+ chainCodeString);` `  ``}`   `  ``public` `static` `void` `main(String[] args)` `  ``{` `    ``DriverFunction();` `  ``}` `}`   `// This code is contributed by ishankhandelwals.`

## Python3

 `# Python3 code for generating 8-neighbourhood chain` `# code for a 2-D line`   `codeList ``=` `[``5``, ``6``, ``7``, ``4``, ``-``1``, ``0``, ``3``, ``2``, ``1``]`   `# This function generates the chaincode ` `# for transition between two neighbour points` `def` `getChainCode(x1, y1, x2, y2):` `    ``dx ``=` `x2 ``-` `x1` `    ``dy ``=` `y2 ``-` `y1` `    ``hashKey ``=` `3` `*` `dy ``+` `dx ``+` `4` `    ``return` `codeList[hashKey]`   `'''This function generates the list of ` `chaincodes for given list of points'''` `def` `generateChainCode(ListOfPoints):` `    ``chainCode ``=` `[]` `    ``for` `i ``in` `range``(``len``(ListOfPoints) ``-` `1``):` `        ``a ``=` `ListOfPoints[i]` `        ``b ``=` `ListOfPoints[i ``+` `1``]` `        ``chainCode.append(getChainCode(a[``0``], a[``1``], b[``0``], b[``1``]))` `    ``return` `chainCode`     `'''This function generates the list of points for ` `a straight line using Bresenham's Algorithm'''` `def` `Bresenham2D(x1, y1, x2, y2):` `    ``ListOfPoints ``=` `[]` `    ``ListOfPoints.append([x1, y1])` `    ``xdif ``=` `x2 ``-` `x1` `    ``ydif ``=` `y2 ``-` `y1` `    ``dx ``=` `abs``(xdif)` `    ``dy ``=` `abs``(ydif)` `    ``if``(xdif > ``0``):` `        ``xs ``=` `1` `    ``else``:` `        ``xs ``=` `-``1` `    ``if` `(ydif > ``0``):` `        ``ys ``=` `1` `    ``else``:` `        ``ys ``=` `-``1` `    ``if` `(dx > dy):`   `        ``# Driving axis is the X-axis` `        ``p ``=` `2` `*` `dy ``-` `dx` `        ``while` `(x1 !``=` `x2):` `            ``x1 ``+``=` `xs` `            ``if` `(p >``=` `0``):` `                ``y1 ``+``=` `ys` `                ``p ``-``=` `2` `*` `dx` `            ``p ``+``=` `2` `*` `dy` `            ``ListOfPoints.append([x1, y1])` `    ``else``:`   `        ``# Driving axis is the Y-axis` `        ``p ``=` `2` `*` `dx``-``dy` `        ``while``(y1 !``=` `y2):` `            ``y1 ``+``=` `ys` `            ``if` `(p >``=` `0``):` `                ``x1 ``+``=` `xs` `                ``p ``-``=` `2` `*` `dy` `            ``p ``+``=` `2` `*` `dx` `            ``ListOfPoints.append([x1, y1])` `    ``return` `ListOfPoints`   `def` `DriverFunction():` `    ``(x1, y1) ``=` `(``-``9``, ``-``3``)` `    ``(x2, y2) ``=` `(``10``, ``1``)` `    ``ListOfPoints ``=` `Bresenham2D(x1, y1, x2, y2)` `    ``chainCode ``=` `generateChainCode(ListOfPoints)` `    ``chainCodeString ``=` `"".join(``str``(e) ``for` `e ``in` `chainCode)` `    ``print` `(``'Chain code for the straight line from'``, (x1, y1), ` `            ``'to'``, (x2, y2), ``'is'``, chainCodeString)`   `DriverFunction()`

## C#

 `using` `System;` `using` `System.Collections.Generic;` `using` `System.Linq;` `using` `System.Text;`   `namespace` `CPP_to_C_Sharp` `{` `  ``class` `Program` `  ``{` `    ``static` `List<``int``> codeList = ``new` `List<``int``> { 5, 6, 7, 4, -1, 0, 3, 2, 1 };`   `    ``// This function generates the chaincode` `    ``// for transition between two neighbour points` `    ``static` `int` `getChainCode(``int` `x1, ``int` `y1, ``int` `x2, ``int` `y2)` `    ``{` `      ``int` `dx = x2 - x1;` `      ``int` `dy = y2 - y1;` `      ``int` `hashKey = 3 * dy + dx + 4;` `      ``return` `codeList[hashKey];` `    ``}`   `    ``// This function generates the list of` `    ``// chaincodes for given list of points` `    ``static` `List<``int``> generateChainCode(` `      ``List> ListOfPoints)` `    ``{` `      ``List<``int``> chainCode = ``new` `List<``int``>();` `      ``for` `(``int` `i = 0; i < ListOfPoints.Count - 1; i++)` `      ``{` `        ``List<``int``> a = ListOfPoints[i];` `        ``List<``int``> b = ListOfPoints[i + 1];` `        ``chainCode.Add(getChainCode(a[0], a[1], b[0], b[1]));` `      ``}` `      ``return` `chainCode;` `    ``}`   `    ``// This function generates the list of points for` `    ``// a straight line using Bresenham's Algorithm` `    ``static` `List> Bresenham2D(``int` `x1, ``int` `y1,` `                                       ``int` `x2, ``int` `y2)` `    ``{` `      ``List> ListOfPoints = ``new` `List>();` `      ``ListOfPoints.Add(``new` `List<``int``> { x1, y1 });` `      ``int` `xdif = x2 - x1;` `      ``int` `ydif = y2 - y1;` `      ``int` `dx = Math.Abs(xdif);` `      ``int` `dy = Math.Abs(ydif);` `      ``int` `xs;` `      ``if` `(xdif > 0)` `      ``{` `        ``xs = 1;` `      ``}` `      ``else` `      ``{` `        ``xs = -1;` `      ``}`   `      ``int` `ys;` `      ``if` `(ydif > 0)` `      ``{` `        ``ys = 1;` `      ``}` `      ``else` `      ``{` `        ``ys = -1;` `      ``}`   `      ``if` `(dx > dy)` `      ``{` `        ``// Driving axis is the X-axis` `        ``int` `p = 2 * dy - dx;` `        ``while` `(x1 != x2)` `        ``{` `          ``x1 += xs;` `          ``if` `(p >= 0)` `          ``{` `            ``y1 += ys;` `            ``p -= 2 * dx;` `          ``}` `          ``p += 2 * dy;` `          ``ListOfPoints.Add(``new` `List<``int``> { x1, y1 });` `        ``}` `      ``}` `      ``else` `      ``{` `        ``// Driving axis is the Y-axis` `        ``int` `p = 2 * dx - dy;` `        ``while` `(y1 != y2)` `        ``{` `          ``y1 += ys;` `          ``if` `(p >= 0)` `          ``{` `            ``x1 += xs;` `            ``p -= 2 * dy;` `          ``}` `          ``p += 2 * dx;` `          ``ListOfPoints.Add(``new` `List<``int``> { x1, y1 });` `        ``}` `      ``}`   `      ``return` `ListOfPoints;` `    ``}`   `    ``static` `void` `DriverFunction()` `    ``{` `      ``int` `x1 = -9;` `      ``int` `y1 = -3;` `      ``int` `x2 = 10;` `      ``int` `y2 = 1;` `      ``List> ListOfPoints` `        ``= Bresenham2D(x1, y1, x2, y2);` `      ``List<``int``> chainCode` `        ``= generateChainCode(ListOfPoints);`   `      ``string` `chainCodeString = ``""``;` `      ``for` `(``int` `i = 0; i < chainCode.Count; i++)` `      ``{` `        ``chainCodeString += chainCode[i].ToString();` `      ``}`   `      ``Console.WriteLine(``"Chain code for the straight line from ("` `                        ``+ x1 + ``","` `+ y1 + ``") to ("` `+ x2 + ``","` `                        ``+ y2 + ``") is "` `+ chainCodeString);` `    ``}`   `    ``static` `void` `Main(``string``[] args)` `    ``{` `      ``DriverFunction();` `    ``}` `  ``}` `}`   `// This code is contributed by ishankhandelwals.`

## Javascript

 `// JavaScript code for generating 8-neighbourhood chain` `// code for a 2-D line`   `let codeList = [5, 6, 7, 4, -1, 0, 3, 2, 1];`   `// This function generates the chaincode ` `// for transition between two neighbour points` `function` `getChainCode(x1, y1, x2, y2){` `    ``let dx = x2 - x1;` `    ``let dy = y2 - y1;` `    ``let hashKey = 3 * dy + dx + 4;` `    ``return` `codeList[hashKey];   ` `}`     `// This function generates the list of ` `// chaincodes for given list of points` `function` `generateChainCode(ListOfPoints){` `    ``let chainCode = [];` `    ``for``(let i = 0; i < ListOfPoints.length-1; i++){` `        ``let a = ListOfPoints[i];` `        ``let b = ListOfPoints[i + 1];` `        ``chainCode.push(getChainCode(a[0], a[1], b[0], b[1]));` `            `  `    ``}` `    ``return` `chainCode;    ` `}`   `// This function generates the list of points for ` `// a straight line using Bresenham's Algorithm` `function` `Bresenham2D(x1, y1, x2, y2){` `    ``let ListOfPoints = [];` `    ``ListOfPoints.push([x1, y1]);` `    ``let xdif = x2 - x1;` `    ``let ydif = y2 - y1;` `    ``let dx = Math.abs(xdif);` `    ``let dy = Math.abs(ydif);` `    ``if``(xdif > 0){` `        ``xs = 1;` `    ``}       ` `    ``else``{` `        ``xs = -1;` `    ``}` `        `  `    ``if` `(ydif > 0){` `        ``ys = 1;` `    ``}` `    ``else``{` `        ``ys = -1;` `    ``}` `        `  `    ``if` `(dx > dy){` `        ``// Driving axis is the X-axis` `        ``let p = 2 * dy - dx;` `        ``while` `(x1 != x2){` `            ``x1 += xs` `            ``if` `(p >= 0){` `                ``y1 += ys;` `                ``p -= 2 * dx;         ` `            ``}` `            ``p += 2 * dy;` `            ``ListOfPoints.push([x1, y1]);         ` `        ``}` `       `  `    ``}` `    ``else``{` `        ``// Driving axis is the Y-axis` `        ``let p = 2 * dx-dy;` `        ``while``(y1 != y2){` `             ``y1 += ys;` `            ``if` `(p >= 0){` `                ``x1 += xs;` `                ``p -= 2 * dy;              ` `            ``}` `            ``p += 2 * dx;` `            ``ListOfPoints.push([x1, y1]);        ` `        ``}` `    ``}` `    `  `    ``return` `ListOfPoints   ` `}`     `function` `DriverFunction(){` `    ``let x1 = -9;` `    ``let y1 = -3;` `    ``let x2 = 10;` `    ``let y2 = 1;` `    ``let ListOfPoints = Bresenham2D(x1, y1, x2, y2);` `    ``let chainCode = generateChainCode(ListOfPoints);` `    `  `    ``let chainCodeString = ``""``;` `    ``for``(let i = 0; i < chainCode.length; i++){` `            ``chainCodeString += chainCode[i].toString();    ` `    ``}`   `    ``console.log(``"Chain code for the straight line from ("``, x1,``","``, y1,``")"``,``"to"``,``"("``, x2,``","``, y2,``")"``, ``"is"``, chainCodeString);` `}`   `DriverFunction();` `// The code is contributed by Nidhi goel`

Output:

`Chain code for the straight line from (-9, -3) to (10, 1) is 0010000100010000100`

Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!

Previous
Next