Select to view content in your preferred language

Japanese visual multiplication with lines using arcpy

2100
11
07-03-2014 07:51 PM
XanderBakker
Esri Esteemed Contributor
3 11 2,100

Today I stumbled upon a tweet showing how children in Japan are using line intersections to calculate the multiplication of two numbers. I was amazed by the beauty of the method which can be extended to larger numbers too.  Just take a look at the example below:

Japanese-Multiplication-Trick.jpg

Source: http://www.pinpopular.com/japanese-multiplication-trick-pinterest-education/

It is basically counting intersections of lines. Wait ... intersections of lines ... sounds to me that arcpy could do that too. So, why not write some arcpy / python code to multiply 2 numbers?

I know, what you're thinking ... why? Because it's fun and completely useless!

So this is what I came up with:

# Japanese visual multiplication with arcpy

import arcpy

import os

ws = r"C:\Forum\JapaneseMultiply\fgdb\test.gdb"

arcpy.env.workspace = ws

arcpy.env.overwriteOutput = True

sr = arcpy.SpatialReference(3857)

arcpy.env.outputCoordinateSystem = sr

# values to multiply:

value1 = 47 # (1 -99)

value2 = 63 # (1 -99)

fc_points = "points"

fc_lines_h = "lines_h"

fc_lines_v = "lines_v"

fc_polygones = "polygons"

fc_result = "result"

size = 10

fld_factor = "factor"

val_h1 = value1 / 10

val_h2 = value1 % 10

val_v1 = value2 / 10

val_v2 = value2 % 10

# create horizontal lines

arcpy.CreateFeatureclass_management(ws, fc_lines_h, "POLYLINE", "#", "DISABLED", "DISABLED", sr)

with arcpy.da.InsertCursor(fc_lines_h, ("SHAPE@")) as rows:

    for y in range(1, val_h1 + 1):

        x1 = -1 * size

        x2 = size

        array = arcpy.Array([arcpy.Point(x1, y),

                     arcpy.Point(x2, y)])

        polyline = arcpy.Polyline(array)

        rows.insertRow([polyline])

    for y in range(1, val_h2 + 1):

        x1 = -1 * size

        x2 = size

        array = arcpy.Array([arcpy.Point(x1, -1 * y),

                     arcpy.Point(x2, -1 * y)])

        polyline = arcpy.Polyline(array)

        rows.insertRow([polyline])

# create vertical lines

arcpy.CreateFeatureclass_management(ws, fc_lines_v, "POLYLINE", "#", "DISABLED", "DISABLED", sr)

with arcpy.da.InsertCursor(fc_lines_v, ("SHAPE@")) as rows:

    for x in range(1, val_v1 + 1):

        y1 = -1 * size

        y2 = size

        array = arcpy.Array([arcpy.Point(-1 * x, y1),

                     arcpy.Point(-1 * x, y2)])

        polyline = arcpy.Polyline(array)

        rows.insertRow([polyline])

    for x in range(1, val_v2 + 1):

        y1 = -1 * size

        y2 = size

        array = arcpy.Array([arcpy.Point(x, y1),

                     arcpy.Point(x, y2)])

        polyline = arcpy.Polyline(array)

        rows.insertRow([polyline])

# Create polygon cuadrants

arcpy.CreateFeatureclass_management(ws, fc_polygones, "POLYGON", "#", "DISABLED", "DISABLED", sr)

arcpy.AddField_management(fc_polygones, fld_factor, "DOUBLE")

with arcpy.da.InsertCursor(fc_polygones, ("SHAPE@", fld_factor)) as rows:

    # left top factor 100

    factor = 100

    array = arcpy.Array([arcpy.Point(-1 * size, 0),

                         arcpy.Point(-1 * size, size),

                         arcpy.Point(0, size),

                         arcpy.Point(0, 0),

                         arcpy.Point(-1 * size, 0)])

    polygon = arcpy.Polygon(array)

    rows.insertRow([polygon, factor])

    # right top factor 10

    factor = 10

    array = arcpy.Array([arcpy.Point(0, 0),

                         arcpy.Point(0, size),

                         arcpy.Point(size, size),

                         arcpy.Point(size, 0),

                         arcpy.Point(0, 0)])

    polygon = arcpy.Polygon(array)

    rows.insertRow([polygon, factor])

    # left bottom factor 10

    factor = 10

    array = arcpy.Array([arcpy.Point(-1 * size, -1 * size),

                         arcpy.Point(-1 * size, 0),

                         arcpy.Point(0, 0),

                         arcpy.Point(0, -1 * size),

                         arcpy.Point(-1 * size, -1 * size)])

    polygon = arcpy.Polygon(array)

    rows.insertRow([polygon, factor])

    # right bottom factor 1

    factor = 1

    array = arcpy.Array([arcpy.Point(0, 0),

                         arcpy.Point(0, -1 * size),

                         arcpy.Point(size, -1 * size),

                         arcpy.Point(size, 0),

                         arcpy.Point(0, 0)])

    polygon = arcpy.Polygon(array)

    rows.insertRow([polygon, factor])

# start analysis: intersect horizontal and vertical lines

arcpy.Intersect_analysis([fc_lines_h, fc_lines_v], fc_points, "ALL", "", "POINT")

# Next intersect the polygon with the points (intersection of lines)

arcpy.Intersect_analysis([fc_polygones, fc_points], fc_result)

# now use Search cursor to get result

res = 0

with arcpy.da.SearchCursor(fc_result, (fld_factor)) as rows:

    for row in rows:

        factor = row[0]

        res += factor

print "{0} * {1} = {2}".format(value1, value2, res)

print "verify: {0} * {1} = {2}".format(value1, value2, value1 * value2)

In the example above the following result is printed:

47 * 63 = 2961.0

verify: 47 * 63 = 2961

Displaying the featureclasses gives the following result:

result.png

I hope my next blog post will be of more use.

Xander

Tags (2)
11 Comments
About the Author
Solution Engineer for the Utilities Sector @ Esri Colombia - Ecuador - Panamá sr GIS Advisor / Python - Arcpy developer / GIS analyst / technical project leader / lecturer and GeoNet moderator, focusing on innovations in the field of GIS. Specialties: ArcGIS, Python, ArcGIS Enterprise, ArcGIS Online, Arcade, Configurable Apps, WAB, Mobile Apps, Insights, Spatial Analysis, LiDAR / 3D Laser Scanning / Point Clouds. UNME http://nl.linkedin.com/in/xanderbakker/ http://www.slideshare.net/XanderBakker http://www.scribd.com/xbakker http://twitter.com/#!/XanderBakker
Labels