# This is a slight modification of the script provided at http://www.smustard.com/script/offset# Only the Face.offset method is kept, and it is wrapped in a function instead of modifying the base class to avoid conflicts=begin rdoc= Offset.rbCopyright 2004,2005,2006,2009 by Rick Wilson - All Rights Reserved== DisclaimerTHIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.== LicenseThis software is distributed under the Smustard End User License Agreementhttp://www.smustard.com/eula== InformationAuthor:: Rick WilsonOrganization:: SmustardName:: offset.rbVersion:: 2.201SU Version:: 4.0Date:: 2010-10-15Description:: Offset edges of a selected face (new method for class Sketchup::Face)Usage::* 1:: Intended for developers as a method to call from within a script. Add a "require 'offset.rb'" line right after the "require 'sketchup.rb'" line. Developers may distribute with their scripts since not everyone will have this already, but best to link to http://www.smustard.com/script/offset for the most current version. Returns the face created by the offset, or 'nil' if no face can be created.* 2:: ArcCurve.offset(dist) -- if dist is (+), offsets outside the curve (larger radius); if dist is (-), offsets inside the curve (smaller radius).* 3:: Curve.offset(dist) -- if dist is (+), offsets to the right of the curve (relative to the first segment direction and plane); if dist is (-), offsets to the left of the curve.History::* 2.201:: 2010-10-15 * fixed Face.offset(dist) bug that prevented some faces from being offset* 2.200:: 2009-02-05 * added point analysis tools and error trapping to the face.offset method* 2.100:: 2006-06-28 * changed the face creation to parent.entities.add_face to allow for correct creation regardless of nested status* 2.000:: 2005-08-12 * added offset methods for ArcCurve and Curve objects* 1.000:: 2004-09-07 * first version=end#/moduleAlexHallmoduleSunHoursdefSunHours.offset_face(face, dist)begin pi =Math::PIif (not ((dist.class==Fixnum|| dist.class==Float|| dist.class==Length) && dist!=0))returnnilend verts=face.outer_loop.vertices pts = []# CREATE ARRAY pts OF OFFSET POINTS FROM FACE0.upto(verts.length-1) do|a| vec1 = (verts[a].position-verts[a-(verts.length-1)].position).normalize vec2 = (verts[a].position-verts[a-1].position).normalize vec3 = (vec1+vec2).normalizeif vec3.valid? ang = vec1.angle_between(vec2)/2 ang = pi/2if vec1.parallel?(vec2) vec3.length = dist/Math::sin(ang) #/ t =Geom::Transformation.new(vec3)if pts.length >0 vec4 = pts.last.vector_to(verts[a].position.transform(t))if vec4.valid?unless (vec2.parallel?(vec4)) t =Geom::Transformation.new(vec3.reverse)endendend pts.push(verts[a].position.transform(t))endend# CHECK FOR DUPLICATE POINTS IN pts ARRAY duplicates = [] pts.each_index do|a| pts.each_index do|b|nextif b==a duplicates<<b if pts[a]===pts[b]endbreakif a==pts.length-1end duplicates.reverse.each{|a| pts.delete(pts[a])}# CREATE FACE FROM POINTS IN pts ARRAY (pts.length >2) ? (face.parent.entities.add_face(pts)) : (returnnil)rescueputs"#{face} did not offset: #{pts}"raiseendendendend