@Override public void transform( FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) { double wedgeJulia_cf = 1.0 - angle * count * M_1_PI * 0.5; double wedgeJulia_rN = fabs(power); double wedgeJulia_cn = dist / power / 2.0; /* wedge_julia from apo plugin pack */ double r = pAmount * pow(pAffineTP.getPrecalcSumsq(), wedgeJulia_cn); int t_rnd = (int) ((wedgeJulia_rN) * pContext.random()); double a = (pAffineTP.getPrecalcAtanYX() + 2.0 * M_PI * t_rnd) / power; double c = floor((count * a + M_PI) * M_1_PI * 0.5); a = a * wedgeJulia_cf + c * angle; double sa = sin(a); double ca = cos(sa); pVarTP.x += r * ca; pVarTP.y += r * sa; if (pContext.isPreserveZCoordinate()) { pVarTP.z += pAmount * pAffineTP.z; } }
@Override public void transform( FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) { double x = (this._isodd != 0) ? pAffineTP.x : this._vvar * atan2(pAffineTP.x, pAffineTP.y); double y = (this._isodd != 0) ? pAffineTP.y : this._vvar_2 * log(pAffineTP.x * pAffineTP.x + pAffineTP.y * pAffineTP.y); double angle = (atan2(y, x) + M_2PI * (pContext.random(Integer.MAX_VALUE) % (int) this._absn)) / this._nnz; double r = pAmount * pow(sqr(x) + sqr(y), this._cn) * ((this._isodd == 0) ? 1.0 : this.parity); double sina = sin(angle); double cosa = cos(angle); cosa *= r; sina *= r; x = (this._isodd != 0) ? cosa : (this._vvar_2 * log(cosa * cosa + sina * sina)); y = (this._isodd != 0) ? sina : (this._vvar * atan2(cosa, sina)); pVarTP.x += x; pVarTP.y += y; if (pContext.isPreserveZCoordinate()) { pVarTP.z += pAmount * pAffineTP.z; } }
@Override public void init( FlameTransformationContext pContext, Layer pLayer, XForm pXForm, double pAmount) { colorMap = null; // renderColors = pContext.getFlameRenderer().getColorMap(); // TODO optimize renderColors = pLayer .getPalette() .createRenderPalette(pContext.getFlameRenderer().getFlame().getWhiteLevel()); if (inlinedImage != null) { try { colorMap = RessourceManager.getImage(inlinedImageHash, inlinedImage); } catch (Exception e) { e.printStackTrace(); } } else if (imageFilename != null && imageFilename.length() > 0) { try { colorMap = RessourceManager.getImage(imageFilename); } catch (Exception e) { e.printStackTrace(); } } if (colorMap == null) { colorMap = getDfltImage(); } imgWidth = colorMap.getImageWidth(); imgHeight = colorMap.getImageHeight(); }
@Override public void init(FlameTransformationContext pContext, XForm pXForm, double pAmount) { /* Set up two major angle systems */ _rswtch = (int) trunc(pContext.random() * 3.0); // Chooses 6 or 3 nodes double hlift = sin(M_PI / 3.0); // sin(60) _fcycle = 0; _bcycle = 0; _seg60x[0] = 1.0; _seg60x[1] = 0.5; _seg60x[2] = -0.5; _seg60x[3] = -1.0; _seg60x[4] = -0.5; _seg60x[5] = 0.5; _seg60y[0] = 0.0; _seg60y[1] = -hlift; _seg60y[2] = -hlift; _seg60y[3] = 0.0; _seg60y[4] = hlift; _seg60y[5] = hlift; _seg120x[0] = 0.0; // These settings cause the 3-node setting to _seg120x[1] = cos(7.0 * M_PI / 6.0); // rotate 30 degrees relative to the hex structure. _seg120x[2] = cos(11.0 * M_PI / 6.0); // _seg120y[0] = -1.0; _seg120y[1] = 0.5; _seg120y[2] = 0.5; }
@Override public void transform( FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) { double a = pAffineTP.getPrecalcAtan() * 0.5 + M_PI * (int) (2.0 * pContext.random()); double sina = sin(a); double cosa = cos(a); double r = pAmount * sqrt(sqrt(pAffineTP.x * pAffineTP.x + pAffineTP.y * pAffineTP.y)); pVarTP.x += r * cosa; pVarTP.y += r * sina; if (pContext.isPreserveZCoordinate()) { pVarTP.z += pAmount * pAffineTP.z; } }
public void transformPowerMinus2( FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) { double a; if (pContext.random(2) == 0) a = atan2(pAffineTP.y, pAffineTP.x) / 2.0; else a = M_PI - atan2(pAffineTP.y, pAffineTP.x) / 2.0; double sina = sin(a); double cosa = cos(a); double r = pAmount / sqrt(sqrt(sqr(pAffineTP.x) + sqr(pAffineTP.y))); pVarTP.x = pVarTP.x + r * cosa; pVarTP.y = pVarTP.y - r * sina; if (pContext.isPreserveZCoordinate()) { pVarTP.z += pAmount * pAffineTP.z; } }
public void transformFunction( FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) { int rnd = pContext.random(absPower); double a; if ((rnd & 1) == 0) a = (2 * M_PI * rnd + atan2(pAffineTP.y, pAffineTP.x)) / power; else a = (2 * M_PI * rnd - atan2(pAffineTP.y, pAffineTP.x)) / power; double sina = sin(a); double cosa = cos(a); double r = pAmount * pow(sqr(pAffineTP.x) + sqr(pAffineTP.y), cPower); pVarTP.x = pVarTP.x + r * cosa; pVarTP.y = pVarTP.y + r * sina; if (pContext.isPreserveZCoordinate()) { pVarTP.z += pAmount * pAffineTP.z; } }
public void transformPower1( FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) { pVarTP.x = pVarTP.x + pAmount * pAffineTP.x; pVarTP.y = pVarTP.y + pAmount * pAffineTP.y; if (pContext.isPreserveZCoordinate()) { pVarTP.z += pAmount * pAffineTP.z; } }
@Override public void transform( FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) { pVarTP.x += pAmount * sin(pAffineTP.x); pVarTP.y += pAmount * pAffineTP.y; if (pContext.isPreserveZCoordinate()) { pVarTP.z += pAmount * pAffineTP.z; } }
@Override public void transform( FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) { // nBlur by FractalDesire, http://fractaldesire.deviantart.com/art/nBlur-plugin-190401515 // *********Adjustment of width of shape********* if (this.adjustToLinear == TRUE) { if ((this.numEdges) % 4 == 0) { pAmount /= sqrt(2.0 - 2.0 * cos(this._midAngle * ((double) this.numEdges / 2.0 - 1.0))) / 2.0; } else { pAmount /= sqrt(2.0 - 2.0 * cos(this._midAngle * floor(((double) this.numEdges / 2.0)))) / 2.0; } } // randXY(pContext, _randXYData); // ********Exact calculation slower - interpolated calculation faster******** if ((this.exactCalc == TRUE) && (this.circumCircle == FALSE)) { while ((_randXYData.lenXY < _randXYData.lenInnerEdges) || (_randXYData.lenXY > _randXYData.lenOuterEdges)) randXY(pContext, _randXYData); } if ((this.exactCalc == TRUE) && (this.circumCircle == TRUE)) { while (_randXYData.lenXY < _randXYData.lenInnerEdges) randXY(pContext, _randXYData); } double xTmp = _randXYData.x; double yTmp = _randXYData.y; // ************************************************************************** // ********Begin of horizontal adjustment (rotation)******** double x = this._cosa * xTmp - this._sina * yTmp; double y = this._sina * xTmp + this._cosa * yTmp; // *********End of horizontal adjustment (rotation)********* pVarTP.x += pAmount * x; pVarTP.y += pAmount * y; if (pContext.isPreserveZCoordinate()) { pVarTP.z += pAmount * pAffineTP.z; } }
@Override public void transform( FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) { /* Bent2 in the Apophysis Plugin Pack */ double nx = pAffineTP.x; double ny = pAffineTP.y; if (nx < 0.0) nx = nx * x; if (ny < 0.0) ny = ny * y; pVarTP.x += pAmount * nx; pVarTP.y += pAmount * ny; if (pContext.isPreserveZCoordinate()) { pVarTP.z += pAmount * pAffineTP.z; } }
@Override public void transform( FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) { double sumsq = pAffineTP.getPrecalcSumsq(); // Prevent divide by zero error if (sumsq == 0) { pVarTP.doHide = true; } else { double xfactor = xscale * pAffineTP.x + xshift; double yfactor = yscale * pAffineTP.y + yshift; pVarTP.x = (pAmount / sumsq) * sin(xfactor) * (cosh(yfactor) + ushift) * sqr(sin(xfactor)); pVarTP.y += (pAmount / sumsq) * cos(xfactor) * (cosh(yfactor) + ushift) * sqr(sin(xfactor)); } if (pContext.isPreserveZCoordinate()) { pVarTP.z += pAmount * pAffineTP.z; } }
@Override public void transform( FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) { // fibonacci2 by Larry Berlin, http://aporev.deviantart.com/gallery/#/d2blmhg // p^z - (-p)^(-z) // z' = ----------------- // sqrt(5) // // Where p is the Golden Ratio. // This function generates the fibonacci sequence // for real integer values. // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 < Real Value // 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 < Fib Value // // Negative real integers produce the negative fibonacci sequence, // which is the same as the normal one, except every // other number is negative. // 1 0 -1 -2 -3 -4 -5 -6 -7 -8 < Real Value // 1 0 1 -1 3 -3 5 -8 13 -21 < Fib Value double a = pAffineTP.y * fnatlog; double snum1 = sin(a); double cnum1 = cos(a); double b = (pAffineTP.x * M_PI + pAffineTP.y * fnatlog) * -1.0; double snum2 = sin(b); double cnum2 = cos(b); double eradius1 = sc * exp(sc2 * (pAffineTP.x * fnatlog)); double eradius2 = sc * exp(sc2 * ((pAffineTP.x * fnatlog - pAffineTP.y * M_PI) * -1)); pVarTP.x += pAmount * (eradius1 * cnum1 - eradius2 * cnum2) * ffive; pVarTP.y += pAmount * (eradius1 * snum1 - eradius2 * snum2) * ffive; if (pContext.isPreserveZCoordinate()) { pVarTP.z += pAmount * pAffineTP.z; } }
private int rand(FlameTransformationContext pContext) { return pContext.random(RAND_MAX); }
private void randXY(FlameTransformationContext pContext, RandXYData data) { double x, y; double xTmp, yTmp, lenOuterEdges, lenInnerEdges; double angXY, lenXY; double ranTmp, angTmp, angMem; double ratioTmp, ratioTmpNum, ratioTmpDen; double speedCalcTmp; int count; if (this.exactCalc == TRUE) { angXY = pContext.random() * M_2PI; } else { angXY = (atan(this._arc_tan1 * (pContext.random() - 0.5)) / this._arc_tan2 + 0.5 + (double) (rand(pContext) % this.numEdges)) * this._midAngle; } x = sin(angXY); y = cos(angXY); angMem = angXY; while (angXY > this._midAngle) { angXY -= this._midAngle; } // ********Begin of xy-calculation of radial stripes******** if (this._hasStripes == TRUE) { angTmp = this._angStart; count = 0; while (angXY > angTmp) { angTmp += this._angStripes; if (angTmp > this._midAngle) angTmp = this._midAngle; count++; } if (angTmp != this._midAngle) angTmp -= this._angStart; if (this._negStripes == FALSE) { if ((count % 2) == 1) { if (angXY > angTmp) { angXY = angXY + this._angStart; angMem = angMem + this._angStart; x = sin(angMem); y = cos(angMem); angTmp += this._angStripes; count++; } else { angXY = angXY - this._angStart; angMem = angMem - this._angStart; x = sin(angMem); y = cos(angMem); angTmp -= this._angStripes; count--; } } if (((count % 2) == 0) && (this.ratioStripes > 1.0)) { if ((angXY > angTmp) && (count != this._maxStripes)) { angMem = angMem - angXY + angTmp + (angXY - angTmp) / this._angStart * this.ratioStripes * this._angStart; angXY = angTmp + (angXY - angTmp) / this._angStart * this.ratioStripes * this._angStart; x = sin(angMem); y = cos(angMem); } else { angMem = angMem - angXY + angTmp - (angTmp - angXY) / this._angStart * this.ratioStripes * this._angStart; angXY = angTmp + (angXY - angTmp) / this._angStart * this.ratioStripes * this._angStart; x = sin(angMem); y = cos(angMem); } } if (((count % 2) == 0) && (this.ratioStripes < 1.0)) { if ((fabs(angXY - angTmp) > this._speedCalc2) && (count != (this._maxStripes))) { if ((angXY - angTmp) > this._speedCalc2) { ratioTmpNum = (angXY - (angTmp + this._speedCalc2)) * this._speedCalc2; ratioTmpDen = this._angStart - this._speedCalc2; ratioTmp = ratioTmpNum / ratioTmpDen; double a = (angMem - angXY + angTmp + ratioTmp); x = sin(a); y = cos(a); angXY = angTmp + ratioTmp; } if ((angTmp - angXY) > this._speedCalc2) { ratioTmpNum = ((angTmp - this._speedCalc2 - angXY)) * this._speedCalc2; ratioTmpDen = this._angStart - this._speedCalc2; ratioTmp = ratioTmpNum / ratioTmpDen; double a = (angMem - angXY + angTmp - ratioTmp); x = sin(a); y = cos(a); angXY = angTmp - ratioTmp; } } if (count == this._maxStripes) { if ((angTmp - angXY) > this._speedCalc2) { ratioTmpNum = ((angTmp - this._speedCalc2 - angXY)) * this._speedCalc2; ratioTmpDen = this._angStart - this._speedCalc2; ratioTmp = ratioTmpNum / ratioTmpDen; double a = (angMem - angXY + angTmp - ratioTmp); x = sin(a); y = cos(a); angXY = angTmp - ratioTmp; } } } } else { // ********Change ratio and ratioComplement******** ratioTmp = this.ratioStripes; this.ratioStripes = this._nb_ratioComplement; this._nb_ratioComplement = ratioTmp; speedCalcTmp = this._speedCalc1; this._speedCalc1 = this._speedCalc2; this._speedCalc2 = speedCalcTmp; // ************************************************ if ((count % 2) == 0) { if ((angXY > angTmp) && (count != this._maxStripes)) { angXY = angXY + this._angStart; angMem = angMem + this._angStart; x = sin(angMem); y = cos(angMem); angTmp += this._angStripes; count++; } else { angXY = angXY - this._angStart; angMem = angMem - this._angStart; x = sin(angMem); y = cos(angMem); angTmp -= this._angStripes; count--; } } if (((count % 2) == 1) && (this.ratioStripes > 1.0)) { if ((angXY > angTmp) && (count != this._maxStripes)) { angMem = angMem - angXY + angTmp + (angXY - angTmp) / this._angStart * this.ratioStripes * this._angStart; angXY = angTmp + (angXY - angTmp) / this._angStart * this.ratioStripes * this._angStart; x = sin(angMem); y = cos(angMem); } else { angMem = angMem - angXY + angTmp - (angTmp - angXY) / this._angStart * this.ratioStripes * this._angStart; angXY = angTmp + (angXY - angTmp) / this._angStart * this.ratioStripes * this._angStart; x = sin(angMem); y = cos(angMem); } } if (((count % 2) == 1) && (this.ratioStripes < 1.0)) { if ((fabs(angXY - angTmp) > this._speedCalc2) && (count != this._maxStripes)) { if ((angXY - angTmp) > this._speedCalc2) { ratioTmpNum = (angXY - (angTmp + this._speedCalc2)) * this._speedCalc2; ratioTmpDen = this._angStart - this._speedCalc2; ratioTmp = ratioTmpNum / ratioTmpDen; double a = (angMem - angXY + angTmp + ratioTmp); x = sin(a); y = cos(a); angXY = angTmp + ratioTmp; } if ((angTmp - angXY) > this._speedCalc2) { ratioTmpNum = ((angTmp - this._speedCalc2 - angXY)) * this._speedCalc2; ratioTmpDen = this._angStart - this._speedCalc2; ratioTmp = ratioTmpNum / ratioTmpDen; double a = (angMem - angXY + angTmp - ratioTmp); x = sin(a); y = cos(a); angXY = angTmp - ratioTmp; } } if (count == this._maxStripes) { angTmp = this._midAngle; if ((angTmp - angXY) > this._speedCalc2) { ratioTmpNum = ((angTmp - this._speedCalc2 - angXY)) * this._speedCalc2; ratioTmpDen = this._angStart - this._speedCalc2; ratioTmp = ratioTmpNum / ratioTmpDen; double a = (angMem - angXY + angTmp - ratioTmp); x = sin(a); y = cos(a); angXY = angTmp - ratioTmp; } } } // ********Restore ratio and ratioComplement******* ratioTmp = this.ratioStripes; this.ratioStripes = this._nb_ratioComplement; this._nb_ratioComplement = ratioTmp; speedCalcTmp = this._speedCalc1; this._speedCalc1 = this._speedCalc2; this._speedCalc2 = speedCalcTmp; // ************************************************ } } // ********End of xy-calculation of radial stripes******** // ********Begin of calculation of edge limits******** xTmp = this._tan90_m_2 / (this._tan90_m_2 - tan(angXY)); yTmp = xTmp * tan(angXY); lenOuterEdges = sqrt(xTmp * xTmp + yTmp * yTmp); // *********End of calculation of edge limits******** // ********Begin of radius-calculation (optionally hole)******** if (this.exactCalc == TRUE) { if (this.equalBlur == TRUE) ranTmp = sqrt(pContext.random()); else ranTmp = pContext.random(); } else { if (this.circumCircle == TRUE) { if (this.equalBlur == TRUE) ranTmp = sqrt(pContext.random()); else ranTmp = pContext.random(); } else { if (this.equalBlur == TRUE) ranTmp = sqrt(pContext.random()) * lenOuterEdges; else ranTmp = pContext.random() * lenOuterEdges; } } lenInnerEdges = this.ratioHole * lenOuterEdges; if (this.exactCalc == FALSE) { if (ranTmp < lenInnerEdges) { if (this.circumCircle == TRUE) { if (this.equalBlur == TRUE) ranTmp = lenInnerEdges + sqrt(pContext.random()) * (1.0 - lenInnerEdges + SMALL_EPSILON); else ranTmp = lenInnerEdges + pContext.random() * (1.0 - lenInnerEdges + SMALL_EPSILON); } else { if (this.equalBlur == TRUE) ranTmp = lenInnerEdges + sqrt(pContext.random()) * (lenOuterEdges - lenInnerEdges); else ranTmp = lenInnerEdges + pContext.random() * (lenOuterEdges - lenInnerEdges); } } } // if(VAR(hasStripes)==TRUE) ranTmp = pow(ranTmp,0.75); x *= ranTmp; y *= ranTmp; lenXY = sqrt(x * x + y * y); // *********End of radius-calculation (optionally hole)********* data.x = x; data.y = y; data.lenXY = lenXY; data.lenOuterEdges = lenOuterEdges; data.lenInnerEdges = lenInnerEdges; }
@Override public void transform( FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) { // bwrands, by dark-beam double Vx, Vy; // V is "global" vector, double Cx, Cy; // C is "cell centre" vector double Lx, Ly; // L is "local" bubble vector double r, theta, s, c; double Vv2, flwr; Vx = pAffineTP.x; Vy = pAffineTP.y; if (fabs(cellsize) < SMALL_EPSILON) { // Linear if cells are too small pVarTP.x += pAmount * Vx; pVarTP.y += pAmount * Vy; if (pContext.isPreserveZCoordinate()) { pVarTP.z += pAmount * pAffineTP.z; } return; } int Ix = (int) floor(Vx / cellsize); int Iy = (int) floor(Vy / cellsize); Cx = (Ix + 0.5) * cellsize; Cy = (Iy + 0.5) * cellsize; // mess with Ix & Iy to get random int xx = Ix ^ 0xB641; int yy = Iy ^ 0x9D81; int xy = xx * yy + seed; xx &= 0xFFFF; yy &= 0xFFFF; xy &= 0xFFFF; // no less than 3 remixes are needed to get good randomness // use always identical mixes or you lose some data (you don't want this!) int tt = bytemix(xx, yy); yy = bytemix(yy, xx); xx = tt; tt = byteshf(xx, xy); yy = byteshf(xy, yy); xx = tt; tt = bytexim(xx, yy); yy = bytexim(yy, xx); xx = tt; double Ssz = ((double) xx) / 65535.0; // to get a range not 0-1 for circles size edit here Ssz = rmin + Ssz * (1.0 - rmin); double Aan = rrot * M_2PI * ((double) yy) / 65535.0; // to get a range not 0-2pi for rotations size edit here tt = byteprimes(xx, yy); yy = byteprimes(yy, xx); xx = tt; double LoonieChance = -((double) xx) / 65535.0 + loonie_chance; // 0.5 for a chance 50% ! double PetalsChance = 0.0; if (LoonieChance < 0) PetalsChance = LoonieChance + petals_chance; // user choice but don't upset modulus... double NPetals; if (_pety == 0) NPetals = (double) _petx; // ... when min = max else NPetals = (double) (_petx + (yy >> 3) % (1 + _pety)); // yy last byte is not enough random. But yy >> 3 is good if (LoonieChance <= PetalsChance) LoonieChance = -1.0; // the bigger probability must win. // if more random values are needed remix again :D Lx = Vx - Cx; Ly = Vy - Cy; Vv2 = Ssz * _r2; if ((Lx * Lx + Ly * Ly) > Vv2) { // Linear if outside the bubble pVarTP.x += pAmount * Vx; pVarTP.y += pAmount * Vy; if (pContext.isPreserveZCoordinate()) { pVarTP.z += pAmount * pAffineTP.z; } return; } if (LoonieChance > 0.0) { // We're in the loonie! // r = Vv2 / (Lx * Lx + Ly * Ly) - MAX(MIN(VAR(bwrands_gain),1.0),0.0); LOOKING BAD!!! r = Vv2 / (Lx * Lx + Ly * Ly) - 1.0; r = sqrt(r); Lx *= r; Ly *= r; Vv2 = 1.0; // recycled var } else if (PetalsChance > 0.0) { // We're in the petals! flwr = NPetals / M_2PI * (M_PI + atan2(Ly, Lx)); flwr = flwr - (int) (flwr); flwr = fabs(flwr - 0.5) * 2.0; r = sqrt(Lx * Lx + Ly * Ly); // We need a little chaos game to fill the empty space outside the flower. PetalsChance = pContext.random(); if (PetalsChance < .5 * (flwr + .5)) { // petals Lx *= (1.0 - r) * (flwr * 1.1); // 1.1 remove the ugly border Ly *= (1.0 - r) * (flwr * 1.1); // 1.1 remove the ugly border } else { Vv2 = sqrt(Vv2); // dist to circle border // filling the rest of the circle Lx *= (Vv2 - r * (1.0 - flwr)) / (r + SMALL_EPSILON); Ly *= (Vv2 - r * (1.0 - flwr)) / (r + SMALL_EPSILON); } Vv2 = 1.0; // recycled var } else { // We're in the bubble! // Bubble distortion on local co-ordinates: Lx *= _g2; Ly *= _g2; r = _rfactor / ((Lx * Lx + Ly * Ly) / (4.0 * Ssz) + 1.0); Lx *= r; Ly *= r; Vv2 = sqrt(Ssz); // recycled var } // Spin around the centre: r = Vv2 * (Lx * Lx + Ly * Ly) / _r2; // r should be 0.0 - 1.0 theta = inner_twist * (1.0 - r) + outer_twist * r; s = sin(theta + Aan); c = cos(theta + Aan); // Add rotated local vectors direct to centre (avoids use of temp storage) Vx = Cx + c * Lx + s * Ly; Vy = Cy - s * Lx + c * Ly; // Finally add values in pVarTP.x += pAmount * Vx; pVarTP.y += pAmount * Vy; if (pContext.isPreserveZCoordinate()) { pVarTP.z += pAmount * pAffineTP.z; } }
@Override public void transform( FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) { /* hexnix3D by Larry Berlin, http://aporev.deviantart.com/art/3D-Plugins-Collection-One-138514007?q=gallery%3Aaporev%2F8229210&qo=15 */ if (_fcycle > 5) { // Resets the cyclic counting _fcycle = 0; _rswtch = (int) trunc(pContext.random() * 3.0); // Chooses new 6 or 3 nodes } if (_bcycle > 2) { _bcycle = 0; _rswtch = (int) trunc(pContext.random() * 3.0); // Chooses new 6 or 3 nodes } double lrmaj = pAmount; // Sets hexagon length radius - major plane double smooth = 1.0; double smRotxTP = 0.0; double smRotyTP = 0.0; double smRotxFT = 0.0; double smRotyFT = 0.0; double gentleZ = 0.0; if (fabs(pAmount) <= 0.5) { smooth = pAmount * 2.0; } else { smooth = 1.0; } double boost = 0.0; // Boost is the separation distance between the two planes int posNeg = 1; int loc60; int loc120; double scale = this.scale; double scale3 = this._3side; if (pContext.random() < 0.5) { posNeg = -1; } // Determine whether one or two major planes int majplane = 0; double abmajp = fabs(this.majp); if (abmajp <= 1.0) { majplane = 0; // 0= 1 plate active 1= transition to two plates active 2= defines two plates boost = 0.0; } else if (abmajp > 1.0 && abmajp < 2.0) { majplane = 1; boost = 0.0; } else { majplane = 2; boost = (abmajp - 2.0) * 0.5; // distance above and below XY plane } // Creating Z factors relative to the planes if (majplane == 0) { pVarTP.z += smooth * pAffineTP.z * scale * this.zlift; // single plate instructions } else if (majplane == 1 && this.majp < 0.0) { // Transition for reversing plates because majp is negative value if (this.majp < -1.0 && this.majp >= -2.0) { gentleZ = (abmajp - 1.0); // Set transition smoothing values 0.00001 to 1.0 } else { gentleZ = 1.0; // full effect explicit default value } // Begin reverse transition - starts with pVarTP.z==pVarTP.z proceeds by gradual negative if (posNeg < 0) { pVarTP.z += -2.0 * (pVarTP.z * gentleZ); // gradually grows negative plate, in place, no boost, } } if (majplane == 2 && this.majp < 0.0) { // Begin the splitting operation, animation transition is done if (posNeg > 0) { // The splitting operation positive side pVarTP.z += (smooth * (pAffineTP.z * scale * this.zlift + boost)); } else { // The splitting operation negative side pVarTP.z = (pVarTP.z - (2.0 * smooth * pVarTP.z)) + (smooth * posNeg * (pAffineTP.z * scale * this.zlift + boost)); } } else { // majp > 0.0 The splitting operation pVarTP.z += smooth * (pAffineTP.z * scale * this.zlift + (posNeg * boost)); } if (this._rswtch <= 1) { // Occasion to build using 60 degree segments loc60 = (int) trunc(pContext.random() * 6.0); // random nodes selection // loc60 = this.fcycle; // sequential nodes selection - seems to create artifacts that are // progressively displaced smRotxTP = (smooth * scale * pVarTP.x * _seg60x[loc60]) - (smooth * scale * pVarTP.y * _seg60y[loc60]); smRotyTP = (smooth * scale * pVarTP.y * _seg60x[loc60]) + (smooth * scale * pVarTP.x * _seg60y[loc60]); smRotxFT = (pAffineTP.x * smooth * scale * _seg60x[loc60]) - (pAffineTP.y * smooth * scale * _seg60y[loc60]); smRotyFT = (pAffineTP.y * smooth * scale * _seg60x[loc60]) + (pAffineTP.x * smooth * scale * _seg60y[loc60]); pVarTP.x = pVarTP.x * (1.0 - smooth) + smRotxTP + smRotxFT + smooth * lrmaj * _seg60x[loc60]; pVarTP.y = pVarTP.y * (1.0 - smooth) + smRotyTP + smRotyFT + smooth * lrmaj * _seg60y[loc60]; this._fcycle += 1; } else { // Occasion to build on 120 degree segments loc120 = (int) trunc(pContext.random() * 3.0); // random nodes selection // loc120 = this.bcycle; // sequential nodes selection - seems to create artifacts that are // progressively displaced smRotxTP = (smooth * scale * pVarTP.x * _seg120x[loc120]) - (smooth * scale * pVarTP.y * _seg120y[loc120]); smRotyTP = (smooth * scale * pVarTP.y * _seg120x[loc120]) + (smooth * scale * pVarTP.x * _seg120y[loc120]); smRotxFT = (pAffineTP.x * smooth * scale * _seg120x[loc120]) - (pAffineTP.y * smooth * scale * _seg120y[loc120]); smRotyFT = (pAffineTP.y * smooth * scale * _seg120x[loc120]) + (pAffineTP.x * smooth * scale * _seg120y[loc120]); pVarTP.x = pVarTP.x * (1.0 - smooth) + smRotxTP + smRotxFT + smooth * lrmaj * scale3 * _seg120x[loc120]; pVarTP.y = pVarTP.y * (1.0 - smooth) + smRotyTP + smRotyFT + smooth * lrmaj * scale3 * _seg120y[loc120]; this._bcycle += 1; } /* Rotations need to interchange smoothly between x and y values (pseudo code) new x = in_x*cos(r) - in_y*sin(r) + movedLoci_x; new y = in_y*cos(r) + in_x*sin(r) + movedLoci_y; */ }