
يمكن أن يخيفك الفن التوليدي (الفن التوليدي أو الإجرائي) إذا لم تكن قد واجهته من قبل. باختصار ، هذا هو مفهوم الفن الذي يخلق نفسه حرفيا ولا يتطلب معرفة البرمجة المتشددين لأول مرة. لذلك قررت أن أخفف الشريط قليلاً ، قادوا.
ما هو الفن التوليدي؟
هذا هو نتيجة نظام يتخذ قراراته الخاصة حول شيء ما بدلاً من شخص. يمكن أن يكون النظام بسيطًا مثل برنامج Python واحد إذا كان لديه قواعد ولحظة حظ.
مع البرمجة ، من السهل جدًا وضع القواعد والقيود. هناك عبارات شرطية لهذا. لكن إيجاد طرق لجعل هذه القواعد تخلق شيئًا مثيرًا للاهتمام قد لا يكون بهذه البساطة.
لعبة الحياة في كونوايلعبة الحياة في كونواي هي مجموعة معروفة من أربع قواعد بسيطة تحدد "ولادة" و "موت" كل خلية في النظام. تلعب كل قاعدة دورًا في تعزيز النظام من خلال كل جيل. على الرغم من أن القواعد بسيطة وسهلة الفهم ، تظهر أنماط معقدة بسرعة تؤدي في النهاية إلى نتائج مثيرة.
قد تكون القواعد مسؤولة عن إرساء الأساس لشيء مثير للاهتمام ، ولكن حتى شيء مثير مثل لعبة كونواي للحياة يمكن توقعه. القواعد الأربعة هي العوامل المحددة لكل جيل. لذلك ، للحصول على نتائج غير متوقعة ، تحتاج إلى إدخال التوزيع العشوائي في الحالة الأولية للخلايا. بدءًا بمصفوفة عشوائية ، سيكون كل تنفيذ فريدًا دون الحاجة إلى تغيير القواعد.
أفضل الأمثلة على الفن التوليدي هي تلك التي تجد مزيجًا من القدرة على التنبؤ والعشوائية لإنشاء شيء مثير للاهتمام لا يمكن تكراره إحصائيًا.
لماذا يجب أن تجرب هذا؟
لن يكون الفن التوليدي دائمًا ما تريد قضاء الوقت فيه. ولكن إذا قررت العمل عليه ، فيمكنك الاعتماد على المزايا التالية:
- الخبرة. الفن التوليدي هو فرصة أخرى لصقل المهارات الجديدة والقديمة. يمكن أن تكون بمثابة مدخل للعمل على مفاهيم مثل الخوارزميات وهياكل البيانات ، وحتى اللغات الجديدة.
- نتائج ملموسة. في البرمجة ، نادرًا ما نرى النتائج المادية لجهودنا. حسنًا ، أو على الأقل لا أراها. يوجد الآن في غرفة المعيشة الخاصة بي العديد من الملصقات التي تحتوي على مطبوعات للفن الإجرائي. وأنا أحب أن يتم ذلك عن طريق التعليمات البرمجية.
- تصميمات جذابة. كل شخص لديه خبرة في شرح مشروع شخصي لشخص ما ، ربما حتى خلال مقابلة. الفن التوليدي يتحدث عن نفسه. سيقدر معظم الناس النتائج ، حتى لو لم يتمكنوا من فهم الأساليب تمامًا.
من أين تبدأ؟
إن البدء في الفن التوليدي هو نفس العملية التي تبدأ بها مع أي مشروع آخر. أهم خطوة هي الخروج بفكرة أو العثور عليها لمزيد من التطوير. بمجرد أن يكون لديك هدف ، يمكنك البدء في العمل على تحقيقه.
معظم مشاريعي الإبداعية موجودة في Python. إنها لغة بسيطة إلى حد ما مع العديد من الحزم المفيدة التي تساعد في معالجة الصور. على سبيل المثال ،
وسادة .
لحسن الحظ ، لا يتعين عليك البحث طويلًا عن مكان البدء - أدناه سأشارك رمزي.
مولد العفريت
بدأ هذا المشروع عندما رأيت منشورًا يحتوي على منشئ نقش متحرك مكتوب بلغة جافا سكريبت. أنشأ البرنامج 5 × 5 بيكسل فني مع خيارات ألوان عشوائية ، وكانت نتائجه تشبه غزاة الفضاء متعدد الألوان.
كنت أرغب في ممارسة معالجة الصور في Python ، لذلك قررت إعادة إنشاء هذا المفهوم بنفسي. بالإضافة إلى ذلك ، اعتقدت أنه يمكنني توسيعه ، لأن المشروع الأصلي كان محدودًا جدًا في حجم العفاريت. وأريد أن أشير ليس فقط إلى حجم العفاريت ، ولكن أيضًا إلى عددهم وحتى حجم الصورة.
فيما يلي نتيجتان مختلفتان من برنامجي:
7x7-30–1900
43x43-6–1900هاتان الصورتان مختلفتان تمامًا عن بعضهما البعض ، لكنهما نتائج نفس النظام. ناهيك عن حقيقة أنه بسبب التعقيد والتوليد العشوائي للعفاريت ، هناك احتمال كبير أنه حتى مع نفس الحجج ، ستبقى هذه الصور إلى الأبد فريدة من نوعها. أحبه.
البيئة
قبل أن تتعرف على مولد العفريت ، يجب عليك إعداد أساس صغير لهذه المهمة.
إذا لم تكن قد عملت مع Python من قبل ،
فقم بتنزيل
Python 2.7.10 . في البداية ، واجهت مشاكل في إعداد البيئة ، إذا واجهتها أيضًا ، فابحث في
البيئات الافتراضية . وتأكد من تثبيت
الوسادة أيضًا.
بعد إعداد البيئة ، يمكنك نسخ الرمز الخاص بي إلى ملف بالملحق
.py وتشغيل الأمر التالي:
python spritething.py [SPRITE_DIMENSIONS] [NUMBER] [IMAGE_SIZE]
على سبيل المثال ، سيكون الأمر لإنشاء المصفوفة الأولى من العفاريت:
python spritething.py 7 30 1900
كود
import PIL, random, sys from PIL import Image, ImageDraw origDimension = 1500 r = lambda: random.randint(50,215) rc = lambda: (r(), r(), r()) listSym = [] def create_square(border, draw, randColor, element, size): if (element == int(size/2)): draw.rectangle(border, randColor) elif (len(listSym) == element+1): draw.rectangle(border,listSym.pop()) else: listSym.append(randColor) draw.rectangle(border, randColor) def create_invader(border, draw, size): x0, y0, x1, y1 = border squareSize = (x1-x0)/size randColors = [rc(), rc(), rc(), (0,0,0), (0,0,0), (0,0,0)] i = 1 for y in range(0, size): I *= -1 element = 0 for x in range(0, size): topLeftX = x*squareSize + x0 topLeftY = y*squareSize + y0 botRightX = topLeftX + squareSize botRightY = topLeftY + squareSize create_square((topLeftX, topLeftY, botRightX, botRightY), draw, random.choice(randColors), element, size) if (element == int(size/2) or element == 0): I *= -1; element += I def main(size, invaders, imgSize): origDimension = imgSize origImage = Image.new('RGB', (origDimension, origDimension)) draw = ImageDraw.Draw(origImage) invaderSize = origDimension/invaders padding = invaderSize/size for x in range(0, invaders): for y in range(0, invaders): topLeftX = x*invaderSize + padding/2 topLeftY = y*invaderSize + padding/2 botRightX = topLeftX + invaderSize - padding botRightY = topLeftY + invaderSize - padding create_invader((topLeftX, topLeftY, botRightX, botRightY), draw, size) origImage.save(«Examples/Example-«+str(size)+»x»+str(size)+»-«+str(invaders)+»-«+str(imgSize)+».jpg») if __name__ == «__main__»: main(int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3]))
لا يزال هذا الحل بعيدًا عن الكمال ، ولكنه يوضح أن إنشاء الفن التوليدي لا يتطلب الكثير من التعليمات البرمجية. سأشرح النقاط الرئيسية.
تبدأ الوظيفة الرئيسية بإنشاء الصورة الأصلية وتحديد حجم العفاريت. اثنان من الحلقات مسؤولان عن تحديد حدود كل نقش متحرك ، وقسمة حجم الصورة بشكل أساسي على عدد الرموز المتحركة المطلوبة. يتم استخدام هذه القيم لتحديد الإحداثيات لكل منها.
ألق نظرة على الصورة أدناه. تخيل أن كل من المربعات الأربعة عبارة عن نقش متحرك بحجم 1. تشير الحدود التي يتم تمريرها إلى الوظيفة التالية إلى إحداثيات الزوايا العلوية اليسرى والسفلى اليمنى. وبالتالي فإن الصف في الجزء العلوي من العفريت الأيسر سيكون (0،0،1،1) ، وسيكون الصف في الجزء العلوي الأيمن (1،0،2،1). سيتم استخدامها كأبعاد وإحداثيات أساسية لمربعات كل نقش متحرك.
مثال لتحديد حدود العفريتتحدد دالة
create_invader الحدود لكل مربع داخل العفريت. يتم تطبيق نفس عملية تحديد الحدود هنا ويتم عرضها أدناه ، بدلاً من الصورة الكاملة فقط نستخدم حدًا محددًا مسبقًا للعمل بالداخل. سيتم استخدام هذه الإحداثيات النهائية لكل مربع في الوظيفة التالية لرسم نقش متحرك.
3 × 3 مثال لتحليل العفريتلتحديد اللون ، يتم استخدام مجموعة بسيطة من ثلاث مجموعات عشوائية RGB وثلاث أخرى سوداء لمحاكاة فرصة 50٪ في الرسم. وظائف لامدا في أعلى الكود هي المسؤولة عن توليد قيم RGB.
الحيلة الحقيقية لهذه الوظيفة هي خلق التماثل. يرتبط كل مربع بقيمة عنصر. يوضح الشكل أدناه كيفية زيادة قيم العناصر عند وصولها إلى المركز ، ثم تنخفض. يتم عرض المربعات ذات قيم العناصر المطابقة بنفس اللون.
قيم العنصر والألوان المتماثلة لسلسلة في نقش متحرك 7 × 7نظرًا لأن
create_square يحصل على معلماته من
create_invader ، فإنه يستخدم قائمة الانتظار وقيم العناصر السابقة لضمان التناظر. عندما تظهر القيم لأول مرة ، يتم وضع ألوانها في قائمة الانتظار ، وتزيل مربعات المرآة الألوان.
إكمال عملية الإنشاءأفهم مدى صعوبة قراءة حل شخص آخر للمشكلة والرمز المعوج ، ولكن آمل أن تجد هذا التطبيق. سيكون الأمر رائعًا إذا تخليت تمامًا عن الكود الخاص بي ووجدت حلًا مختلفًا تمامًا.
الخلاصة
يستغرق الفن التوليدي بعض الوقت للوصول إلى إمكاناته الكاملة. بشكل عام ، قد تكون هناك مشاريع مفيدة أكثر من الفن التوليدي ، والتي لا تستحق الوقت دائمًا. ولكن هناك الكثير من المرح ولا تعرف أبدًا أين يمكن أن تكون في متناول اليد.