寒假回家时,我将尝试使用Processing编程语言(具有Java风格)制作一些很棒的东西。对于我的第一个项目,我想定义一个自定义Line类,以使在线数学更容易。在python中,它将是这样的:
import numpy as np
class Line():
def __init__(self, x1, y1, x2, y2):
self.x1, self.x2 = x1, x2
self.y1, self.y2 = y1, y2
@property
def p1(self):
return np.array([self.x1, self.y1])
@property
def p2(self):
return np.array([self.x2, self.y2])
这样,如果x1,...,y2更改,则相应的点矢量也将更改。显然,此示例效率不高,但要点仍然存在。在javascript中,我知道
Object.defineProperty(obj, prop, descriptor)
,但不清楚如何在加工中做到这一点
在这里发挥作用。定义类时的等效操作是什么?
编辑:澄清为什么
@property
特别有用:假设我希望用两种方式表示线,这两种方式都将由Line对象存储:
一是香草版本:两个点p1和p2,每个点都包含x,y坐标。
两个具有两个点u和v的参数化版本,使得p1 = u和p2 = u + v,线段上的任何点都由u + t * v给出,其中t是介于0和1之间的标量。
如果p2改变,那将改变v,反之亦然。更改p1会同时更改u和v。就参数化版本而言,某些数学更容易实现,而对于原始版本而言,某些数学更容易实现,因此我希望对任何属性所做的任何更改均能正确进行更新其他属性,以使p1,p2和u,v始终代表相同的行。
在python中,我可以修改属性的setter和getter方法以适当地解决所有这些问题,但是我似乎无法在Processing中确定执行此操作的方法。
最佳答案
如果您仅使用常规的Processing对象和语法,则几乎可以自动获得此信息。
例如,您可能使用两个PVector
实例来定义您的端点。
class Line{
PVector p1;
PVector p2;
public Line(float x1, float y1, float x2, float y2){
p1 = new PVector(x1, y1);
p2 = new PVector(x2, y2);
}
}
然后,如果您想更改这些端点之一,则可以直接访问
PVector
实例:Line myLine = new Line(0, 10, 25, 100);
println(myLine.p1.x + ", " myLine.p1.y);
myLine.p1.x = 750;
println(myLine.p1.x + ", " myLine.p1.y);
您还可以获得PVector class中已经定义的所有数学知识。
您可以通过将变量设置为最终变量,或者仅允许
PVector
类的用户通过设置器来更改端点,然后再访问Line
实例,从而更好地“保护”变量。编辑:我将在这里尝试回答您的其他问题。
有必要公开吗?
这完全取决于您如何使用此类,您希望其他人如何访问它,等等。您可以在the Processing reference中了解此内容,或者仅在Google中搜索“ java访问修饰符”之类的内容。或者,您可以尝试将其取出来看看会发生什么。
如果我同时希望线的原始定义(x1,y1,x2,y2)和参数化版本(u1,u2,v1,v2,s.t.x1 = u1和x2 = u1 + v1等)怎么办?在这种情况下,而且重要的是,如果x2已更新,则v1也应更新。
我不确定您在这里问什么。在编写课程时,您可以决定如何表示自己的州,以及如何让人们与该州互动。
例如,我上面的示例使用两个
PVector
实例表示该行,它使人们可以直接与他们互动以修改该行。但是我可以添加一个函数,使他们可以将一条线定义为一个点,一个角度和一个距离。我只需要确保计算出第二点即可存储状态。像这样:class Line{
PVector p1;
PVector p2;
public Line(float x1, float y1, float x2, float y2){
p1 = new PVector(x1, y1);
p2 = new PVector(x2, y2);
}
public Line(PVector origin, float angle, float distance){
p1 = origin;
p2 = new PVector(origin.x + cos(angle)*distance, origin.y + sin(angle)*distance);
}
}
请注意,第二个构造函数允许用户以完全不同的方式指定行,但是我仍将状态存储为两个
PVector
实例。如果以后需要它们,可以存储PVector
和angle
值,并且可以使用允许用户修改的设置器-您只需要相应地更新distance
值即可。