RhinoScript OffsetCurve problem

I have a script works well in Rhino6, but when I run it in Rhino 7, the offsetcurve works differently, I have give the direction with the centroid area point to make as inside curve, however, it still offset the curve in y axis, I also try vector method, it still works wrong. what is the problem?

The script:

import rhinoscriptsyntax as rs
winFraWid=100
zxPlane=rs.WorldZXPlane()
rec=rs.AddRectangle(zxPlane,2000,1000)
winPts=rs.CurvePoints(rec)
cenPt=rs.CurveAreaCentroid(rec)[0]
vec=rs.VectorCreate(winPts[0],cenPt)
inFrameRec=rs.OffsetCurve(rec,cenPt,winFraWid,normal=vec)

Hi @herocaripod ,

import rhinoscriptsyntax as rs

winFraWid = rs.GetInteger("Offset value")
curve_id = rs.GetObject("Select a curve", rs.filter.curve)
if curve_id:
    # Get the plane of the selected curve
    curve_plane = rs.CurvePlane(curve_id)
    if curve_plane:
        winPts = rs.CurvePoints(curve_id)
        cenPt = rs.CurveAreaCentroid(curve_id)[0]
        # Calculate the offset direction vector
        vec = rs.VectorCreate(cenPt, winPts[0])
        vec = rs.VectorUnitize(vec)
        # Offset the curve using the direction vector
        inFrameRec = rs.OffsetCurve(curve_id, vec, winFraWid)
    else:
        print("Failed to get the plane of the selected curve.")
else:
    print("No curve selected.")

You must set reference plane for the offset, in this case we extract the plane from the curve using CurvePlane.

Hope this helps,
Farouk

yes, i try this program in Rhino 7, the result is still this.
still thank you!
it seems like the point with vector cannot give rhino a clear direction

The problem is that getting the correct direction point is not an easy task. The curve area centroid could actually be outside the curve for example. And as offset is sometimes sensitive to exactly where the offset point is placed, I prefer a different approach. I offset both sides using the simple distance overload in RhinoCommon, then I try to determine which is inside from the two results. I’m pretty sure that the inside offset will always have a smaller area then the outside offset - in any case that is what I use here.

Also note that offset can produce multiple results…

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino

def GetCombinedArea(crvs,tol):
    tot_area=0
    for crv in crvs:
        mp=Rhino.Geometry.AreaMassProperties.Compute(crv,tol)
        if  not mp: return
        tot_area+=mp.Area
    return tot_area

def OffsetCrv2Sides(crv,plane,dist,trans,tol):
    offset1=crv.Offset(plane,dist,tol,trans)
    offset2=crv.Offset(plane,-dist,tol,trans)
    #either offset could be a list of one or multiple curves or be None
    return offset1,offset2

#planar closed curves filter
def cp_crv_filt(rhino_object, geometry, component_index):
    return rs.IsCurvePlanar(geometry) and rs.IsCurveClosed(geometry)

def OffsetClsdCrvInside():
    msg="Select a closed planar curve to offset inside"
    crv_id = rs.GetObject(msg,4,preselect=True,custom_filter=cp_crv_filt)
    if not crv_id: return
    
    tol=sc.doc.ModelAbsoluteTolerance
    dist=rs.GetReal("Distance to offset?",1,minimum=tol)
    if dist is None: return
    
    crv=rs.coercecurve(crv_id)
    rc,plane=crv.TryGetPlane()
    if not rc:
        print("Error getting curve plane")
        return
    
    #change the following if necessary
    trans=Rhino.Geometry.CurveOffsetCornerStyle.Sharp
    off_1,off_2=OffsetCrv2Sides(crv,plane,dist,trans,tol)
    if off_1 is None or off_2 is None:
        print("Unable to get offsets")
        return
    off_1_area=GetCombinedArea(off_1,tol)
    off_2_area=GetCombinedArea(off_2,tol)
    if not off_1_area or not off_2_area:
        print("Unable to calculate areas")
        return
    #if you want an outside offset, change < to >
    if off_1_area<off_2_area:
        offset_ids=[sc.doc.Objects.AddCurve(crv) for crv in off_1]
    else:
        offset_ids=[sc.doc.Objects.AddCurve(crv) for crv in off_2]
    rs.SelectObjects(offset_ids)
    sc.doc.Views.Redraw()

OffsetClsdCrvInside()