寒假回家时,我将尝试使用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实例。如果以后需要它们,可以存储PVectorangle值,并且可以使用允许用户修改的设置器-您只需要相应地更新distance值即可。

07-26 06:06