Skip to content

nonDegenerateAngle incorrect behaviour for "range" #1901

@AlexKubiesa

Description

@AlexKubiesa

Describe the bug
When I use nonDegenerateAngle with a small range value of 5, angles are forced to be much larger than 5°, so the range cutoff is not respected. I am using Bloom but the issue seems to be in penrose/core, so it affects Penrose as well.

Looking at the implementation

const c0 = shapeCenter(s0);
const c1 = shapeCenter(s1);
const c2 = shapeCenter(s2);

const l1 = ops.vsub(c0, c1);
const l2 = ops.vsub(c2, c1);
const cosine = absVal(ops.vdot(ops.vnormalize(l1), ops.vnormalize(l2)));
// angles that are more than `range` deg from 0 or 180 do not need to be pushed
return ifCond(
  lt(cosine, range * (Math.PI / 180)),
  0,
  mul(strength, cosine),
);

it seems that a cosine is being directly compared with an angle in lt(cosine, range * (Math.PI / 180)). I guess the correct thing to do would be to take the cosine of range * (Math.PI / 180) and compare against that instead.

To Reproduce

Domain:

type Angle

Substance:

Angle A

Style:

canvas {
  width = 500
  height = 500
}

forall Angle a {
  a.pos = (?, ?)
  
  a.line1 = Line {
    start : a.pos
    end : (?, ?)
    strokeColor : #000000
    strokeWidth : 1
    style : "solid"
  }

  a.line2 = Line {
    start : a.pos
    end : (?, ?)
    strokeColor : #000000
    strokeWidth : 1
    style : "solid"
  }

  a.p1 = Circle {
    r : 5
    fillColor : #000000
    center : a.line1.end
  }

  a.p2 = Circle {
    r : 5
    fillColor : #000000
    center : a.pos
  }

  a.p3 = Circle {
    r : 5
    fillColor : #000000
    center: a.line2.end
  }

  encourage nonDegenerateAngle(a.p1, a.p2, a.p3, 20, 1)
}

global {
    shape background = Rectangle {
        center: (0, 0)
        width: canvas.width
        height: canvas.height
        fillColor: #F6F4F2
    } 
}

Steps to reproduce the behavior:

  1. Put the Domain, Substance and Style above into the Penrose editor and compile.
  2. Resample a few times and see that the angle is never close to 1°. You can also drag the slider and see that the optimizer pushes it to be larger even though it's greater than 1°.
  3. Comment out the "encourage nonDegenerateAngle" line and repeat step 2. The behaviour is different: smaller angles are seen, and the optimizer barely affects the angle at all.

Expected behavior
The range parameter should behave as documented. Setting range to 1 should not affect angles that are already between 1° and 179°. Setting range to 5 should not affect angles between 5° and 175°.

Screenshots
Not included. Should be easy to reproduce.

Desktop (please complete the following information if applicable):

  • OS: Linux (Ubuntu)
  • Browser: Chromium
  • Version: 135.0.7049.114 (Official Build) snap (64-bit)

Additional context
N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions