GithubHelp home page GithubHelp logo

Comments (11)

Nocte- avatar Nocte- commented on June 28, 2024

How does it behave if you leave autosolve turned on, and remove the explicit .solve() calls?

(Also, there's a function 'add_stays' that takes a list of variables.)

from rhea.

hfossli avatar hfossli commented on June 28, 2024

You are right. It does behave very differently!

I was even able to add other constraints without any problems. See video

static rhea::simplex_solver solver;

static rhea::variable blueLeft (10);
static rhea::variable blueTop (10);
static rhea::variable blueWidth (100);
static rhea::variable blueHeight (100);

static rhea::variable greenLeft (220);
static rhea::variable greenTop (10);
static rhea::variable greenHeight (100);
static rhea::variable greenWidth (100);

static rhea::variable containerWidth (320);
static rhea::variable containerHeight (480);

@interface ViewController ()

@property (nonatomic, strong) UIView *blueView;
@property (nonatomic, strong) UIView *greenView;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self setupViews];

    solver.set_autosolve(true);

    solver.on_resolve = [self](rhea::simplex_solver &solver) {
        [self updateFrames];
    };

    rhea::variable_set variable_set = {
        blueLeft, blueTop, blueWidth, blueHeight,
        greenLeft, greenTop, greenWidth, greenHeight,
        containerWidth, containerHeight
    };
    solver.add_stays(variable_set);

    solver.add_constraints({
        greenTop == blueTop,
        blueLeft >= 10,
        (blueLeft + blueWidth) <= greenLeft
    });
}

- (void)setupViews
{
    self.blueView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
    self.blueView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:self.blueView];

    UIPanGestureRecognizer *blueRecognizer = [UIPanGestureRecognizer new];
    [blueRecognizer addTarget:self action:@selector(blueRecognizerUpdated:)];
    [self.blueView addGestureRecognizer:blueRecognizer];

    self.greenView = [[UIView alloc] initWithFrame:CGRectMake(220, 0, 200, 200)];
    self.greenView.backgroundColor = [UIColor greenColor];
    [self.view addSubview:self.greenView];

    UIPanGestureRecognizer *greenRecognizer = [UIPanGestureRecognizer new];
    [greenRecognizer addTarget:self action:@selector(greeRecognizerUpdated:)];
    [self.greenView addGestureRecognizer:greenRecognizer];
}

- (void)blueRecognizerUpdated:(UIPanGestureRecognizer *)recognizer
{
    CGPoint translation = [recognizer translationInView:recognizer.view.superview];
    [recognizer setTranslation:CGPointZero inView:recognizer.view.superview];

    solver.suggest({
        { blueLeft, blueLeft.value() + translation.x },
        { blueTop, blueTop.value() + translation.y }
    });
}

- (void)greeRecognizerUpdated:(UIPanGestureRecognizer *)recognizer
{
    CGPoint translation = [recognizer translationInView:recognizer.view.superview];
    [recognizer setTranslation:CGPointZero inView:recognizer.view.superview];

    solver.suggest({
        { greenLeft, greenLeft.value() + translation.x },
        { greenTop, greenTop.value() + translation.y }
    });
}

- (void)updateFrames
{
    CGRect blueFrame;
    blueFrame.origin.x = blueLeft.value();
    blueFrame.origin.y = blueTop.value();
    blueFrame.size.width = blueWidth.value();
    blueFrame.size.height = blueHeight.value();
    self.blueView.frame = blueFrame;

    CGRect greenFrame;
    greenFrame.origin.x = greenLeft.value();
    greenFrame.origin.y = greenTop.value();
    greenFrame.size.width = greenWidth.value();
    greenFrame.size.height = greenHeight.value();
    self.greenView.frame = greenFrame;
}

@end

from rhea.

Nocte- avatar Nocte- commented on June 28, 2024

Looking good in that latest video! Yeah, manually triggering the solution definitely is buggy. It works in the original code base, so it's a matter of doing a side-by-side comparison of the execution paths. I'll have a crack at it tonight.

from rhea.

hfossli avatar hfossli commented on June 28, 2024

Thanks!!

from rhea.

hfossli avatar hfossli commented on June 28, 2024

Do you have time to look at this bug? Do you know how to reproduce the bug? If your time is limited we could probably arrange so that you get paid for fixing this.

from rhea.

Nocte- avatar Nocte- commented on June 28, 2024

Yes it's reproducable. I couldn't find the bug at first glance and haven't looked at it since. I'll have another go at it.

from rhea.

hfossli avatar hfossli commented on June 28, 2024

Awesome! The following code always works if I omit the solver.set_autosolve(false); command, but yields very different results if not.

    rhea::simplex_solver solver;
    rhea::variable a, b, c;

    solver.set_autosolve(false);

    solver.add_stays(rhea::variable_set({
        a, c
    }));

    solver.add_constraints({
        a == 10,
        b == c,
    });

    solver.suggest({
        { c, 100 }
    });

    solver.solve();

    NSLog(@"a %.2f, b %.2f, c %.2f", a.value(), b.value(), c.value());

    solver.suggest({
        { c, 90 }
    });

    solver.solve();

    NSLog(@"a %.2f, b %.2f, c %.2f", a.value(), b.value(), c.value());

Output 1

a 10.00, b 0.00, c 0.00
a 10.00, b 90.00, c 90.00

Output 2

a 10.00, b 0.00, c 0.00
a 10.00, b 0.00, c 0.00

Output 3 (expected)

a 10.00, b 100.00, c 100.00
a 10.00, b 90.00, c 90.00

from rhea.

hfossli avatar hfossli commented on June 28, 2024

Seems to be similar to this https://github.com/hfossli/rhea/compare/inconcistency

from rhea.

Nocte- avatar Nocte- commented on June 28, 2024

Alright, I think it works now, but it's a kinda weird fix that I'll probably revisit in the future. Let me know if this solves it!

from rhea.

hfossli avatar hfossli commented on June 28, 2024

Awesome. I will check on monday. 👍 do you think this is a problem with rhea or all cassowary ports?=

from rhea.

Nocte- avatar Nocte- commented on June 28, 2024

Hard to tell, but I think it's just my version. I must admit that I don't understand the problem 100%, but what I've seen is that Rhea sometimes picks the "wrong" variable to pivot out during the tableau optimization (first part of simplex_solver::optimize). This bites you in the ass later in delta_edit_constant(). Seems to be a matter of what type of slack variables you end up with (basic or not).

I've fixed it by changing linear_expression::terms_map from a std::unordered_map to a std::map. The result is that all linear expressions now iterate through their terms in a consistent order. But not only are map (and flat_map) slower, I also don't understand why the iteration order matters.

The original implementation also had the option to use a hash map, so there's a good chance I'm fixing the wrong thing here. I can't switch it easily to test it though ( is unavailable and <unordered_map> does not compile).

On the other hand, if it's stupid and it works, it's not stupid. ;)

from rhea.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.