Я пытаюсь заполнить окружность точками, расположенными через равные интервалы.Вот код (он использует некоторую обработку, но это не важно для понимания):
class Circle (x: Float, y: Float, subdivisions: Int, radius: Float) extends WorldObject(x, y) {
def subs = subdivisions
def r = radius
val d = r + r
def makePoints() : List[Glyph] = {
val step = PConstants.TWO_PI / subdivisions
val points = List.make(subdivisions, new Glyph())
for(i <- 0 to subdivisions - 1) {
points(i) position (PApplet.cos(step * i) * r + xPos, PApplet.sin(step * i) * r + yPos)
}
points
}
val points: List[Glyph] = makePoints()
override def draw() {
applet fill 0
applet stroke 255
applet ellipse(x, y, d, d)
applet fill 255
points map(_.update())
}
}
class Glyph(x: Float, y: Float) extends WorldObject(x, y){
def this() = this(0, 0)
override def draw() {
applet ellipse(xPos, yPos, 10, 10)
}
}
object WorldObject {
}
abstract class WorldObject(var xPos: Float, var yPos: Float) {
def this() = this(0, 0)
def x = xPos
def y = yPos
def update() {
draw()
}
def draw()
def position(x: Float, y: Float) {
xPos = x
yPos = y
}
def move(dx: Float, dy: Float) {
xPos += dx
yPos += dy
}
}
Странный результат, который я получаю, заключается в том, что все точки расположены в одном месте.Я экспериментировал с проверками println
... проверки в методе makePoints()
показывают все нормально, но проверки в Circle.draw()
или даже сразу после makePoints()
показывают результат, как я вижу его на экране - всеточки расположены в одном месте, именно там, где генерируется последняя из них, а именно x=430.9017 y=204.89435
для круга, расположенного в x=400 y=300
и подразделенного на 5 точек.Так что как-то все они собираются в том месте, где сидит последний из них.
Почему такое поведение?Что я делаю не так?
UPD: Нам удалось найти причину, см. Ниже:
Отвечая на вопрос, неизвестный пользователь изменил кодиспользовать метод fill
вместо make
.Основное существенное различие между ними заключается в том, что make
предварительно вычисляет его аргументы, а fill
- нет.Таким образом make
заполняет список полностью идентичными элементами.Однако fill
повторяет вычисления для каждого дополнения.Вот исходные коды этих методов из источников Scala:
/** Create a list containing several copies of an element.
*
* @param n the length of the resulting list
* @param elem the element composing the resulting list
* @return a list composed of n elements all equal to elem
*/
@deprecated("use `fill' instead", "2.8.0")
def make[A](n: Int, elem: A): List[A] = {
val b = new ListBuffer[A]
var i = 0
while (i < n) {
b += elem
i += 1
}
b.toList
}
И метод fill
:
/** Produces a $coll containing the results of some element computation a number of times.
* @param n the number of elements contained in the $coll.
* @param elem the element computation
* @return A $coll that contains the results of `n` evaluations of `elem`.
*/
def fill[A](n: Int)(elem: => A): CC[A] = {
val b = newBuilder[A]
b.sizeHint(n)
var i = 0
while (i < n) {
b += elem
i += 1
}
b.result
}