rikrd / geomerative

Geomerative is a library for Processing. It extends 2D geometry operations to facilitate generative geometry. Includes a TrueType font and an SVG interpreters. This library exposes the shapes (such as vector drawings or typographies) in a more approchable way. Geomerative makes it easy to access the contours, the control points and the curve points, making it easy to develop generative typography and geometry pieces in Processing.

Home Page:http://www.ricardmarxer.com/geomerative

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

RShape.contains(RShape) is always false

Angular-Angel opened this issue · comments

RShape.contains(RShape) always seems to return false, no matter what. Here's a sketch that accurately describes the problem - the small rectangle should turn red when inside the larger one, but it never does, despite intersecting with it, and then not intersecting with it after it goes inside.

import geomerative.*;

RShape shape;
RShape rect;

void setup(){
  size(600, 600, OPENGL);
  smooth();

  // VERY IMPORTANT: Allways initialize the library before using it
  RG.init(this);
  RG.setPolygonizer(RG.ADAPTATIVE);

  RG.ignoreStyles();
  
  shape = RG.getRect(100,100,100,50);
}

void draw(){
  rect = RShape.createRectangle(mouseX, mouseY, 10, 10);
  shape.draw(this);
  if (shape.contains(rect))
    rect.setFill(color(255, 0, 0));
  rect.draw(this);
  RPoint[] ps = shape.getIntersections(rect);
  if (ps != null) {
    for (int i=0; i<ps.length; i++) {
      ellipse(ps[i].x, ps[i].y, 10, 10);
    }
  }
}

I believe this to be due to faulty logic in RGeomElem.java

  public boolean contains(RPoint[] ps) {
    boolean contains = false;
    if(ps != null){
      for(int i=0; i < ps.length; i++) {
        contains &= this.contains(ps[i]);
      }
    }
    return contains;
  } 

In my hands always returns false
Simple crude fix:-

 public boolean contains(RPoint[] ps) {
        if (ps.length == 0) {
            return false;
        }
        for (RPoint p : ps) {
            if (!this.contains(p)) {
                return false;
            }
        }
        return true;
    } 

Since java-8 possible to use lambda for a more elegant solution, and it makes sense not to overload contains.

    public boolean containsPoints(RPoint[] pts) {
        Stream<RPoint> outside = Arrays.stream(pts).filter(pt -> !contains(pt));
        return outside.count() == 0;
    }

Hmm. Is this library maintained? If not it might be necessary to fork it. A pain, but I could do it if I need to. :/

As for the function, the earlier fix you posted seems more efficient. It returns immediately upon discovering false, whereas this one performs a bunch of unnecessary computation. And yeah, this ones shorter, but it's also a lot denser and more complicated. Personally, I'd prefer the first, simpler option.

Sorry for the delay fellows.
I have been swamped with pressing deadlines and hadn't had a chance to look into this.

Do I need to do anything to update my library for this? I tried running Processing and it didn't show any updates, or say anything about updates. :/