WEVLにはユーザープログラムの出力を解釈して、様々な表現を行うための機能が備わっています。これをWEVLでは「インタプリタ」機能と呼びます。

インタプリタはユーザープログラムの出力のみに依存して動作しますので、ユーザープログラムの記述言語には依存しません。そのため、WEVLが対応する様々な言語において、同等の表現を行うことが可能です。

C言語による例(区分求積法図解)

区分求積法図解.png

#include <stdio.h>

double f(double x) {
    return x * x * x + x * x - x + 2;
}

struct Point {
    double x;
    double y;
};

void line(char* color, int n, struct Point* points) {
    const double TRANSLATE_X = 0;
    const double TRANSLATE_Y = -200;
    const double SCALE = 100;
    printf("line|%s", color);
    for (int i = 0; i < n; ++i) {
        const double x = SCALE * points[i].x + TRANSLATE_X;
        const double y = SCALE * points[i].y + TRANSLATE_Y;
        printf("|%.2f,%.2f", x, y);
    }
    printf("\\n");
}

void fill(char* color, int n, struct Point* points) {
    const double TRANSLATE_X = 0;
    const double TRANSLATE_Y = -200;
    const double SCALE = 100;
    printf("fill|%s", color);
    for (int i = 0; i < n; ++i) {
        const double x = SCALE * points[i].x + TRANSLATE_X;
        const double y = SCALE * points[i].y + TRANSLATE_Y;
        printf("|%.2f,%.2f", x, y);
    }
    printf("\\n");
}

void curve(void (*op)(char*, int, struct Point*), char* color, double x_min, double x_max, double (*ptr_f)(double), int n) {
    struct Point points[n];
    for (int i = 0; i < n; ++i) {
        const double x = x_min + i * (x_max - x_min) / n;
        const double y = (*ptr_f)(x);
        points[i].x = x;
        points[i].y = y;
    }
    (*op)(color, n, points);    
}

void segment(void (*op)(char*, int, struct Point*), char* color, double x1, double y1, double x2, double y2) {
    struct Point points[2] = { { x1, y1}, { x2, y2 } };
    (*op)(color, 2, points);
}

void box(void (*op)(char*, int, struct Point*), char* color, double x, double y, double w, double h) {
    struct Point points[5] = {
        { x, y },
        { x + w, y },
        { x + w, y + h },
        { x, y + h },
        { x, y },
    };
    (*op)(color, 5, points);
}

int main(void) {
    // 積分区間
    const double x_low = -2;
    const double x_high = 1;
    const int ndiv = 30;  // ndiv個の長方形で近似
    
    struct Point points[ndiv + 1];
    for (int i = 0; i <= ndiv; ++i) {
        const double x = x_low + i * (x_high - x_low) / ndiv;
        const double y = f(x);
        points[i].x = x;
        points[i].y = y;
    }
    // Draw axes
    segment(line, "red", -10, 0, 10, 0);
    segment(line, "green", 0, -10, 0, 10);
    // Draw lower boxes
    for (int i = 0; i < ndiv; ++i) {
        box(fill, "rgb(from pink r g b / 50%)", points[i].x, 0, (x_high - x_low) / ndiv, points[i].y);
        box(line, "rgb(from pink r g b / 50%)", points[i].x, 0, (x_high - x_low) / ndiv, points[i].y);
    }
    // Draw upper boxes
    for (int i = 0; i < ndiv; ++i) {
        box(fill, "rgb(from yellowgreen r g b / 50%)", points[i].x, 0, (x_high - x_low) / ndiv, points[i + 1].y);
        box(line, "rgb(from yellowgreen r g b / 50%)", points[i].x, 0, (x_high - x_low) / ndiv, points[i + 1].y);
    }
    // Draw f
    curve(line, "blue", -10, +10, f, 1000);
    return 0;
}