1

我是一名新手程序员,使用 Javascript 编写的 OpenJScad 构建 3D 模型。

我试图弄清楚如何构造我的代码,以便我可以访问使用用户输入参数动态创建的对象的实例属性。我有一个带有以下变量的父 Gear 类...

// Gear parent class
Gear = function(numTeeth, circularPitch, pressureAngle, clearance, thickness)
{    
var pitchRadius = numTeeth * circularPitch / (2 * Math.PI);

我正在制作几个接受用户参数的 Gear 子类,即...

// Spur Gear
function makeSpur(params)
{
    var gear = new Gear(
    params.spurTeeth,
    params.circularPitch,
    params.pressureAngle,
    params.clearance,
    params.inputBore
);

if(params.inputBore > 0)
{
    var inputBore = CSG.cylinder({start: [0,0,-params.thickness2], end:
        [0,0,params.thickness2], radius: params.inputBore, resolution: 16});
    gear = gear.subtract(inputBore).rotateX(90);
}
return gear;

...然后根据另一个 Gear 对象的 pitchRadius 属性动态生成位置坐标...

// function main
var spurGear = makeSpur(params);
spurGear = spurGear.translate([-pinionGear.pitchRadius,0,0]);

一切都会呈现,除非我尝试从另一个 Gear 实例访问 pitchRadius 属性。我已经阅读了有关原型和访问私有/公共属性的信息,但我只是不知道如何构造代码以便我可以访问函数 main 中的实例属性。

4

2 回答 2

0

这是完整的代码...

   include("gears.jscad");

// Here we define the user editable parameters: 
function getParameterDefinitions() {
  return [
    { name: 'circularPitch', caption: 'Circular pitch:', type: 'float', initial: 5 },
    { name: 'pressureAngle', caption: 'Pressure angle:', type: 'float', initial: 20 },
    { name: 'clearance', caption: 'Clearance:', type: 'float', initial: 0 },
    { name: 'thickness', caption: 'Thickness of transmission gears:', type: 'float', initial: 5 },
    { name: 'spurTeeth', caption: 'Number of spur teeth:', type: 'int', initial: 32 },
    { name: 'pinionTeeth', caption: 'Number of pinion teeth:', type: 'int', initial: 14 },
    { name: 'bore', caption: 'Radius of shaft:', type: 'float', initial: 5 }
  ];
}

 // Main function
 function main(params)
{
  // declare parts
  spurGear = new makeSpur(params);
  pinionGear = new makePinion(params);

  // assemble parts
  spurGear = spurGear.translate([-pinionGear.pitchRadius, 0, -20]); // BREAKS CODE
  pinionGear = pinionGear.translate([-spurGear.pitchRadius, 0, 20]); // BREAKS CODE

  return [spurGear,pinionGear];
}

// Spur Gear
function makeSpur(params)
{
  var gear = new involuteGear(
    params.spurTeeth,
    params.circularPitch,
    params.pressureAngle,
    params.clearance,
    params.thickness,
    params.bore
  );
  if(params.bore > 0)
  {
    var bore = CSG.cylinder({start: [0,0,-params.thickness], end: [0,0,params.thickness], radius: params.bore, resolution: 16});
    gear = gear.subtract(bore).rotateX(90);
  }
  return gear;
}

// Pinion Gear
function makePinion(params)
{
  var gear = new involuteGear(
    params.pinionTeeth,
    params.circularPitch,
    params.pressureAngle,
    params.clearance,
    params.thickness,
    params.bore
  );
  if(params.bore > 0)
  {
    var bore = CSG.cylinder({start: [0,0,-params.thickness], end: [0,0,params.thickness], radius: params.bore, resolution: 16});
    gear = gear.subtract(bore).rotateX(90);
  }
  return gear;
}

// title: Gear
// author: Joost Nieuwenhuijse
// license: MIT License

/*
  For gear terminology see: 
    http://www.astronomiainumbria.org/advanced_internet_files/meccanica/easyweb.easynet.co.uk/_chrish/geardata.htm
  Algorithm based on:
    http://www.cartertools.com/involute.html

  circularPitch: The distance between adjacent teeth measured at the pitch circle
*/ 
function involuteGear(numTeeth, circularPitch, pressureAngle, clearance, thickness)
{
  // default values:
  if(arguments.length < 3) pressureAngle = 20;
  if(arguments.length < 4) clearance = 0;
  if(arguments.length < 4) thickness = 1;

  var addendum = circularPitch / Math.PI;
  var dedendum = addendum + clearance;

  // radiuses of the 4 circles:
  this.pitchRadius = numTeeth * circularPitch / (2 * Math.PI);
  // this.getpitchRadius = function() {
    //return pitchRadius;
  //};
  var baseRadius = this.pitchRadius * Math.cos(Math.PI * pressureAngle / 180);
  var outerRadius = this.pitchRadius + addendum;
  var rootRadius = this.pitchRadius - dedendum;

  var maxtanlength = Math.sqrt(outerRadius*outerRadius - baseRadius*baseRadius);
  var maxangle = maxtanlength / baseRadius;

  var tl_at_pitchcircle = Math.sqrt(this.pitchRadius*this.pitchRadius - baseRadius*baseRadius);
  var angle_at_pitchcircle = tl_at_pitchcircle / baseRadius;
  var diffangle = angle_at_pitchcircle - Math.atan(angle_at_pitchcircle);
  var angularToothWidthAtBase = Math.PI / numTeeth + 2*diffangle;

  // build a single 2d tooth in the 'points' array:
  var resolution = 5;
  var points = [new CSG.Vector2D(0,0)];
  for(var i = 0; i <= resolution; i++)
  {
    // first side of the tooth:
    var angle = maxangle * i / resolution;
    var tanlength = angle * baseRadius;
    var radvector = CSG.Vector2D.fromAngle(angle);    
    var tanvector = radvector.normal();
    var p = radvector.times(baseRadius).plus(tanvector.times(tanlength));
    points[i+1] = p;

    // opposite side of the tooth:
    radvector = CSG.Vector2D.fromAngle(angularToothWidthAtBase - angle);    
    tanvector = radvector.normal().negated();
    p = radvector.times(baseRadius).plus(tanvector.times(tanlength));
    points[2 * resolution + 2 - i] = p;
  }

  // create the polygon and extrude into 3D:
  var tooth3d = new CSG.Polygon2D(points).extrude({offset: [0, 0, thickness]});

  var allteeth = new CSG();
  for(var j = 0; j < numTeeth; j++)
  {
    var ang = j*360/numTeeth;
    var rotatedtooth = tooth3d.rotateZ(ang);
    allteeth = allteeth.unionForNonIntersecting(rotatedtooth);
  }

  // build the root circle:  
  points = [];
  var toothAngle = 2 * Math.PI / numTeeth;
  var toothCenterAngle = 0.5 * angularToothWidthAtBase; 
  for(var k = 0; k < numTeeth; k++)
  {
    var angl = toothCenterAngle + k * toothAngle;
    var p1 = CSG.Vector2D.fromAngle(angl).times(rootRadius);
    points.push(p1);
  }

  // create the polygon and extrude into 3D:
  var rootcircle = new CSG.Polygon2D(points).extrude({offset: [0, 0, thickness]});

  var result = rootcircle.union(allteeth);

  // center at origin:
  result = result.translate([0, 0, -thickness/2]);

  return result;
}
于 2013-07-23T18:35:38.630 回答
0

我注意到您实际上是在构造函数中返回 CSG 对象,因此请尝试使用 OpenJSCAD 用户指南中描述的属性容器。根据引导属性,变量旨在存储对象的元数据。

这是指南中的一个示例:

var cube = CSG.cube({radius: 1.0});
cube.properties.aCorner = new CSG.Vector3D([1, 1, 1]);

附加评论:

  1. 您在构造函数中返回不同的对象然后 this
  2. 如果你会做这样的事情: gear = gear.rotateX(90); 那么你有新的对象
  3. 如果您将使用属性,则在进行转换时会克隆元数据。
于 2015-06-30T07:26:15.473 回答