صور النمطي هندسي متكرر في بيثون. تجول

مرحبا يا هابر! لقد ظهرت مشاركة اليوم على فركتلات كجزء من موضوع Python ، على وجه الخصوص ، Matplotlib. اتبع مثال المؤلف وحذر من أنه يوجد في المنشور الكثير من الرسوم المتحركة الثقيلة التي قد لا تعمل حتى على جهاز محمول. ولكن كم هو جميل.



يستمتع الجميع بالقراءة

صور النمطي هندسي متكرر جميلة. إنها تتماشى مع نمط معقد للغاية ويتم الحفاظ عليها بدون تشويه بأي تكبير! في هذه المقالة ، سنلقي نظرة على كيفية رسم الفركتلات بسهولة من عدة أنواع ، باستخدام أداة تسمى L-Systems ووحدة السلاحف لـ Python لأداء الرسم خطوة بخطوة.

في هذه المقالة ، لن نتطرق بشكل مفرط إلى التفاصيل الفنية ؛ بدلاً من ذلك ، أقصر نفسي على مقدمة موجزة ، وأعرض الكثير من الأمثلة المتحركة والرمز الذي يمكنك من خلاله إنشاء مثل هذا المثال. إذا كنت تريد تخطي النظرية ومشاهدة الرسوم المتحركة فقط ، فانتقل مباشرة إلى الأمثلة. بالإضافة إلى ذلك ، في النهاية ، سأشير إلى العديد من الموارد ، التي قد ترغب في استكشافها في كتابة التعليمات البرمجية وفي الرياضيات الأساسية.

ما هو الفراكتل؟

للبدء ، دعنا نعطي تعريفًا "فضفاضًا" للفراكتل. من حيث المبدأ ، الفركتل هو شكل هندسي يوضح نفس الخصائص بغض النظر عن درجة الزيادة.

هذا التعريف ليس مثاليًا ، لذلك هنا تعريف أكثر دقة من موقع Math World:
الفركتل هو شيء أو كمية تُظهر التشابه الذاتي (بالمعنى الرسمي) على أي نطاق. لا يعرض الكائن هياكل متطابقة بمقاييس مختلفة ، ولكن يجب أن تظهر الهياكل من "النوع" نفسه على جميع مستويات الفراكتل. في هذه الحالة ، يتم رسم الرسم البياني في نظام إحداثيات بمقياس لوغاريتمي ، حيث يتم حساب الحجم والمقياس على طول المحاور ، ثم الرسم البياني هو خط مستقيم مع منحدر يعكس أبعاد الفراكتل. - عالم الرياضيات

كيفية رسم فركتلات باستخدام بايثون؟

عادةً ما يكون تقديم الفركتلات معقدًا ، حيث يتم تحديد الطبيعة العميقة للفراكتات بمفهوم العودية. بالحديث عن الرسوم البيانية ورسمها ، نعتقد عادة أنها تتكون من وحدات بكسل أو متجهات ، ولكن عدد وحدات البكسل أو المتجهات محدود دائمًا ، والكسور ، بحكم تعريفها ، متكررة بشكل لا نهائي. وبالتالي ، عند محاولة تطبيق فراكتل على شبكة الإحداثيات ، سيتعين علينا التوقف عند نقطة ما ، ولهذا نتحدث عن "التكرارات" في هذه الحالة. في كل تكرار ، يصبح الفراكتل أكثر تعقيدًا ، وفي مرحلة ما يصبح من المستحيل التمييز بين اثنين من تكراراته بعد بعضها البعض (تحدث مثل هذه اللحظة عندما تحدث تغييرات عند مستوى مماثل لحجم البكسل). من المنطقي أن تتوقف هنا ، ولكن ، كقاعدة عامة ، يلوح شكل الفراكتل بشكل أسرع ، ويمكنك التوقف حتى قبل ذلك.

مثالان متشابهان هما جزيرة كوخ المربعة ، التي يظهر هيكلها بوضوح بعد ثلاثة تكرارات ، وتنين كارتر هيتواي ، والتي تكفي 8 تكرارات لبناء الهيكل الكامل. يعتمد العدد المطلوب من التكرارات بشكل كبير على الفراكتل المحدد الذي نعمل معه.

بالطبع ، هناك العديد من مكتبات Python للتآمر ، من بينها الأكثر شيوعًا Matplotlib ، ولكنها عادة ما تكون مصممة لرسم الإحصاءات ورسم الرسوم البيانية المعروفة. على وجه الخصوص ، يحتوي Matplotlib على بعض الإنشاءات ذات المستوى المنخفض التي يمكن استخدامها لبناء صور النمطي هندسي متكرر ، ولكن هذه المرة سنركز على الوحدة غير المعروفة من المكتبة القياسية غير المعروفة باسم السلحفاة.

وحدة السلاحف

في وثائق بايثوننقرأ: "رسومات السلاحف هي أداة شائعة للتعارف الأول للأطفال مع البرمجة. كان جزءًا من لغة برمجة الشعار الأصلية ، التي طورها والي والي فورزمور وسيمور بيبر في عام 1966. "

خلاصة القول هي أن السلحفاة تتعرف على 3 أوامر بشكل افتراضي:

  • الزحف إلى الأمام
  • تدوير الزاوية اليسرى
  • تدوير الزاوية اليمنى

ملاحظة: يتم توفير أوامر أخرى في المكتبة القياسية ، ولكن هنا سنستخدم هذه الثلاثة فقط.

يمكننا أيضًا:

  • سجل كتم الصوت
  • تمكين التسجيل

تبدو هذه الخصائص بسيطة للغاية بحيث لا يمكن رسمها على رسم بياني معقد مثل كسورية ، معتمدين عليها فقط ، لكننا سنستخدم أداة أخرى تستخدم هذه المجموعة الصغيرة من التعليمات فقط. أنا أتحدث عن أنظمة L.

L-systems

النظام L هو طريقة لتمثيل الهياكل العودية (على سبيل المثال ، الفركتلات) كسلسلة من الأحرف وإعادة كتابة مثل هذه السلسلة عدة مرات. مرة أخرى ، نقدم تعريفًا رسميًا:
نظام Lindenmeyer ، المعروف أيضًا باسم L-system ، هو عبارة عن آلية لإعادة كتابة الخط يمكن استخدامها لتوليد فركتلات بأبعاد من 1 إلى 2 - عالم الرياضيات

بعد فهم ما هو نظام L ، يمكننا إنشاء هياكل متكررة ، ولكن أولاً ، دعونا نكتشف المكونات التي نحتاجها لهذا. لكل نظام L:

  • : , L-.
  • : .
  • : , .

ملاحظة لمحبي علوم الكمبيوتر: إذا كنت قد درست علوم الكمبيوتر بتعمق ، فقد يذكرك كل ما سبق بشيء ما. في الواقع ، القواعد النحوية محددة بشكل مشابه جدا. والفرق الرئيسي هو أنه ، على عكس القواعد النحوية ، هنا في كل تكرار يتم تطبيق العديد من القواعد قدر الإمكان ، وليس قاعدة واحدة فقط. لذلك ، تعد أنظمة L مجموعة فرعية من القواعد النحوية الخالية من السياق.

بالنظر إلى أننا سنستخدم السلاحف لبناء الرسوم البيانية ونظام L لتمثيل ما سنرسمه ، نحتاج إلى إنشاء علاقة بينهما.

نظرًا لأننا في Turtle لدينا فقط الفرق المذكورة أعلاه ، فإننا نعطي كل منهم رمزًا ؛ تتكون الأبجدية من هذه الأحرف.

  • F: الزحف إلى الأمام
  • +: إستدر لليمين
  • -: انعطف لليسار

لكي يعمل هذا ، يجب توفير زاوية لكل فراكتل ؛ ستكون هذه هي الزاوية التي تتحول فيها السلحفاة إلى اليمين أو اليسار. من أجل البساطة ، نتفق على أنه يجب توفير زاوية واحدة فقط ، وسنكتب نظام L ، مع مراعاة ذلك.
تعتمد البديهية والتعليمات الخاصة بإنشاء سلاسل على الفراكتل فقط ، ولكن يجب كتابة الفراكتل بطريقة لا يمكن تمثيلها إلا بهذه الأحرف الثلاثة. لذا ، هناك قيود ، لا يمكننا من خلالها بناء فراكتل ذات خط واحد فقط ، أي أنه لا يمكن الحصول على شيء مثل مجموعة كانتور بهذه الطريقة. لكن هذا مجرد تبسيط ، لأنه يمكننا دائمًا إدخال أمرين آخرين للمضي قدمًا دون تسجيل ، والشيء نفسه للتحرك للخلف.

الآن دعونا نصل إلى الأمثلة!

أمثلة متحركة

تم أخذ الأمثلة التالية عبر الإنترنت من عدة مصادر متاحة للجمهور ، وقررت نقلها إلى Python باستخدام وحدة Turtle ، وتوسيطها ، وتلوينها ، وتوفير طريقة للتصدير إلى تنسيق متجه.

تنبيه: الرسوم المتحركة المقترحة كبيرة جدًا ، فمن المستحسن مشاهدتها فقط مع إنترنت جيد. قد لا يعمل رمز الاستبدال لأنه يستهلك مواردك ، وقد تكون هناك مشاكل في عرض صور النمطي هندسي متكرر على الأجهزة المحمولة.

ملاحظة: يستخدم Skulpt متصفحك لتقديم الرسوم المتحركة وإنشائها ، لذلك عندما تعلق أو تتأخر أو أي سلوك غريب ، يكفي عادةً إعادة تشغيل الرسوم المتحركة أو إعادة تحميل الصفحة. قد لا يعمل على الجهاز المحمول.

الأمثلة مقدمة بترتيب التعقيد (في رأيي الشخصي) ، لذلك الشيء الأكثر إثارة للاهتمام هو في النهاية.

ندفة الثلج كوخ

axiom = "F--F--F"
rules = {"F":"F+F--F+F"}
iterations = 4 # TOP: 7
angle = 60


جزيرة كوخ سكوير

axiom = "F+F+F+F"
rules = {"F":"F-F+F+FFF-F-F+F"}
iterations = 2 # TOP: 4
angle = 90


كريستال

axiom = "F+F+F+F"
rules = {"F":"FF+F++F+F"}
iterations = 3 # TOP: 6
angle = 90


ندفة الثلج المربعة

axiom = "F--F"
rules = {"F":"F-F+F+F-F"}
iterations = 4 # TOP: 6
angle = 90


كسورية ويشيكا

axiom = "F-F-F-F"
rules = {"F":"F-F+F+F-F"}
iterations = 4 # TOP: 6
angle = 90


ليفي كيرف

axiom = "F"
rules = {"F":"+F--F+"}
iterations = 10 # TOP: 16
angle = 45


سجادة سيربينسكي

axiom = "YF"
rules = {"X":"YF+XF+Y", "Y":"XF-YF-X"}
iterations = 1 # TOP: 10
angle = 60


شعرية سيربينسكي

axiom = "FXF--FF--FF"
rules = {"F":"FF", "X":"--FXF++FXF++FXF--"}
iterations = 7 # TOP: 8
angle = 60


ميدان

axiom = "F+F+F+F"
rules = {"F":"FF+F+F+F+FF"}
iterations = 3 # TOP: 5
angle = 90


البلاط

axiom = "F+F+F+F"
rules = {"F":"FF+F-F+F+FF"}
iterations = 3 # TOP: 4
angle = 90


خواتم

axiom = "F+F+F+F"
rules = {"F":"FF+F+F+F+F+F-F"}
iterations = 2 # TOP: 4
angle = 90


صليب 2

axiom = "F+F+F+F"
rules = {"F":"F+F-F+F+F"}
iterations = 3 # TOP: 6
angle = 90


الخماسي

axiom = "F++F++F++F++F"
rules = {"F":"F++F++F+++++F-F++F"}
iterations = 1 # TOP: 5
angle = 36


32 منحنى المقطع

axiom = "F+F+F+F"
rules = {"F":"-F+F-F-F+F+FF-F+F+FF+F-F-FF+FF-FF+F+F-FF-F-F+FF-F-F+F+F-F+"}
iterations = 3 # TOP: 3
angle = 90


منحنى Peano Gosper

axiom = "FX"
rules = {"X":"X+YF++YF-FX--FXFX-YF+", "Y":"-FX+YFYF++YF+FX--FX-Y"}
iterations = 4 # TOP: 6
angle = 60


منحنى سيربينسكي

axiom = "F+XF+F+XF"
rules = {"X":"XF-F+F-XF+F+XF-F+F-X"}
iterations = 4 # TOP: 8
angle = 90


أسئلة كريشنا

axiom = " -X--X"
rules = {"X":"XFX--XFX"}
iterations = 3 # TOP: 9
angle = 45


فراكتال مربعة الشكل

axiom = "YF"
rules = {"X": "XFX-YF-YF+FX+FX-YF-YFFX+YF+FXFXYF-FX+YF+FXFX+YF-FXYF-YF-FX+FX+YFYF-", 
        "Y": "+FXFX-YF-YF+FX+FXYF+FX-YFYF-FX-YF+FXYFYF-FX-YFFX+FX+YF-YF-FX+FX+YFY"}
iterations = 2 # TOP: 3
angle = 90


مور كيرف

axiom = "LFL-F-LFL"
rules = {"L":"+RF-LFL-FR+", "R":"-LF+RFR+FL-"}
iterations = 0 # TOP: 8
angle = 90


منحنى هيلبرت

axiom = "L"
rules = {"L":"+RF-LFL-FR+", "R":"-LF+RFR+FL-"}
iterations = 8 # TOP: 9
angle = 90


هيلبرت كيرف الثاني

axiom = "X"
rules = {"X":"XFYFX+F+YFXFY-F-XFYFX", "Y":"YFXFY-F-XFYFX+F+YFXFY"}
iterations = 4 # TOP: 6
angle = 90


منحنى Peano

axiom = "F"
rules = {"F":"F+F-F-F-F+F+F+F-F"}
iterations = 2 # TOP: 5
angle = 90


تعبر

axiom = "F+F+F+F"
rules = {"F":"F+FF++F+F"}
iterations = 3 # TOP: 6
angle = 90


مثلث

axiom = "F+F+F"
rules = {"F":"F-F+F"}
iterations = 2 # TOP: 9
angle = 120


منحنى التنين

axiom = "FX"
rules = {"X":"X+YF+", "Y":"-FX-Y"}
iterations = 8 # TOP: 16
angle = 90


منحنى Terdragon

axiom = "F"
rules = {"F":"F-F+F"}
iterations = 5 # TOP: 10
angle = 120


منحنى التنين المزدوج

axiom = "FX+FX"
rules = {"X":"X+YF+", "Y":"-FX-Y"}
iterations = 6 # TOP: 16
angle = 90


منحنى التنين الثلاثي

axiom = "FX+FX+FX"
rules = {"X":"X+YF+", "Y":"-FX-Y"}
iterations = 7 # TOP: 15
angle = 90


الرمز

تم الحصول على جميع الأمثلة المذكورة أعلاه باستخدام نفس الرمز ، وعند العمل عليها نشأت بعض الصعوبات (على سبيل المثال ، كيفية الحفاظ على الفراكتل في المركز قدر الإمكان) ، والعمل مع اللون ، والانقلاب ، والإزاحة ، وكذلك توفير تصدير سريع إلى شكل متجه. أريكم هنا فقط أبسط نسخة.
يعرض هذا الإصدار صور النمطي هندسي متكرر باللونين الأسود والأبيض وغير مجهز بوظيفة التصدير

import turtle

def create_l_system(iters, axiom, rules):
    start_string = axiom
    if iters == 0:
        return axiom
    end_string = ""
    for _ in range(iters):
        end_string = "".join(rules[i] if i in rules else i for i in start_string)
        start_string = end_string

    return end_string


def draw_l_system(t, instructions, angle, distance):
    for cmd in instructions:
        if cmd == 'F':
            t.forward(distance)
        elif cmd == '+':
            t.right(angle)
        elif cmd == '-':
            t.left(angle)


def main(iterations, axiom, rules, angle, length=8, size=2, y_offset=0,
        x_offset=0, offset_angle=0, width=450, height=450):

    inst = create_l_system(iterations, axiom, rules)

    t = turtle.Turtle()
    wn = turtle.Screen()
    wn.setup(width, height)

    t.up()
    t.backward(-x_offset)
    t.left(90)
    t.backward(-y_offset)
    t.left(offset_angle)
    t.down()
    t.speed(0)
    t.pensize(size)
    draw_l_system(t, inst, angle, length)
    t.hideturtle()

    wn.exitonclick()


شرح الكود

import turtle


تحتاج أولاً إلى استيراد وحدة السلاحف

def create_l_system(iters, axiom, rules):
    start_string = axiom
    if iters == 0:
        return axiom
    end_string = ""
    for _ in range(iters):
        end_string = "".join(rules[i] if i in rules else i for i in start_string)
        start_string = end_string

    return end_string

ثم تحتاج إلى إنشاء نظام L ، والذي سيكون عبارة عن مجموعة من التعليمات للسلحفاة. نحدد دالة create_l_systemتستقبل عدد التكرارات ، البديهية ، وقواعد البناء. يبدأ ببديهية ويستخدم متغيرًا مساعدًا end_string، إذا كان التكرار 0 ، فسوف يعيد البديهية ، حيث يمكن أيضًا تطبيق بعض الفركتلات مع عدم تكرارها. في هذه الحالة ، يُفترض أن القواعد لها شكل قواميس ، لذلك كل مفتاح فريد ، يمثل رمزًا ، وتشير القيمة إلى ما يجب استبداله وما الذي يجب استبداله. لذا ، فإننا نجمع بين جميع البدائل لكل حرف ونحصل في النهاية على سلسلة للتكرار التالي.

def draw_l_system(t, instructions, angle, distance):
    for cmd in instructions:
        if cmd == 'F':
            t.forward(distance)
        elif cmd == '+':
            t.right(angle)
        elif cmd == '-':
            t.left(angle)

ثم نحدد draw_l_systemأيهما يقبل السلحفاة ، ومجموعة من التعليمات (مخرجات النظام L) ، وزاوية التدوير لليسار أو اليمين ، وطول كل خط فردي. وتتكون من بنية بسيطة elifلكل فريق تم تحديده مسبقًا.

def main(iterations, axiom, rules, angle, length=8, size=2, y_offset=0,
        x_offset=0, offset_angle=0, width=450, height=450):

    inst = create_l_system(iterations, axiom, rules)

    t = turtle.Turtle()
    wn = turtle.Screen()
    wn.setup(width, height)

    t.up()
    t.backward(-x_offset)
    t.left(90)
    t.backward(-y_offset)
    t.left(offset_angle)
    t.down()
    t.speed(0)
    t.pensize(size)
    draw_l_system(t, inst, angle, length)
    t.hideturtle()

    wn.exitonclick()

وأخيرًا ، لنتحدث عن الوظيفة main، التي تأخذ جميع المعلمات اللازمة لتوليد أنظمة L ، وكذلك y_offset، x_offsetو offset_angle، widthو height. تصف الثلاثة الأولى إزاحة السلحفاة ، فمن الضروري فقط وضع الرسم البياني على القماش بالطريقة التي نريدها.

تقوم الوظيفة أولاً بإنشاء مجموعة من التعليمات وحفظها في inst ، ثم تهيئة السلحفاة والشاشة ووضع السلحفاة عند نقطة معينة ، ثم رسم رسم بياني وفقًا للتعليمات وينتظر النقر لإغلاقها.

إعتبارات خاصة

كما ذكرت أعلاه ، بقيت العديد من القيود هنا. أولاً ، لم نوفر للسلحفاة القدرة على الحركة دون التقديم. هذا يتطلب شخصية أخرى. لا يوجد أيضًا رمز للتراجع ، ولتذكر المواقف السابقة. لم تكن مطلوبة لجميع الفراكتلات التي تمت مناقشتها أعلاه ، ولكنها مطلوبة لبعض الآخرين (على سبيل المثال ، أشجار الفراكتل).

موارد إضافية

الإنترنت لديها العديد من الموارد على الكسيريات ، حيث يتم اعتبارها من وجهة نظر البرمجة ومن وجهة نظر الرياضيات. يبدو أن الاثنين التاليين مثيران للاهتمام بشكل خاص بالنسبة لي: 3Blue1Brown (math) و CodingTrain (code).

واستلهم المقالة قبل آخر من الرياضيات الدولي و المادة بولا بوركا.

All Articles