Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

simple koch fractal app #2

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor
  • Loading branch information
DerArvend committed Feb 27, 2018
commit f9e1b1063c8417e7fa537c102e94ca678b7e9f9a
4 changes: 1 addition & 3 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
<title>Fractal App</title>
</head>
<body>
<h1>Снежинка Коха</h1>
<div id="slider"></div>
<div id="canvas"></div>
<div id="root"></div>
</body>
</html>
7 changes: 2 additions & 5 deletions src/LSystem.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
'use strict'


/** Represents simple L-System */
export default class LSystem {
/**
Expand All @@ -25,12 +22,12 @@ export default class LSystem {
return this.axiom;

let result = [];
this.getOutput(depth - 1).forEach(symbol => {
for (let symbol of this.getOutput(depth-1)){
if (symbol === this.rule.symbol)
this.rule.replacement.forEach(s => result.push(s));
else
result.push(symbol);
});
}
return result;
}
}
56 changes: 36 additions & 20 deletions src/components/FractalApp.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
// import React from 'react';
// import RecursionDepthSlider from "./RecursionDepthSlider";
//
// class FractalApp extends React.Component {
// constructor(props) {
// super(props);
// this.state = {
// currentDepth: 1
// }
// }
//
// render() {
// return (
// <div>
// <h1>Снежинка Коха</h1>
// <RecursionDepthSlider/>
// </div>
// );
// }
// }
import React from 'react';
import RecursionDepthSlider from './RecursionDepthSlider';
import {drawKochFractal} from '../kochSnowflake';
import DrawingBox from './DrawingBox';

class FractalApp extends React.Component {
constructor(props) {
super(props);
this.state = {
currentDepth: 1
};
}

handleSlider = (event, value) => {
let canvas = document.getElementById('fractal-canvas');
drawKochFractal(canvas, value);
this.setState({currentDepth: value});
};

render() {
return (
<div>
<h1>Снежинка Коха</h1>
<RecursionDepthSlider onChange={this.handleSlider} value={this.state.currentDepth}/>
<p>Глубина рекурсии: {this.state.currentDepth}</p>
<DrawingBox size={500}/>
</div>);
}

componentDidMount () {
let canvas = document.getElementById('fractal-canvas');
drawKochFractal(canvas, 1);
}
}

export default FractalApp
49 changes: 19 additions & 30 deletions src/components/RecursionDepthSlider.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,22 @@
import React from "react";
import {MuiThemeProvider, Slider} from "material-ui";
import {drawKochFractal} from "../kochSnowflake";
import React from 'react';
import {MuiThemeProvider, Slider} from 'material-ui';

class RecursionDepthSlider extends React.Component {
state = {slider: 1};
handleSlider = (event, value) => {
let canv = document.getElementById('fractal-canvas');
drawKochFractal(canv, value);
this.setState({slider: value});
};

render() {
return (
<MuiThemeProvider>
<Slider
min={1}
max={7}
step={1}
value={this.state.slider}
onChange={this.handleSlider}
style={{
marginRight: '30%',
marginLeft: '30%',
marginBottom: '-40px'
}}/>
<p>Глубина рекурсии: {this.state.slider}</p>

</MuiThemeProvider>);
}
function FractalDepthSlider(props) {
return (
<MuiThemeProvider>
<Slider
min={1}
max={8}
step={1}
value={props.value}
onChange={props.onChange}
style={{
marginRight: '30%',
marginLeft: '30%',
marginBottom: '-40px'
}}/>
</MuiThemeProvider>);
}

export default RecursionDepthSlider

export default FractalDepthSlider
7 changes: 3 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react'
import {render} from 'react-dom'
import RecursionDepthSlider from './components/RecursionDepthSlider'
import DrawingBox from "./components/DrawingBox";
import FractalApp from './components/FractalApp';

render(<RecursionDepthSlider/>, document.getElementById('slider'));
render(<DrawingBox size={500}/>, document.getElementById('canvas'));

render(<FractalApp/>, document.getElementById('root'))
50 changes: 28 additions & 22 deletions src/kochSnowflake.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
'use strict';

import LSystem from './LSystem';

const axiom = [...'F--F--F'];
Expand All @@ -11,35 +9,43 @@ const kochLSystem = new LSystem(axiom, rule);
export function drawKochFractal(canvasElement, depth, shouldClear = true) {
const ctx = canvasElement.getContext('2d');
const size = parseInt(canvasElement.getAttribute('height'));
const length = size * 0.7 / Math.pow(3, depth - 1);
const segmentLength = size * 0.7 / Math.pow(3, depth - 1);

const LSequence = kochLSystem.getOutput(depth);

if (shouldClear) ctx.clearRect(0, 0, size, size);
drawLSequence(LSequence, ctx, segmentLength, angle, size * 0.15, size * 0.3);
}

function drawLine(context, lineLength, x0, y0, angleInRadians) {
let x = x0 + lineLength * Math.cos(angleInRadians);
let y = y0 + lineLength * Math.sin(-angleInRadians);
context.lineTo(x, y);
return {x: x, y: y};
}

let x = size * 0.15;
let y = size * 0.3;
function drawLSequence(sequence, context, lineLength, turnAngle, x0, y0) {
let x = x0;
let y = y0;
let currentAngle = 0;
const drawNextLine = () => drawLine(ctx, length, x, y, currentAngle);

let sequence = kochLSystem.getOutput(depth);
const drawNextLine = () => drawLine(context, lineLength, x, y, currentAngle);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не стоит делать замыкание для одного вызова: кода больше становится, а смысл тот же.


context.beginPath();
context.moveTo(x, y);

if (shouldClear) ctx.clearRect(0, 0, size, size);
ctx.beginPath();
ctx.moveTo(x, y);
for (let symbol of sequence) {
if (symbol === 'F') {
let nextPoint = drawNextLine();
x = nextPoint.x;
y = nextPoint.y;
} else if (symbol === '+') {
currentAngle += angle;
} else if (symbol === '-') {
currentAngle -= angle;
}
else if (symbol === '+') {
currentAngle += turnAngle;
}
else if (symbol === '-') {
currentAngle -= turnAngle;
}
}
ctx.stroke();
}

function drawLine(context, lineLength, x0, y0, angleInRadians) {
let x = x0 + lineLength * Math.cos(angleInRadians);
let y = y0 + lineLength * Math.sin(-angleInRadians);
context.lineTo(x, y);
return {x: x, y: y};
context.stroke();
}