问题描述
我开发了自己认为是一个精巧的处理程序的小程序。它设置一些rng,然后绘制每个rng每个输出的计数图形。这是处理代码。我认为这方面没有任何问题,因为它在处理中可以正常运行:
int [] randomCounts;
int [] gaussianCounts;
int [] monteCarloCounts;
int [] invMonteCarloCounts;
void setup(){
size(1000,700);
randomCounts = new int[500];
gaussianCounts = new int[500];
monteCarloCounts = new int[500];
invMonteCarloCounts = new int[500];
}
float invMonteCarlo(){
while (true){
float r1 = random(1);
float r2 = random(1);
if (r2>r1){
return r1;
}
}
}
float monteCarlo(){
while (true){
float r1 = random(1);
float r2 = random(1);
if (r2<r1){
return r1;
}
}
}
void draw(){
background(255);
int randindex = int(random(randomCounts.length));
int gaussIndex = int(randomGaussian()*20+250);
int monteIndex = int(monteCarlo()*monteCarloCounts.length);
int invMonteIndex = int(invMonteCarlo()*invMonteCarloCounts.length);
randomCounts[randindex]++;
gaussianCounts[gaussIndex]++;
monteCarloCounts[monteIndex]++;
invMonteCarloCounts[invMonteIndex]++;
nostroke();
int w = width/randomCounts.length;
fill(0,255,150);
for (int x = 0; x < gaussianCounts.length;x++){
rect(x*w,height-gaussianCounts[x],w-1,gaussianCounts[x]);
}
fill(0,150);
for (int x = 0;x < monteCarloCounts.length;x++){
rect(x*w,height-monteCarloCounts[x],monteCarloCounts[x]);
}
fill(255,150);
for (int x = 0;x < invMonteCarloCounts.length;x++){
rect(x*w,height-invMonteCarloCounts[x],invMonteCarloCounts[x]);
}
fill(255,150);
for (int x = 0; x < randomCounts.length; x++){
rect(x*w,height-randomCounts[x],randomCounts[x]);
}
}
void mousepressed(){
for (int x = 0; x < randomCounts.length; x++){
randomCounts[x] = 0;
gaussianCounts[x] = 0;
monteCarloCounts[x] = 0;
invMonteCarloCounts[x] = 0;
}
}
再次,此代码可以正常工作。我试图快速地做基本上相同的事情(有点疯狂),并且XCode指出没有错误。但是,当我在“系统偏好设置”中安装“保护程序”时,即使是其他屏幕保护程序,预览也只是黑色并且无法正常运行,并且实际上无法运行该屏幕保护程序。它似乎卡在了某处,从而使其无法在引擎中实际运行。 这是我的快速代码:
import Foundation
import ScreenSaver
import GameplayKit
class RandomGraphView: ScreenSaverView {
private var randomCounts: [Int] = [500]
private var gaussianCounts: [Int] = [500]
private var shuffledCounts: [Int] = [500]
private var monteCarloCounts: [Int] = [500]
private var invMonteCarloCounts: [Int] = [500]
private func MonteCarlo() -> Int{
while true {
let r1 = Int.random(in: 1...360)
let r2 = Int.random(in: 1...360)
if r2<r1 {
return r1
}
}
}
private func invMonteCarlo() -> Int{
while true {
let r1 = Int.random(in: 1...360)
let r2 = Int.random(in: 1...360)
if r2>r1 {
return r1
}
}
}
private func gaussian() -> Int{
let gaussianD6 = GKGaussiandistribution(lowestValue: 1,highestValue: 360)
return gaussianD6.nextInt()
}
private func shuffled() -> Int{
let shuffledD6 = GKShuffleddistribution(lowestValue: 1,highestValue: 360)
return shuffledD6.nextInt()
}
private func pullNumbers(){
let randindex = Int.random(in: 1...360)
let gaussIndex = gaussian()
let shuffIndex = shuffled()
let monteCarloIndex = MonteCarlo()
let invMonteCarloIndex = invMonteCarlo()
randomCounts[randindex]+=1
gaussianCounts[gaussIndex]+=1
shuffledCounts[shuffIndex]+=1
monteCarloCounts[monteCarloIndex]+=1
invMonteCarloCounts[invMonteCarloIndex]+=1
}
private func drawRandomBars(){
for n in 1...360{
let countBarRect = NSRect(x:(n-1)*4,y: 900,width:4,height: randomCounts[n])
let countBar = NSBezierPath(rect: countBarRect)
NSColor.red.setFill()
countBar.fill()
}
}
private func drawGaussianBars(){
for n in 1...360{
let countBarRect = NSRect(x: (n-1)*4,width: 4,height: gaussianCounts[n])
let countBar = NSBezierPath(rect: countBarRect)
NSColor.green.setFill()
countBar.fill()
}
}
private func drawShuffledBars(){
for n in 1...360{
let countBarRect = NSRect(x: (n-1)*4,height: shuffledCounts[n])
let countBar = NSBezierPath(rect: countBarRect)
NSColor.systembrown.setFill()
countBar.fill()
}
}
private func drawMonteCarloBars(){
for n in 1...360{
let countBarRect = NSRect(x: (n-1)*4,height: monteCarloCounts[n])
let countBar = NSBezierPath(rect: countBarRect)
NSColor.magenta.setFill()
countBar.fill()
}
}
private func drawInverseMonteCarloBars(){
for n in 1...360{
let countBarRect = NSRect(x: (n-1)*4,height: invMonteCarloCounts[n])
let countBar = NSBezierPath(rect: countBarRect)
NSColor.systemIndigo.setFill()
countBar.fill()
}
}
private func drawBackground(_ color:NSColor){
let background = NSBezierPath(rect: bounds)
color.setFill()
background.fill()
}
override init?(frame: NSRect,isPreview: Bool){
super.init(frame: frame,isPreview: isPreview)
}
@available(*,unavailable)
required init?(coder decoder: NSCoder){
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: NSRect){
drawBackground(.white)
pullNumbers()
drawRandomBars()
drawGaussianBars()
drawShuffledBars()
drawMonteCarloBars()
drawInverseMonteCarloBars()
}
override func animateOneFrame(){
super.animateOneFrame()
}
}
很抱歉,冗长的代码,我真的不知道我在做什么错。我从this tutorial复制了大部分脚本,效果很好。
解决方法
您必须在animateOneFrame中设置needsDisplay,如下所示:
override func animateOneFrame(){
needsDisplay = true
}
,
此行
private var randomCounts: [Int] = [500]
不等于
randomCounts = new int[500];
前者创建一个内部带有单个数字500的数组,而后者创建一个包含500个整数的数组(我不是Processing / Java专家,但我假设它们被初始化为0)。因此,当randIndex
,gaussIndex
等大于0时,您的程序将崩溃,因为索引将超出范围。
相反,您可能想使用init(repeating:count:):private var randomCounts: [Int] = Array(repeating: 0,count: 500)
。
一般来说,为了避免这种问题,您可以通过不在各处编写1...360
而不是使用randomCounts.count
来引用数组的长度来改进代码。同样,使用for n in 1...360
之类的字词代替for (n,height) in monteCarloCounts.enumerated()
。