Example #1
0
class Viewport(Window):
    def __init__(self, x_min, y_min, x_max, y_max):
        super().__init__(x_min, y_min, x_max, y_max)
        self.t = Transform()

    def setWindow(self, window):
        self.window = window

    def transform(self, x, y):
        xw_min, yw_min = self.window.getMin()["x"], self.window.getMin()["y"]
        xw_max, yw_max = self.window.getMax()["x"], self.window.getMax()["y"]

        xvp_min, yvp_min = self.x_min, self.y_min
        xvp_max, yvp_max = self.x_max, self.y_max

        denormalized_point = self.t.denormalize(x, y)

        xvp = ((denormalized_point["x"] - xw_min) /
               (xw_max - xw_min)) * (xvp_max - xvp_min)
        yvp = (1 - (denormalized_point["y"] - yw_min) /
               (yw_max - yw_min)) * (yvp_max - yvp_min)
        #print(xvp, yvp)
        return {"x": xvp, "y": yvp}

    def transformadaViewPortCoordenada(self, x, y):
        xw_min, yw_min = self.window.getMin()["x"], self.window.getMin()["y"]
        xw_max, yw_max = self.window.getMax()["x"], self.window.getMax()["y"]

        xvp_min, yvp_min = self.x_min, self.y_min
        xvp_max, yvp_max = self.x_max, self.y_max

        xvp = ((x - xw_min) / (xw_max - xw_min)) * (xvp_max - xvp_min)
        yvp = (1 - (y - yw_min) / (yw_max - yw_min)) * (yvp_max - yvp_min)

        return {"x": xvp, "y": yvp}
Example #2
0
class Shape:
  def __init__(self, name):
    self.world_coords = []
    self.normalized_coords = []
    self.name = name
    self.id = generateRandomId()
    self.transform = Transform()

  def addCoords(self, x, y, z = 1):
    self.world_coords.append({"x": x, "y": y, "z": z})
    self.normalized_coords.append(self.transform.normalize(x, y))

  def popCoords(self):
    self.world_coords.pop()
    self.normalized_coords.pop()

  def getWorldCoords(self):
    return self.world_coords

  def getNormalizedCoords(self):
    return self.normalized_coords
  
  def scaleNormalizedCoords(self, percentage):
    center = self.transform.denormalize(0,0)  # get world coordenates for current viewport center

    # get real world coordinates from normalized ones
    coords = self.transform.denormalizeList(self.normalized_coords)

    for i in range(len(coords)):
      temp = self.transform.scale(
        coords[i]["x"], coords[i]["y"],
        percentage, percentage,
        center["x"], center["y"]
      )
      new_coords = self.transform.normalize(temp[0], temp[1])
      self.normalized_coords[i] = {"x": new_coords["x"], "y": new_coords["y"]}
  
  def rotateNormalizedCoords(self, degrees):
    center = self.transform.denormalize(0,0)  # get world coordenates for current viewport center

    # get real world coordinates from normalized ones
    coords = self.transform.denormalizeList(self.normalized_coords)
    
    for i in range(len(coords)):
      temp = self.transform.rotation(coords[i]["x"], coords[i]["y"], center["x"], center["y"], degrees)
      new_coords = self.transform.normalize(temp[0], temp[1])
      self.normalized_coords[i] = {"x": new_coords["x"], "y": new_coords["y"]}

  def setWorldCoords(self, i, x, y):
    self.world_coords[i] = { "x": x, "y": y }
    self.normalized_coords[i] = self.transform.normalize(x, y)

  def normalizeCoords(self):
    for i in range(len(self.world_coords)):
      x, y = self.world_coords[i]["x"], self.world_coords[i]["y"]
      self.normalized_coords[i] = self.transform.normalize(x, y)

  def getName(self):
    return self.name

  def getId(self):
    return self.id

  def drawToViewport(self, ctx, viewport):
    # move context to initial point
    clipping = Clipping()
    point = viewport.transform(self.normalized_coords[0]["x"], self.normalized_coords[0]["y"])
    ctx.move_to(point["x"],point["y"])

    if(self.__class__.__name__ == "Point"):
      # print("{},{}".format(self.normalized_coords[0]["x"], self.normalized_coords[0]["y"]))

      if (self.normalized_coords[0]["x"] >= -1 and self.normalized_coords[0]["x"] <= 1
          and self.normalized_coords[0]["y"] >= -1 and self.normalized_coords[0]["y"] <= 1):
        ctx.rel_line_to(1,1)  # equivalent to ctx.line_to(x+1,y+1)
        ctx.stroke()
    else:
      
      if(self.__class__.__name__ == "Line"):
        clipped_coords = clipping.clipLine(self.normalized_coords)
      elif(self.__class__.__name__ == "Polygon"):
        clipped_coords = clipping.sutherland_hodgman_clipping(self.normalized_coords)
      else:
        coords = self.transform.calculatePointsBezier(self.normalized_coords)
        #coords = self.transform.calculateBSpline(self.normalized_coords)
        clipped_coords = []
        temp_coords = []
        for i in range(0,len(coords)-1):
          temp_coords = []
          temp_coords.append(coords[i])
          temp_coords.append(coords[i+1])
          clipped = clipping.clipLine(temp_coords)
          if(clipped):
            clipped_coords.append(clipped[0])
            clipped_coords.append(clipped[1])
      if(clipped_coords):
        point = viewport.transform(clipped_coords[0]["x"], clipped_coords[0]["y"])
        ctx.move_to(point["x"],point["y"])
        
        for entry in clipped_coords:  # 1st interation does move_to and line_to to same point
          x2, y2 = entry["x"], entry["y"]
          point2 = viewport.transform(x2, y2)
          ctx.line_to(point2["x"],point2["y"])
        if(self.__class__.__name__ is not "Curve"):
          ctx.close_path()
        ctx.stroke()