الرسم باستخدام HTML Canvas في تطبيقات الذكاء الاصطناعي
تُعد HTML Canvas من الأدوات المهمة في JavaScript
عندما نريد رسم البيانات بصريًا داخل المتصفح. وتوضح الصفحة الأصلية
أن Canvas مناسبة جدًا لرسم المخططات المبعثرة،
والرسوم الخطية، وكذلك الجمع بين النقاط والخطوط
في نفس الرسم.
وهذا يجعلها أداة مفيدة في التطبيقات التعليمية
وفي أمثلة تعلم الآلة والذكاء الاصطناعي،
لأنها تسمح لنا بعرض البيانات والنتائج بشكل بصري مباشر.
Canvas وScatter Plots
تبدأ الصفحة بالتأكيد على أن Canvas مناسبة جدًا
لرسم Scatter Plots.
وفي المثال المعروض يتم استخدام مصفوفتين:
- مصفوفة لقيم x
- مصفوفة لقيم y
ثم يتم المرور على هذه القيم نقطة نقطة،
وتحويلها إلى إحداثيات مناسبة داخل مساحة الـ Canvas،
ثم رسم كل نقطة باستخدام ellipse.
const xArray = [50,60,70,80,90,100,110,120,130,140,150];
const yArray = [7,8,8,9,9,9,10,11,14,14,15];
// Plot Scatter
ctx.fillStyle = \"red\";
for (let i = 0; i < xArray.length-1; i++) {
let x = xArray[i] * 400 / 150;
let y = yArray[i] * 400 / 15;
ctx.beginPath();
ctx.ellipse(x, y, 2, 3, 0, 0, Math.PI * 2);
ctx.fill();
}الفكرة هنا أن القيم الأصلية لا تُرسم كما هي مباشرة،
بل يتم تغيير مقياسها لتناسب حجم مساحة الرسم.
وبذلك يمكن تحويل بيانات واقعية مثل الأسعار أو المساحات
إلى نقاط مرئية داخل Canvas.
Canvas وLine Graphs
بعد ذلك تنتقل الصفحة إلى مثال الرسم الخطي،
وتوضح أن Canvas مناسبة أيضًا لرسم Line Graphs.
وفي المثال يتم تعريف:
- أقصى قيمة للرسم
- الميل slope
- التقاطع intercept
ثم يتم رسم الخط باستخدام:
const xMax = canvas.height = canvas.width;
const slope = 1.2;
const intercept = 70;
// Plot Line
ctx.beginPath();
ctx.moveTo(0, intercept);
ctx.lineTo(xMax, xMax * slope + intercept);
ctx.stroke();هذا المثال يوضح أن Canvas لا تُستخدم فقط للنقاط،
بل يمكن استخدامها أيضًا لتمثيل العلاقات الخطية
بصورة بصرية بسيطة.
الجمع بين النقاط والخطوط
ثم تعرض الصفحة مثالًا ثالثًا يجمع بين
الرسم المبعثر والرسم الخطي
في نفس المساحة.
في هذا المثال يتم أولًا رسم النقاط،
ثم بعد ذلك يُرسم الخط فوقها،
وبهذا يمكن مقارنة البيانات الأصلية
بالخط الذي يمثل العلاقة بينها.
let xMax = canvas.height;
let yMax = canvas.width;
let slope = 1.2;
let intercept = 70;
const xArray = [50,60,70,80,90,100,110,120,130,140,150];
const yArray = [7,8,8,9,9,9,10,11,14,14,15];
// Plot Scatter
ctx.fillStyle = \"red\";
for (let i = 0; i < xArray.length-1; i++) {
let x = xArray[i] * xMax / 150;
let y = yArray[i] * yMax / 15;
ctx.beginPath();
ctx.ellipse(x, y, 2, 3, 0, 0, Math.PI * 2);
ctx.fill();
}
// Plot Line
ctx.beginPath();
ctx.moveTo(0, intercept);
ctx.lineTo(xMax, xMax * slope + intercept);
ctx.stroke();هذا النوع من الرسم مفيد جدًا في أمثلة الذكاء الاصطناعي،
لأنه يسمح بعرض البيانات الأصلية مع النموذج المتوقع
في نفس الشكل البياني.
لماذا Plotter Object فكرة مفيدة؟
بعد الأمثلة المباشرة، تشرح الصفحة أن إنشاء
Plotter Object فكرة مفيدة عند دراسة الذكاء الاصطناعي،
لأنها تجعل التعلم:
- أكثر متعة
- أكثر بصرية
- أكثر قابلية للفهم
ولهذا تبدأ الصفحة ببناء كائن مخصص للرسم
يسهّل إعادة استخدام الكود بدلًا من كتابة كل شيء
من الصفر في كل مرة.
إنشاء كائن XYPlotter
تعرض الصفحة بداية كائن اسمه XYPlotter.
هذا الكائن يبدأ بالحصول على:
- عنصر الـ Canvas من الصفحة
- سياق الرسم 2d context
- الحدود الدنيا والعليا للرسم
function XYPlotter(id) {
this.canvas = document.getElementById(id);
this.ctx = this.canvas.getContext(\"2d\");
this.xMin = 0;
this.yMin = 0;
this.xMax = this.canvas.width;
this.yMax = this.canvas.height;
}بهذا الشكل يصبح لدينا كائن يمكنه معرفة
مساحة الرسم وحدودها والبدء في تنفيذ وظائف الرسم المختلفة.
إضافة دالة لرسم خط
بعد إنشاء الكائن، تضيف الصفحة إليه دالة باسم
plotLine تستخدم لرسم خط
بين نقطتين.
this.plotLine = function(x0, y0, x, y, color) {
this.ctx.moveTo(x0, y0);
this.ctx.lineTo(x, y);
this.ctx.strokeStyle = color;
this.ctx.stroke();
}هذه الدالة تجعل رسم الخطوط أسهل،
لأنها تجمع منطق الرسم داخل وظيفة واحدة
يمكن استدعاؤها كلما احتجنا إلى رسم خط جديد.
إضافة دالة لتحويل الإحداثيات
من المشاكل المعروفة في Canvas أن محور y
يبدأ من الأعلى إلى الأسفل،
بينما في الرسوم الرياضية المعتادة
نفضل أن يكون الاتجاه من الأسفل إلى الأعلى.
ولهذا تضيف الصفحة دالة باسم
transformXY
لقلب نظام الإحداثيات:
this.transformXY = function() {
this.ctx.transform(1, 0, 0, -1, 0, this.canvas.height)
}هذه الخطوة تجعل الرسم أقرب إلى الطريقة
التي نفكر بها في المحاور الرياضية المعتادة.
إضافة دالة لرسم النقاط
بعد ذلك تضيف الصفحة دالة أخرى باسم
plotPoints،
ومهمتها رسم مجموعة من النقاط دفعة واحدة.
this.plotPoints = function(n, xArr, yArr, color, radius = 3) {
for (let i = 0; i < n; i++) {
this.ctx.fillStyle = color;
this.ctx.beginPath();
this.ctx.ellipse(xArr[i], yArr[i], radius, radius, 0, 0, Math.PI * 2);
this.ctx.fill();
}
}هذه الدالة مفيدة جدًا عندما نريد رسم بيانات كثيرة،
مثل النقاط الناتجة من مجموعة تدريب أو من توزيع عشوائي.
رسم نقاط عشوائية
بعد تجهيز الكائن والدوال الأساسية،
تعرض الصفحة مثالًا لإنشاء 500 نقطة عشوائية
ثم رسمها باستخدام الكائن الجديد.
// Create a Plotter
let myPlotter = new XYPlotter(\"myCanvas\");
// Create random XY Points
numPoints = 500;
const xPoints = Array(numPoints).fill(0).map(function(){return Math.random() * myPlotter.xMax});
const yPoints = Array(numPoints).fill(0).map(function(){return Math.random() * myPlotter.yMax});
// Plot the Points
myPlotter.plotPoints(numPoints, xPoints, yPoints, \"blue\");هذا المثال يوضح فائدة الكائن بوضوح:
فبدلًا من تكرار أوامر الرسم اليدوية في كل مرة،
يمكننا ببساطة إنشاء الكائن ثم استدعاء دواله.
وضع الكود في مكتبة
في الجزء الأخير، تجمع الصفحة كود
XYPlotter
داخل ملف مستقل، بحيث يمكن إعادة استخدامه
في أي صفحة لاحقًا.
function XYPlotter(id) {
this.canvas = document.getElementById(id);
this.ctx = this.canvas.getContext(\"2d\");
this.xMin = 0;
this.yMin = 0;
this.xMax = this.canvas.width;
this.yMax = this.canvas.height;
// Plot Line Function
this.plotLine = function(x0, y0, x, y, color) {
this.ctx.moveTo(x0, y0);
this.ctx.lineTo(x, y);
this.ctx.strokeStyle = color;
this.ctx.stroke();
}
// Transform XY Function
this.transformXY = function() {
this.ctx.transform(1, 0, 0, -1, 0, this.canvas.height)
}
// Plot Points Function
this.plotPoints = function(n, xArr, yArr, color, radius = 3) {
for (let i = 0; i < n; i++) {
this.ctx.fillStyle = color;
this.ctx.beginPath();
this.ctx.ellipse(xArr[i], yArr[i], radius, radius, 0, 0, Math.PI * 2);
this.ctx.fill();
}
}
}ثم توضّح الصفحة أنه يمكن حفظ هذا الكود
داخل ملف مثل:
myplotlib.js
ثم استخدامه داخل أي صفحة HTML.
استخدام المكتبة داخل صفحة HTML
تختم الصفحة بهذه الخطوة البسيطة:
<script src=\"myplotlib.js\"></script>وبهذه الطريقة يصبح كائن الرسم متاحًا
داخل أي صفحة نحتاج فيها إلى رسم نقاط أو خطوط
باستخدام Canvas.
الخلاصة
يوضح هذا الدرس أن HTML Canvas أداة مناسبة جدًا
لرسم Scatter Plots وLine Graphs
والجمع بينهما، وهو ما يجعله مفيدًا في أمثلة الذكاء الاصطناعي
وتعلم الآلة. كما يشرح كيف يمكن الانتقال من الرسم اليدوي المباشر
إلى بناء كائن منظم باسم XYPlotter يحتوي على
دوال جاهزة لرسم الخطوط، وتحويل المحاور، ورسم النقاط،
ثم حفظ هذا الكود داخل مكتبة مستقلة يمكن إعادة استخدامها
في صفحات HTML أخرى.
