D言語からObjective-CとCocoaAPIを使いたい
バーンズリーのシダ (Barnsley fern)
点の形状をovalからrectに変えることで半分ほどの時間になりました。

サンプルコード
Powered by Prism
fern/dub.json
{
"authors": ["hidhok"],
"description": "A D/Objective-C Cocoa application.",
"name": "fern",
"dflags": ["-L-framework", "-LCocoa"],
"sourceFiles": ["../cocoa/window",
"../cocoa/control",
"../cocoa/menus"]
}
fern/source/app.d
/**
* fern/source/app.d Version 0.0.1
*/
module fern.main;
import core.attribute : optional, selector;
import std.stdio;
import cocoa.window;
import cocoa.control;
import cocoa.menus;
import fern.draw;
string appName;
string versionNo = "0.0.1";
string helpMessage = "CocoaAPIを使用して、\n"
~ "フラクタル図形によるシダを\nD言語で表示してみました。";
DrawView drView;
ViewController vCtrlr;
void main() {
auto delegate_ = AppDelegate.alloc.init;
NSApp.delegate_ = cast(void*) delegate_;
NSApp.activationPolicy = NSAppActivationPolicy.regular;
NSApp.run;
}
extern (Objective-C)
class AppDelegate : NSObject {
override static AppDelegate alloc() @selector("alloc");
override typeof(this) init() @selector("init");
bool applicationShouldTerminateAfterLastWindowClosed(
NSNotification notification) @selector(
"applicationShouldTerminateAfterLastWindowClosed:") {
return true;
}
void applicationDidFinishLaunching(NSNotification notification)
@selector("applicationDidFinishLaunching:") {
buildWindow;
}
void aboutPanel() @selector("aboutPanel") {
NSMutableDictionary options = NSMutableDictionary.dictionary;
// NSImage img = NSImage.name("AppIcon.icns".toNs);
// options.setObjKey(img, "ApplicationIcon".toNs);
options.setObjKey(versionNo.toNs, "Version".toNs);
options.setObjKey("horkew.la.coocan.jp".toNs, "Copyright".toNs);
options.setObjKey(versionNo.toNs, "ApplicationVersion".toNs);
NSApplication.shared_.aboutPanelOptions(options.copy);
}
void showHelp() @selector("showHelp") {
dialog("Help", helpMessage);
}
}
void buildWindow() {
NSWindow win;
appName = NSProcessInfo.processInfo.processName.toDs;
appName ~= "(シダ)";
NSApp.menu = miniMenu(appName);
NSRect w_rect = nRect(150, 450, 300, 400);
immutable w_style = NSWindowStyleMask.titled |
NSWindowStyleMask.closable |
NSWindowStyleMask.resizable |
NSWindowStyleMask.miniaturizable;
win = NSWindow.alloc.init(w_rect, w_style, backing.buffered, false);
win.title = (appName ~ " (D言語)").toNs;
win.bgColor = NSColor.colorRGB(0.2, 0.2, 0.2, 1.0);
vCtrlr = ViewController.alloc.init;
vCtrlr.view.subview = win.contentView;
drView = DrawView.alloc.init;
win.contentView = drView;
win.makeKeyAndOrderFront = null ;
NSApp.activateIgnoringOtherApps = true;
}
extern (Objective-C)
class ViewController : NSViewController {
override static ViewController alloc() @selector("alloc");
override ViewController init() @selector("init");
override void loadView() @selector("loadView") {
writeln("loadView " ~ appName ~ "... running Now");
}
override void viewDidLoad() @selector("viewDidLoad") {
printf("viewDidLoad\n");
}
}
fern/source/draw.d
/**
* fern/source/draw.d
*/
module fern.draw;
import core.attribute : optional, selector;
import std.stdio;
import std.conv;
import std.math;
import std.random : uniform;
import std.datetime.stopwatch;
import cocoa.window;
import cocoa.control;
double w, h;
StopWatch sw;
extern (Objective-C)
class DrawView : NSView {
override static DrawView alloc() @selector("alloc");
override DrawView init() @selector("init");
override DrawView init(NSRect) @selector("initWithFrame:");
override void release() @selector("release");
override void drawRect(NSRect) @selector("drawRect:") {
NSColor.green.fill;
w = this.frame.size.width;
h = this.frame.size.height;
int m = 35;
double mx = m * w / 300;
double my = m * h / 400;
float r, x = 0.0, y = 0.0, xn, yn;
assert(!sw.running);
sw.start();
assert(sw.running);
foreach (i; 0..100_000) {
plot(x * mx, y * my);
r = 100.0 * uniform(0.0f, 1.0f);
xn = x;
yn = y;
if (r < 1) {
x = 0; // 茎
y = 0.16 * yn;
} else if (r < 86) {
x = 0.85 * xn + 0.04 * yn;
y = -0.04 * xn + 0.85 * yn + 1.6;
} else if (r < 93) {
x = 0.20 * xn - 0.26 * yn; // 左葉
y = 0.23 * xn + 0.22 * yn + 1.6;
} else {
x = -0.15 * xn + 0.28 * yn; // 右葉
y = 0.26 * xn + 0.24 * yn + 0.44;
}
}
auto t1 = sw.peek();
sw.stop();
assert(!sw.running);
writeln(t1);
sw.reset();
}
}
void plot(float x,float y) {
x += w / 2; // offset
y += 20 * h / 400; // offset
// NSBezierPath dotPath = NSBezierPath.oval(nRect(x, y, 1, 1));
NSBezierPath dotPath = NSBezierPath.rect(nRect(x, y, 1, 1));
dotPath.fill;
}
cocoa/window.d
cocoa/control.d
cocoa/menus.d
- Log
- 2024-07-09 upload