Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.

First time visiting? Here are some places to start:
  1. Looking for a certain topic? Check out the categories filter or use Search (upper right).
  2. Need support? Ask a question to our Community Support category.
  3. Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
  4. Be respectful, on topic and if you see a problem, Flag it.

If you would like to contact our Community Manager personally, feel free to send a private message or an email.

If statement for parameter entry?

RyanAveryRyanAvery Member Posts: 92 EDU
I'm using the parametric curve feature script with a Cartesian parameter input. For my Y value input I have this:
#t^(#tExponent) * #startingConst
where tExponent is a number and startingConst is a length (mm)
and my X and Z values are just trig functions so it gives me a helix that winds close at the begging and then gets more stretched out at the end.
this is working great.

What I now want is at some y value yd, that this function then changes to start using a different function, so it switches back to a normal helix at that yd point (not expanding anymore).
I tried this for the y input box:
(#t^(#tExponent) * #startingConst) < 150 ? (#t^(#tExponent) * #startingConst) : (#t^(#tExponent) * 2mm)

Also, my t is going from 0 to 50

I have got this to work as valid input for the Y field:
#startingConst < 0.5mm ? 1mm * #t : 2mm * #t

And i've also got this to work for the Y field:

But I cant get any of these to work.
(#t^(#tExponent) * #startingConst) < 10mm ? (#t^(#tExponent) * #startingConst) : 2mm * #t
(#t^(#tExponent) * #startingConst) > 10mm ? (#t^(#tExponent) * #startingConst) : 2mm * #t
(#t^(#tExponent) * #startingConst) < 10mm ? (#t^(#tExponent) * #startingConst) : 2mm

Can I reference the current value of Y in the place that I'm inputting Y?
Any ideas?




Comments

  • RyanAveryRyanAvery Member Posts: 92 EDU

    I think my problem is the function needs to be continuous, so I'm trying to make the change on T = 24 (t goes from 0 to 50 the way I have it setup)


    Once it hits that plane, I want the function to switch to linear. So I'm trying this now for Y:

    #t < 24 ? (#t^(#tExponent) * #startingConst) : 4mm*(#t-24)+((24^(tExponent) * #startingConst)

    But that is failing



  • RyanAveryRyanAvery Member Posts: 92 EDU
    I think this should work: #t < 24 ? (#t^(#tExponent) * #startingConst) : 4mm*(#t-24)+(24^#tExponent * #startingConst)




    So my true and false functions are both valid, and I think they do go thru the same point at #t = 24 as shown in desmos above, but I cant get the if / else to work >.<



  • RyanAveryRyanAvery Member Posts: 92 EDU
    This is the function I'm trying to put in for my Y value, lol:

  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,558
    @RyanAvery

    I've taken a look at the code.  I think that all @mahir would have to do to enable this would be to overload the `operator<` function in the same way that he has overloaded the rest of the operators to enable them to be used in that expression field.

    For now, could I suggest doing two separate parametric curve features, and switching them at the boundary of your parameterization, then joining them as a composite curve? That will only work if you don't care about having a tangent discontinuity in your result.  If you do care we can see if Mahir answers, or just copy the feature and try the enhancement.
    Jake Rosenfeld - Modeling Team
  • RyanAveryRyanAvery Member Posts: 92 EDU
    Hey thanks for the response. Is it possible to join two helix curves?
  • mahirmahir Member, Developers Posts: 948 ✭✭✭✭
    I'll take a look at the FS
  • mahirmahir Member, Developers Posts: 948 ✭✭✭✭
    edited April 8
    @Jake_Rosenfeld, I was trying to add overloads for all the logical operators in my FS, but for some reason the only overload that doesn't generate a code error is less than, "<". The error in question is "mismatched input 'XX' expecting {'+', '-', '*', '/', '%', '^', '<'}", where XX is >,<=,>=, ==, or !=.
  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,558
    edited April 8
    @mahir

    Generally all of the other operators should just be abstractions of <.

    > is just < called in the opposite order (assuming the two parameters have the same types).  If you have two different parameter types you may need to define < for both parameter orderings.

    a == b is !(a < b) && !(b < a)
    a != b is a < b || b < a
    a <= b is a < b && !(b < a)
    a >= b is !(a < b)

    We might implement them slightly differently but the point is that all you need is < for both parameter orderings and the other operators just come along.
    It is mentioned in the operator overloads section of the documentation: https://cad.onshape.com/FsDoc/top-level.html

    @ilya_baran may be able to shed more specific light on whether I have totally misunderstood the implementation
    Jake Rosenfeld - Modeling Team
  • mahirmahir Member, Developers Posts: 948 ✭✭✭✭
    @RyanAvery, I created a new version that adds support for "<" (and also hopefully >, <=, and >=). If you update the FS to the latest version your if statements should hopefully work. Let me know how it goes.
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 978
    Jake is almost right about the overloading.  The rule is:
    == and != are not overloadable -- if two things compare == in FeatureScript, they're interchangeable.
    Once you overload a < b,
    a <= b is !(b < a)
    a > b is b < a
    a >= b is !(a < b)

    Unfortunately, I don't think overloading < will be enough here, because the ?: ternary operator itself is not overloadable.  I would suggest doing it by writing function that depending on the value of the first argument evaluates either the second or the third.
    Ilya Baran \ Director, Architecture and FeatureScript \ Onshape Inc
  • mahirmahir Member, Developers Posts: 948 ✭✭✭✭
    @ilya_baran, sounds like you're saying >,<=, and >= will work now that < is overloaded, but I'll need to write something akin to Excel's IF() function to get them to work as @RyanAvery intends? It looks like the ?: ternary operator was already working when not used with comparison operators, so why would the separate IF() function be necessary?
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 978
    @mahir Yeah, that's exactly what I'm saying.  For the separate function, I think something like this:
    export function If(cond is Expression, ifTrue is Expression, ifFalse is Expression) returns Expression
    {
        return function(t)
            {
                return cond(t) ? ifTrue(t) : ifFalse(t);
            } as Expression;
    }
    

    It's needed because just using ? can't evaluate the condition as a function of t.  So we can use it for constants, but not for something that varies with t.
    Ilya Baran \ Director, Architecture and FeatureScript \ Onshape Inc
  • RyanAveryRyanAvery Member Posts: 92 EDU
    edited April 9
    So the if / ternary functionality is working. I can do this and it works:

    works:
    1 < 2 ? -cos(#t * rad) : -sin(#t * rad)
    works:
    1 <= 24 ? sin(#t * rad)*1mm : cos(#t * rad)*1mm

    But if I make the conditional on #t it fails, for instance this fails:

    fails:
    #t < 24 ? sin(#t * rad)*1mm : cos(#t * rad)*1mm

    fails:
    #t < 24 ? 1mm : 2mm


    So I think the problem is referencing #t as an input to the conditional. Also, would it be possible to reference the value of Y in the input of Y's conditional? i.e.

    input for Y field:
    Y < 50 ? sin(#t * rad) * 1mm : cos(#t * rad) * 1mm

  • mahirmahir Member, Developers Posts: 948 ✭✭✭✭
    Updated to V10 to add support for If(), assuming it works. No testing was done. @RyanAvery, so instead of using
    #t < 24 ? 1mm : 2mm
    do this
    If(#t < 24, 1mm, 2mm)
    As for self referencing, that isn't supported, nor does it make much logical sense since it presents a chicken or the egg scenario. Even referencing #X in the Y formula would lead to circular references that would require code that decides which formula gets calculated first, and that isn't happening anytime soon if ever. If you want to reference #Y in the X formula, then can copy the formula for Y and paste it in manually.
  • RyanAveryRyanAvery Member Posts: 92 EDU
    @mahir Thanks man I'll test it out right now. First I'll have to try to update it, i've never updated a FS before.
  • mahirmahir Member, Developers Posts: 948 ✭✭✭✭
    Should be pretty easy. You'll see a little link icon. You'll just need to right-click update.
  • RyanAveryRyanAvery Member Posts: 92 EDU
    edited April 9
    mahir said:
    Updated to V10 to add support for If(), assuming it works. No testing was done. @RyanAvery, so instead of using
    #t < 24 ? 1mm : 2mm
    do this
    If(#t < 24, 1mm, 2mm)
    As for self referencing, that isn't supported, nor does it make much logical sense since it presents a chicken or the egg scenario. Even referencing #X in the Y formula would lead to circular references that would require code that decides which formula gets calculated first, and that isn't happening anytime soon if ever. If you want to reference #Y in the X formula, then can copy the formula for Y and paste it in manually.

    @mahir I tried doing exactly as you said. First, I right clicked the FS in top right corner and did update. It took me to the page of the FS and I did update all. Then, I changed my parametric curve to look exactly like what you said, and it is giving me an error:
    I tried with IF, if, and If, none worked.

    I checked, and I am on V10 of the FS

    This also fails:
    If(1 < 10, 1mm, 2mm)

  • mahirmahir Member, Developers Posts: 948 ✭✭✭✭
    Any ideas @ilya_baran? The logical operators seem to work now that < is overloaded, but the exported If() function isn't working. I copy and pasted your code verbatim and don't see any obvious problem.
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 978
    Just guessing: The function is only defined for expressions -- looks like it needs to overload for values also...
    Ilya Baran \ Director, Architecture and FeatureScript \ Onshape Inc
  • mahirmahir Member, Developers Posts: 948 ✭✭✭✭
    @ilya_baran, I overloaded all permutations, but I can't get any usage of If() to work. Can you take a quick look at the If() overloads at the bottom of the FS? Thanks.
    https://cad.onshape.com/documents/578ff8b3e4b0e65410fcfda3/w/d33395f174e5b38f4abd6097/e/0c17de6a800d4aed83de417f

  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 978
    It's not pretty -- I see two things I forgot about:
    operator< is forced to return a boolean, which will fail since it needs to return an expression.  The solution is to instead implement a function called less (it's uglier syntax but that's what it is).
    The other issue is that the feature can't call these functions directly (because features are imported through namespaces).  The solution I came up with is:
            setVariable(context, "If", function(cond, ifTrue, ifFalse) {
                    return If(cond, ifTrue, ifFalse);
                });
            setVariable(context, "less", function(op1, op2) {
                    return less(op1, op2);
                });
    In the defineParameter feature.  Then I could get it to work...
    Ilya Baran \ Director, Architecture and FeatureScript \ Onshape Inc
  • mahirmahir Member, Developers Posts: 948 ✭✭✭✭
    You're right; it’s not pretty :# You know I’m an ME not a dev, right? :D I think I’ll cut my losses and just remove comparison and If support. Users will just have to create separate curves...
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 978
    I'll consider removing the restriction on the overload of < as I may have been too parochial there.  That will leave just the #If which I think is not that bad.

    Didn't know you weren't a dev @mahir, you built some really nice features.
    Ilya Baran \ Director, Architecture and FeatureScript \ Onshape Inc
  • RyanAveryRyanAvery Member Posts: 92 EDU
    @mahir noooooo!!! please include this functionality! is it greatly needed!!! Is there any devs at onshape that could help Mahir out? 
  • mahirmahir Member, Developers Posts: 948 ✭✭✭✭
    I'll consider removing the restriction on the overload of < as I may have been too parochial there.  That will leave just the #If which I think is not that bad.

    Didn't know you weren't a dev @mahir, you built some really nice features.
    Thanks for the compliment. If overloading of < becomes unrestricted, I'll revisit overloading and If() support, although I'm not sure what the setVariable calls above are accomplishing ¯\_(ツ)_/¯ 
  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,558
    @mahir The setVariable calls are so that the user can use the `If` and `Less` functions in the feature parameter entry boxes.  Ilya is saying that there is a limitation that just defining them as `export function` won't make them available in the parameter entry, but setting them as a variable will.
    Jake Rosenfeld - Modeling Team
  • mahirmahir Member, Developers Posts: 948 ✭✭✭✭
    Ok, gotcha. Guess I'll wait for < to be freed up for overloading. I could implement a LessThan() function, but I really don't like that idea. If() is at least similar to how Excel does it and is somewhat self-explanatory. Nobody is going to want to use a LessThan() function when logically you want to just type <.
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 978
    Kevin pointed out that if the overload for < doesn't return a boolean, we can't automatically use it for <= and >=.  That kills that plan unfortunately.
    Ilya Baran \ Director, Architecture and FeatureScript \ Onshape Inc
  • mahirmahir Member, Developers Posts: 948 ✭✭✭✭
    Can you allow overloading of all the operators so I can get them to return expressions?
  • RyanAveryRyanAvery Member Posts: 92 EDU
    LessThan() still would work though, with four parameters? A < B, C else D?
Sign In or Register to comment.